# CLAUDE.md — Game Night Live You are building a live scoring web app for a church youth group's game nights. Read `docs/` before writing code. Docs are the source of truth; if code and docs disagree, ask. ## Stack (do not swap without asking) - Next.js (App Router, latest stable) + TypeScript (strict) - Tailwind CSS - Supabase: Postgres, Auth (admin only, email magic link), Realtime (Broadcast) - zod for all input validation - Vitest for unit tests (scoring logic MUST be tested) - npm as package manager - Deploy target: Vercel Verify current Next.js and Supabase APIs against their official docs before using them; don't rely on memory for SDK method names (esp. `@supabase/ssr` and Realtime broadcast from the server). ## Non-negotiable rules 1. **The service role key is server-only.** Never import it in a client component. Never prefix it `NEXT_PUBLIC_`. 2. **Anon users get zero table access.** RLS is on for every table. Scoreboard and judge pages read/write ONLY through Next.js route handlers that validate the token and use the service-role client. 3. **Hiding the scoreboard is enforced on the server.** When hidden, the scoreboard API must not return scores at all. Never hide with CSS only — someone will open devtools. 4. **Realtime messages carry no data.** Broadcast a `{ type: "refresh" }` ping; clients refetch from the API. This keeps hidden/sanitised data rules in one place. 5. **One scoring engine.** All score math lives in `src/lib/scoring/` as pure functions with tests. Admin view, scoreboard API and judge view all call it. No score math in components or SQL views. 6. Tokens are unguessable (≥ 128 bits, hex). Validate shape with zod before hitting the DB. 7. Mobile-first for judge pages (they're on phones). Scoreboard is 16:9 projector-first. 8. Small commits per task. After each phase, stop and summarise what to test manually. ## Code conventions - `src/app` routes, `src/lib` logic, `src/components` UI, `src/lib/supabase/{server,admin,browser}.ts` clients. - Server actions for admin mutations; route handlers (`src/app/api/...`) for public/judge. - Every mutation that affects scores/visibility calls `notify()` from `src/lib/realtime.ts` which pings the relevant channels (see ARCHITECTURE.md). - Use DB types generated by `supabase gen types typescript`. - Explain *why* in PR-style summaries, not just what changed. ## Commands - `npm run dev` / `npm run build` / `npm run test` / `npm run lint` - Migrations live in `supabase/migrations/`. Apply via Supabase CLI or paste into SQL editor. # This is NOT the Next.js you know This version has breaking changes — APIs, conventions, and file structure may all differ from your training data. Read the relevant guide in `node_modules/next/dist/docs/` (resolved from this file's directory; in monorepos the `next` package may not be visible from the repo root) before writing any code. Heed deprecation notices. This block is written and re-added by `next dev` — verify at `node_modules/next/dist/server/lib/generate-agent-files.js`. Removing it from a diff only re-creates the uncommitted change; committing it with your work keeps the tree clean.