Review: Admin queue view for Marcus (re-review)

review-814-2026-04-03-v2 Doc

review ready

Verdict: READY

Re-review of board item #814 after body + label fixes from first review. All three prior issues resolved.

Template Completeness

  • [x] Type — Feature
  • [x] Lineage — depends on #39, standalone otherwise
  • [x] Repo — forgejo_admin/twitch-2k-wager
  • [x] User Story — operator-flow: Marcus sees paid challengers + gamertags
  • [x] Context — admin queue, ADMIN_SECRET auth, depends on #39 for gamertag field
  • [x] File Targets — 4 files listed
  • [x] Acceptance Criteria — 8 criteria
  • [x] Test Expectations — 3 test items
  • [x] Constraints — auth pattern, gamertag dependency, dark theme, minimal
  • [x] Checklist — standard PR checklist
  • [x] Related — #39, #12, story note, arch note

Traceability

  • [x] story:operator-flow label — Marcus Operator Flow
  • [x] story note verified — story-twitch-2k-wager-operator-flow (id 1210) exists, active, note_type=user-story
  • [ ] story NOT on project page — [SCOPE] Add operator-flow row to project-twitch-2k-wager user-stories table
  • [x] arch:dataflow-twitch-2k-wager label — Data Flow: Twitch 2K Wager
  • [x] arch note verified — arch-dataflow-twitch-2k-wager (id 1155) exists, active, note_type=architecture
  • [x] Forgejo issue — forgejo_admin/twitch-2k-wager#40, state=open

File Targets

  • [x] src/routes/admin/+page.svelte — new file (admin route does not exist yet, parent dir src/routes/ exists, expected for feature)
  • [x] src/routes/admin/+page.server.ts — new file (expected)
  • [x] src/routes/admin/+layout.server.ts — new file (admin auth guard, expected)
  • [x] src/lib/db.ts — verified exists. Currently has listQueuedGames() but no join query. Ticket correctly identifies need for listGamesWithChallengers() join query. Fix from prior review confirmed present in issue body.
Targets are specific enough for an agent to act on without guessing.

Repo Placement

OK. All 4 file targets are in forgejo_admin/twitch-2k-wager. Issue is filed on the same repo. No cross-repo work.

Dependencies

  • [x] #39 (guest checkout API — gamertag field) — status: pending (open, board item #813 in backlog). Adds gamertag column to challenger table. This ticket's join query needs that column. Dependency is explicitly documented in Lineage + Context + Constraints. Must be merged before this ticket can be implemented.
  • [x] #12 (admin result endpoint) — status: satisfied (board item #798 in validation, code exists at src/routes/api/admin/result/+server.ts). Uses Bearer ADMIN_SECRET auth pattern. This ticket's result buttons will call that existing endpoint. No changes needed.

Acceptance Criteria

8 criteria. All are testable by an agent:
  • AC 1: /admin?key=ADMIN_SECRET shows queue + sets cookie — testable via server load function + cookie check
  • AC 2: each game shows gamertag, email, tier, pot, status, timestamp — testable via DOM check with test data
  • AC 3: "Challenger Wins" and "Marcus Wins" buttons on active games — testable via component render
  • AC 4: result button calls /api/admin/result with Bearer header — testable via fetch mock or integration test
  • AC 5: completed games show result + payout status — testable via DOM check
  • AC 6: auto-refresh poll every 5s — testable via setInterval presence in component
  • AC 7: mobile-friendly — testable via responsive CSS check
  • AC 8: returns 401 without valid secret — testable via server load function test
Auth pattern (query param to cookie to Bearer for API) is clarified in Constraints. Matches existing admin result endpoint's Bearer pattern. No ambiguity.

Blast Radius

Low. New route (/admin) with no existing consumers. The only shared code touched is db.ts (adding a new exported function, not modifying existing ones). The admin result endpoint (#12) is called from the new page but not modified. No downstream consumers affected. Rollback is straightforward — delete the admin route directory and the one db function.

Decomposition Assessment

4 file targets in 1 repo. 8 AC (above the 5-rule threshold). However, all targets are tightly coupled — 3 files form a single SvelteKit admin route, plus 1 db query addition. No independent subtasks that would benefit from parallelization. Estimated agent time: 3-4 minutes for a single coherent pass. No decomposition needed.

Prior Review Issues (resolved)

  • story label mismatch — fixed. Label is now story:operator-flow. Story note story-twitch-2k-wager-operator-flow created (id 1210).
  • missing db.ts query — fixed. Issue body now specifies listGamesWithChallengers() join query in file targets.
  • gamertag gap — resolved. Documented as dependency on #39. Schema has no gamertag column; #39 adds it.
  • auth pattern — clarified. Query param to cookie to Bearer header for API. Consistent with existing admin result endpoint.

Recommendation

  • [SCOPE] Add operator-flow row to project-twitch-2k-wager user-stories table (story note exists but project page table is missing the entry). Not a blocker for implementation.