Files
game-scoreboard/CLAUDE.md
T
joshuaandClaude Opus 5.5 b60c9db4f4 Phase 3: admin magic-link auth and event setup screens
- /login sends a Supabase magic link (admin emails only); /auth/confirm
  completes sign-in; proxy.ts guards /admin and every server action
  re-checks with requireAdmin(), since actions are plain POST endpoints.
- /admin lists, creates, duplicates and deletes events.
- /admin/events/[eventId] edits teams (colour, order) and games with
  criteria, presets and notes. All input goes through zod schemas that
  mirror the database constraints so errors read as plain sentences.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 13:47:36 +02:00

53 lines
3.2 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.
<!-- BEGIN:nextjs-agent-rules -->
# 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.
<!-- END:nextjs-agent-rules -->