Next.js 16 App Router with strict TypeScript, Tailwind 4 theme tokens from docs/UI.md, Vitest, and the three Supabase clients. Env vars are validated with zod in next.config.ts so dev and build fail fast with a readable error. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
43 lines
2.5 KiB
Markdown
43 lines
2.5 KiB
Markdown
# 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.
|