Files
game-scoreboard/docs/PRD.md
T
joshuaandClaude Opus 5.5 c89a82295b Phase 0: scaffold Next.js, Tailwind tokens, Supabase clients, env validation
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>
2026-10-03 12:27:11 +02:00

6.0 KiB
Raw Blame History

PRD — Game Night Live

1. Goal

Run a youth game night (e.g. "Worship Game Night") from one admin tab while a projector tab shows a live scoreboard, and judges score from their phones via links. Versatile enough for any game format.

2. Roles

Role Access How they get in
Admin Everything Logs in (magic link). Email must be in ADMIN_EMAILS.
Scoreboard viewer Read-only scoreboard for ONE event Public link /s/{scoreboardToken}
Judge Score ONE game Personal link /j/{judgeToken} OR open game link /jo/{openToken} (enters name first)

3. Core concepts

  • Event — one game night. Has teams, games, one scoreboard link, visibility state.
  • Team — name + colour. Belongs to an event.
  • Game — one activity. Ordered. Has a scoring mode:
    • judged — judges submit scores via links; admin can see progress & override.
    • direct — admin enters scores directly.
  • Criterion ("block") — one thing being scored in a game. A game has 1..N criteria.
    • e.g. Karaoke: Pitch, Energy, Lyrics accuracy, Stage presence, Crowd reaction (each 1–5).
    • e.g. Guess the Lyric: one criterion "Correct answers" (number input, 0–20).
    • Input type: blocks (tap a number in a row of buttons) or number (free numeric input / +/- stepper).
    • Has min, max, step, weight, and a description (shown to whoever scores it).
  • Points mode per game (how a game's result becomes leaderboard points):
    • raw — game points = criteria total × multiplier.
    • placement — teams ranked by criteria total, then awarded placement points (default 10/7/5/3).
  • Adjustment — bonus or penalty points with a reason, optionally tied to a game.
  • Notes — admin_notes (only admin sees) and judge_notes (judges see) per game.

4. Features

4.1 Admin — Setup (/admin/events/[id])

  • Create/edit/delete events; duplicate an event (copies teams, games, criteria — not scores).
  • Teams: add, rename, recolour, reorder, delete.
  • Games builder: add, reorder (drag or up/down), duplicate, delete.
    • Title, description, scoring mode, points mode, multiplier, placement points.
    • Criteria list: add/remove/reorder; label, description, input type, min/max/step, weight.
    • Quick presets: "Karaoke (5 × 1–5)", "Single score (0–10)", "Points (number)", "Win/Lose (0–1)".
    • Admin notes + judge notes (multiline).
  • Judges (judged games only):
    • Nominate judges by name → each gets a personal link (copy button + QR code).
    • Toggle the open link on/off; anyone opening it types their name and becomes a judge.
    • Revoke a judge (link stops working, their scores excluded).
  • Share panel: scoreboard link + QR, all judge links per game.

4.2 Admin — Control room (/admin/events/[id]/live)

This is the screen used during the night. Must be fast and hard to mess up.

  • Game switcher: Prev / Next buttons + list of all games with status (upcoming / live / done). Setting a game as current marks it live and shows it on the scoreboard.
  • Current game panel:
    • Scoring grid: rows = teams, columns = criteria, using the same block/number inputs.
      • Direct mode: admin types/taps here. Autosaves.
      • Judged mode: shows per-team average per criterion, a judge-progress matrix (✓ per judge per team), and per-judge breakdown on expand. Admin can override a cell (override wins over judge average; clearly marked; can be cleared).
    • Spotlight: pick "now performing" team — judges see it highlighted.
    • Lock judging toggle (judges become read-only).
    • Mark game done.
    • Admin notes visible.
  • Bonus/penalty: per team quick buttons (+1, +5, +10, −5) and custom amount + reason. Recent adjustments list with undo.
  • Scoreboard visibility: Visible / Frozen / Hidden (see 4.3). Big obvious toggle.
  • "Open scoreboard" button (new tab) + "Reveal mode" button (see 4.3).
  • Keyboard shortcuts: N next game, P prev game, H cycle visibility, ? help.

4.3 Scoreboard (/s/[token])

  • Projector-first, 16:9, readable from the back of a hall.
  • Shows: event name, current game title, team standings (rank, name, colour, total points), optionally per-game points columns for completed games.
  • Updates live (< 1s) when admin changes anything. Rank changes animate.
  • Visible — live totals.
  • Frozen — shows totals as they were the moment it was frozen, with a subtle "scores frozen" note. Server stores the snapshot; live scores are not sent.
  • Hidden — no scores sent at all. Shows team names (no order implied — alphabetical) and the current game, with a "scores are hidden" state.
  • Reveal mode (admin-triggered): scoreboard reveals final standings last place → first, one team per admin click ("Reveal next"), then sets visibility to Visible.
  • Auto-reconnects; also polls every 10s as a fallback. Shows a small offline dot if disconnected.
  • Fullscreen button; hides cursor after inactivity.

4.4 Judge (/j/[token])

  • Mobile-first. Shows game title, judge notes, and their own name.
  • One card per team (spotlighted team pinned on top + highlighted).
  • Each card: one block row per criterion (e.g. 1 2 3 4 5 big tap targets) with the criterion label + description; number criteria get a stepper.
  • Autosaves on every tap; shows saved ✓ / saving / error per card.
  • Judges see only their own scores — never other judges' or totals.
  • If judging locked or game done: read-only with a message. If revoked: "This link is no longer active."
  • Open link (/jo/[token]): enter name → creates judge → redirects to personal link and stores it in localStorage so a refresh keeps them in.

5. Non-functional

  • Live latency target < 1s on normal Wi-Fi.
  • Works with ~10 teams, ~20 games, ~10 judges per game without lag.
  • No data loss on refresh; all state server-side.
  • Accessible: visible focus, sufficient contrast, tap targets ≥ 44px.

6. Out of scope (v1)

  • Individual contestants within teams (stretch: participants per team).
  • Multiple admins / co-hosts (stretch).
  • Timers/buzzers (stretch).