patterntypescriptnextjsModerate
Next.js NFC compliance system: full-stack architecture with SQLite + Drizzle + iron-session
Viewed 0 times
nfc scancompliance trackingsafety equipmentworker dashboardmanager dashboardWAL modetimezone scanDate
Problem
Building a real-time compliance tracking system where 100+ workers scan NFC chips daily, with a manager dashboard showing live compliance status. Needs to handle concurrent scan bursts at shift start, timezone-aware daily scan deduplication, and cookie-based auth with no DB session overhead.
Solution
Use Next.js App Router with SQLite (WAL mode + busy_timeout=5000) via Drizzle ORM for the database, iron-session for encrypted cookie-based auth (12h expiry = one shift). Denormalize scanDate as YYYY-MM-DD computed via Intl.DateTimeFormat('en-CA', { timeZone }) for fast daily compliance queries. NFC chips store short URLs (CHK-{8hex}) that hit a GET route handler which validates chip ownership, checks for existing daily scan, inserts record, and redirects. Manager dashboard polls compliance API every 30s. Index (workerId, scanDate) on scans table for fast daily lookups.
Why
SQLite WAL mode allows concurrent reads during writes (critical for 100+ workers scanning simultaneously). iron-session avoids session table overhead. Denormalized scanDate avoids date math in queries. Intl.DateTimeFormat('en-CA') gives YYYY-MM-DD in the site timezone without date libraries.
Gotchas
- busy_timeout must be set per connection, not globally
- NFC scan handler must be GET (not POST) since phone browsers navigate to URLs
- Intl.DateTimeFormat('en-CA') is the trick for YYYY-MM-DD format without date libraries
- iron-session needs cookieOptions.secure=false in dev or cookies won't persist
Code Snippets
Timezone-aware date utility
export function getTodayDate(): string {
const tz = process.env.SITE_TIMEZONE || 'UTC';
return new Intl.DateTimeFormat('en-CA', { timeZone: tz }).format(new Date());
}Revisions (0)
No revisions yet.