Review: jersey-public.html — public intake prototype (System B)

review-942-2026-04-10 Review

review approved

Verdict: APPROVED (re-review 2026-04-10)

Second pass after refinement. Both findings from the first pass are resolved on Forgejo issue forgejo_admin/westside-playground#57. Ticket is ready to advance from backlog to todo per feedback_todo_means_reviewed.md.

Refinement Verification

  • [x] [BODY] AC-3 gear.html reference removed — New AC-3 reads: "When I select Kings, both card images use the kings-home.jpeg and kings-away-new.jpeg sources. When I select Queens, both card images use queens-home.jpeg and queens-away-new.jpeg. The swap is implemented in vanilla JS — there is no existing K/Q pattern to mirror; this is built from scratch." No gear.html mention anywhere in AC-3.
  • [x] AC-3 lists four explicit filenameskings-home.jpeg, kings-away-new.jpeg, queens-home.jpeg, queens-away-new.jpeg all present.
  • [x] AC-3 states "built from scratch" — Verbatim phrase present.
  • [x] File Targets lists four MinIO URLs — All four URLs under "Image sources (verified HTTP 200):" in the File Targets section.
  • [x] Context notes the "no existing pattern" decision — New Context bullet: "Kings/Queens image swap must be built from scratch. Neither jersey.html (hardcoded Queens) nor gear.html (no K/Q toggle) has an existing pattern to reuse. Implement with vanilla JS: a radio or toggle that swaps the two <img> src attributes between the Kings and Queens filenames listed under File Targets."
  • [x] [SCOPE] arch-jersey-intake follow-up noted in Related as non-blocking — Related ends with: "Follow-up (not blocking): create arch-jersey-intake note documenting System A + System B coexistence before any backend/API work lands. Reviewer flagged this as required-before-backend-follow-up but not a gate for this playground ticket." Explicit non-blocking disposition matches first-review guidance.

Regression Check

Spot-checked all sections that were not the target of the refinement to confirm nothing drifted:
  • [x] AC-5 "jersey.html byte-identical to before" — intact (git diff main -- jersey.html returns empty)
  • [x] AC-2 field enumeration — intact (Player Name, Team, K/Q, three preferred numbers, top size, short size, tier)
  • [x] AC-7 mobile/Tailscale exit gate — intact
  • [x] "Do not touch" list — intact (jersey.html, checkout.html, checkout-success.html, jersey-success.html, gear.html, shared/style.css, shared/app.js)
  • [x] No-Tailwind constraint — intact (references feedback_no_tailwind.md)
  • [x] Two-tier spec ($90 Reversible / $130 Reversible + Shooter Shirt) — intact
  • [x] Shooter shirt size "not collected" decision — intact in Context
  • [x] System A/B split language — intact; "No conflict, no merge" preserved
  • [x] story:WS-S31 reference — intact in Related
  • [x] Playground-first + exit-gate language — intact
  • [x] Checklist (PR opened, Tailscale preview posted, zero changes to jersey.html, no unrelated changes) — intact
No regressions. Refinement was surgical and did not disturb the surrounding scope.

Final Verdict

APPROVED. Ticket #57 is ready to advance backlog → todo on board-westside-basketball. The arch-jersey-intake follow-up remains an open scope item but is correctly flagged as non-blocking for this playground ticket — it needs to exist before any backend/API jersey-intake work, which is out of scope here.

First-pass verdict: NEEDS_REFINEMENT (2026-04-10, preserved for provenance)

Scope is fundamentally sound and well-constrained. Minor fixable issues in the ticket body and one missing arch note. Not a BLOCK — the page can be built with the field spec and constraints as written. Fixes below are small and unblocking.

Template Completeness

  • [x] Type — Feature
  • [x] Lineage
  • [x] Repo
  • [x] User Story (WS-S31, full narrative)
  • [x] Context (decisions locked, System A/B split explained)
  • [x] File Targets (creates + "do not touch" list)
  • [x] Acceptance Criteria (7 items, measurable)
  • [x] Test Expectations (manual, playground convention)
  • [x] Constraints
  • [x] Checklist
  • [x] Related
All required sections for template-issue-feature present.

Traceability

  • [x] story:WS-S31 label — "long-standing public jersey order link"
  • [x] story note verified — WS-S31 found in project-westside-basketball user-stories Admin section (added 2026-04-10)
  • [x] arch:jersey-intake label present on board item
  • [ ] arch note MISSING — no arch-jersey-intake note found via search_notes. [SCOPE] Create architecture note arch-jersey-intake documenting System A (token-gated roster) + System B (public intake) coexistence, field spec, and the explicit "no merge" decision. Not a blocker for this playground ticket but must exist before any backend/API work on jersey intake lands.
  • [x] Forgejo issue — forgejo_admin/westside-playground#57, open

File Targets

  • [x] /home/ldraney/westside-playground/ — repo exists
  • [x] jersey-public.html — verified does NOT already exist (safe to create)
  • [x] jersey.html — exists, will be protected by AC "byte-identical to before"
  • [x] shared/style.css — exists
  • [x] MinIO image URLs verified live: https://minio-api.tail5b443a.ts.net/assets/westside/jerseys/queens-home.jpeg (HTTP 200) and kings-home.jpeg (HTTP 200)
  • [x] jersey.html already sources images from the same MinIO base — URL pattern is consistent with System A, no inconsistency

Repo Placement

OK. westside-playground is the correct repo per feedback_playground_first.md and feedback_linked_repo_model.md (per-project playground). No cross-repo spillover.

Dependencies

No blocking dependencies. Board in_progress column has unrelated items (phases 11/14/15, basketball-api #274, accounting #4, basketball-api #408). No jersey-intake work in flight. Ticket correctly scopes out Stripe, backend submission, gear landing link, and minio-mcp as separate future tickets.

Acceptance Criteria

7 ACs, all manually verifiable. Strong points:
  • AC-5 "jersey.html byte-identical to before" is an excellent System A protection — directly diff-testable
  • AC-2 enumerates exact form fields (matches 8-turn scoping with Lucas)
  • AC-7 gates on mobile/Tailscale preview — correct exit gate per feedback_playground_gate.md
Issues:
  • [BODY] AC-3 says "When I select Kings or Queens, the jersey images update to match (same pattern as gear.html)". Verified gear.html does NOT contain a Kings/Queens image swap pattern (138 lines, 7 img tags, no K/Q toggle logic). The reference is misleading. Fix: either drop "(same pattern as gear.html)" or point to a real source — jersey.html itself hardcodes Queens images for a fixed division, so there's no existing K/Q toggle in the playground to mirror. The agent will need to build the swap from scratch; say so explicitly.

Blast Radius

Low. Scope is additive (new file only). Explicit "do not touch" list covers all wired System A files (jersey.html, checkout.html, checkout-success.html, jersey-success.html). No shared CSS/JS modifications unless strictly required. MinIO images already consumed by jersey.html — no new external dependencies. Zero risk to production (playground-only).

Decomposition Assessment

No decomposition needed. 1 file target, 7 ACs, estimated agent time ~15–25 min for form + styling + K/Q swap JS. Within single-pass budget for a playground HTML page. (The 5-AC threshold is exceeded at 7, but all 7 are tightly coupled to one file — splitting would create artificial handoffs. Playground HTML pages are the canonical single-agent unit per feedback_playground_first.md.) Verdict: single agent pass, no sub-board.

Recommendation

  • [BODY] Fix AC-3: remove the "(same pattern as gear.html)" reference — gear.html has no K/Q image swap. Replace with: "When the K/Q selector is toggled, the tier card images swap between kings-home.jpeg/kings-away-new.jpeg and queens-home.jpeg/queens-away-new.jpeg from the MinIO jerseys bucket. Build the swap with vanilla JS — no existing pattern to mirror."
  • [SCOPE] Create architecture note arch-jersey-intake documenting System A (token-gated, jersey.html, existing) + System B (public, jersey-public.html, this ticket) coexistence. Not blocking this playground ticket but required before any backend/API follow-up.
Both are small. Scope is otherwise solid, traceability is complete, file targets verified, and the exit gate (Lucas's phone via Tailscale) is correct.