From 6305985dad119bb23e907ed6441f61af7b436b8c Mon Sep 17 00:00:00 2001 From: Frank Tovar Date: Thu, 5 Feb 2026 10:58:40 +0100 Subject: [PATCH] Update API and spec for linked voting --- API.md | 49 +++++++++++++++++++++++++------------------------ SPEC.md | 42 ++++++++++++++++++++---------------------- 2 files changed, 45 insertions(+), 46 deletions(-) diff --git a/API.md b/API.md index a89cc7d..1bdf6b7 100644 --- a/API.md +++ b/API.md @@ -1,38 +1,39 @@ -# API Contract (Auth-enabled) +# API Contract (auth-enabled) -All endpoints are JSON. Most routes require the HttpOnly cookie `player`, which is issued after successful register/login. Legacy player rows are given `legacy-xxxxxxxx` usernames during migration; they must register/login to get a valid auth cookie. +All endpoints are JSON. Most routes require the HttpOnly `player` cookie issued after register/login. Admin access is granted via authenticated admin user or `X-Admin-Key`/`key` matching `ADMIN_PASSWORD`. ## Auth -POST /api/auth/register +POST /api/auth/register — accepts optional `adminKey` to set `IsAdmin=true` POST /api/auth/login POST /api/auth/logout -- Register accepts optional `adminKey`; when it matches `ADMIN_PASSWORD`, the account is marked `IsAdmin=true` and can use admin APIs. If an `adminKey` is supplied but wrong (or ADMIN_PASSWORD unset), registration returns 400. - -## State -GET /api/state (public) +## State (requires auth) +GET /api/state — returns currentPhase (for caller), votesFinal, resultsOpen, updatedAt, counts (players/suggestions/votes) +GET /api/me — id, displayName, username, isAdmin, currentPhase, votesFinal ## Player (requires auth) -GET /api/me (returns id, displayName, username, isAdmin) -POST /api/me/name +POST /api/me/name — set display name (max 16 chars) +POST /api/me/phase/next — advance caller to next phase (Suggest→Vote→Results; Results gated by resultsOpen) +POST /api/me/phase/prev — admin-only move caller backward (Results→Vote→Suggest) ## Suggestions (requires auth + phase gating) -GET /api/suggestions/mine -POST /api/suggestions -DELETE /api/suggestions/{id} -PUT /api/suggestions/{id} (non-admin: own suggestion, Suggest phase only; admin: any time, any suggestion) -GET /api/suggestions/all +GET /api/suggestions/mine — own suggestions (Suggest phase) +POST /api/suggestions — create (name required ≤100; max 5 per player; validates screenshot URL) +PUT /api/suggestions/{id} — update (non-admin: own suggestion; title locked after Suggest) +DELETE /api/suggestions/{id} — delete (non-admin only in Suggest; admin any time) +GET /api/suggestions/all — all suggestions (from Vote onward), includes author, link metadata -## Votes (requires auth + phase gating) +## Votes (requires auth + Vote phase) GET /api/votes/mine -POST /api/votes +POST /api/votes — upsert vote; if suggestion is in a linked group, applies the same score to all linked siblings +POST /api/votes/finalize — `{ final: bool }` toggles caller’s finalized status (blocks further vote edits when true) -## Results (requires auth + phase gating) -GET /api/results +## Results (requires auth + Results phase + resultsOpen) +GET /api/results — leaderboard with totals, counts, averages, caller’s vote, media/links, link metadata -## Admin (requires admin account or admin key) -POST /api/admin/phase -POST /api/admin/reset -POST /api/admin/factory-reset - -Admin APIs accept either an authenticated admin user (cookie) or, for compatibility, `X-Admin-Key`/`key` matching `ADMIN_PASSWORD`. +## Admin (admin auth or admin key) +POST /api/admin/results — `{ resultsOpen: bool }` locks/unlocks results and aligns player phases +GET /api/admin/vote-status — readiness overview (who finalized) +POST /api/admin/link-suggestions — `{ sourceSuggestionId, targetSuggestionId }`; merges vote groups during Vote, clears votes in the linked group, unfinalizes affected players +POST /api/admin/reset — clear suggestions/votes; keep players; reset phases/vote-final flags +POST /api/admin/factory-reset — wipe players, suggestions, votes, state diff --git a/SPEC.md b/SPEC.md index 608142c..a589ee0 100644 --- a/SPEC.md +++ b/SPEC.md @@ -1,36 +1,34 @@ -# Pick'n'Play — Product Spec (MVP) +# Pick'n'Play — Product Spec (current) ## Goal -A micro web app for a closed Discord group (4–8 players) to decide what co-op game to play using a phased process: +Help a small Discord group (4–8 players) pick a co-op game via phased flow: 1. Suggest (blind) -2. Reveal (discuss) -3. Vote (blind scoring 0–10) -4. Results (leaderboard) +2. Vote (blind, 0–10 sliders) +3. Results (leaderboard) -## MVP Scope +## Scope - Single shared instance -- Username/password login (cookie holds auth token after register/login) -- Organizer-controlled phase switching (admin accounts flagged via admin key at registration) +- Username/password login (cookie auth) +- Admins flagged via admin key at registration +- Per-user phase tracking; admins can move themselves backward, everyone can move forward (subject to admin “results open” toggle) ## Suggest Phase -- Up to 3 suggestions per player -- Name required -- Optional genre, description, screenshot URL, YouTube URL -- Players see only their own suggestions - -## Reveal Phase -- All suggestions visible -- Suggester name shown -- Suggestions locked +- Up to **5 suggestions** per player +- Name required; optional genre, description, screenshot URL, YouTube URL, external game link, min/max players +- Players see only their own suggestions until voting +- Screenshots validated as reachable images ## Vote Phase +- All suggestions visible with authors - Score each suggestion 0–10 -- Players see only their own votes +- Players see only their own votes; can finalize/unfinalize their ballot +- **Linked games**: admins can link duplicates; linked games share a vote group. Moving a slider on one updates all linked siblings. +- Linking two games clears votes for the linked group and unfinalizes affected players ## Results Phase -- Totals, vote count, optional averages -- Sorted by total descending +- Visible only after admin enables results; players auto-advance when opened +- Leaderboard sorted by average score; shows totals, counts, player’s own vote, and links/media ## Non-functional -- Desktop + mobile usable -- IIS-hosted +- Desktop + mobile friendly +- Runs on IIS; SQLite via EF Core