From 152a6602d60bc9d13534123b101d8e2aa74e85ea Mon Sep 17 00:00:00 2001 From: weeihan Date: Thu, 9 Jul 2026 22:36:50 +0800 Subject: [PATCH] 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= 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 Claude-Session: https://claude.ai/code/session_01AWxyMibCuGGtSQSqfajDQ7 --- .superpowers/sdd/progress.md | 10 +++++----- public/qr/.gitkeep | 0 scripts/generate-qr.ts | 38 ++++++++++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 5 deletions(-) create mode 100644 public/qr/.gitkeep create mode 100644 scripts/generate-qr.ts diff --git a/.superpowers/sdd/progress.md b/.superpowers/sdd/progress.md index 115199b..2621a11 100644 --- a/.superpowers/sdd/progress.md +++ b/.superpowers/sdd/progress.md @@ -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 diff --git a/public/qr/.gitkeep b/public/qr/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/scripts/generate-qr.ts b/scripts/generate-qr.ts new file mode 100644 index 0000000..558778a --- /dev/null +++ b/scripts/generate-qr.ts @@ -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) +})