feat: add QR code generation script for seeded zones

Adds scripts/generate-qr.ts that generates one 400px PNG per warehouse
zone into public/qr/ (gitignored). Encodes /report?zone=<token> URL per
zone using NEXT_PUBLIC_APP_URL (default http://localhost:3000). Adds
public/qr/.gitkeep so the output directory is tracked. All 8 tests pass.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AWxyMibCuGGtSQSqfajDQ7
This commit is contained in:
2026-07-09 22:36:50 +08:00
co-authored by Claude Sonnet 4.6
parent c3ba543ebb
commit 152a6602d6
3 changed files with 43 additions and 5 deletions
+5 -5
View File
@@ -6,9 +6,9 @@ Started: 2026-07-09
## Tasks
- [x] Task 1: Scaffold Next.js + Supabase clients (commit f83686f, review clean)
- [ ] Task 2: Role types + middleware
- [ ] Task 3: Database migrations (8 SQL files)
- [ ] Task 4: Apply migrations to Supabase cloud (USER ACTION REQUIRED)
- [ ] Task 5: Auth flow (login + redirect)
- [ ] Task 6: Protected dashboard pages
- [x] Task 2: Role types + middleware (commit 6939a21, review clean)
- [x] Task 3: Database migrations (commit 05daf70, review clean — 2 advisories: concurrent ref_no race, evidence soft-delete needs SECURITY DEFINER fn)
- [x] Task 4: Apply migrations to Supabase cloud (user ran supabase login + link + db push)
- [x] Task 5: Auth flow (commit 5598594, review clean — LOW: open redirect in callback/route.ts:8 fix before prod)
- [x] Task 6: Protected dashboard pages (commit c3ba543, review clean)
- [ ] Task 7: QR code generation
View File
+38
View File
@@ -0,0 +1,38 @@
// scripts/generate-qr.ts
import QRCode from 'qrcode'
import { mkdirSync } from 'fs'
import path from 'path'
const BASE_URL = process.env.NEXT_PUBLIC_APP_URL ?? 'http://localhost:3000'
// Matches seeded zone qr_code_token values in 20260709000008_seed.sql
const ZONES = [
{ token: 'scw1-dock-a-qr-2026', name: 'SCW1 — Dock A' },
{ token: 'scw1-cold-storage-qr-2026', name: 'SCW1 — Cold Storage' },
{ token: 'scw1-loading-bay-qr-2026', name: 'SCW1 — Loading Bay' },
]
async function main() {
const outDir = path.join(process.cwd(), 'public', 'qr')
mkdirSync(outDir, { recursive: true })
for (const zone of ZONES) {
const url = `${BASE_URL}/report?zone=${zone.token}`
const outputPath = path.join(outDir, `${zone.token}.png`)
await QRCode.toFile(outputPath, url, {
width: 400,
margin: 2,
color: { dark: '#000000', light: '#FFFFFF' },
})
console.log(`${zone.name}`)
console.log(`${url}`)
console.log(`${outputPath}`)
}
}
main().catch((err) => {
console.error(err)
process.exit(1)
})