Review: CRM: show jersey payment status per player
Verdict: NEEDS_REFINEMENT
Template Completeness
- [x] Type
- [x] Lineage
- [x] Repo
- [x] User Story
- [x] Context
- [x] File Targets
- [x] Acceptance Criteria
- [x] Test Expectations
- [x] Constraints
- [x] Checklist
- [x] Related
Traceability
- [x] story:WS-S9 label — admin/business management story
- [x] arch:westside-app label — frontend component
- [x] Forgejo issue — forgejo_admin/westside-landing#183, open
File Targets
- [~]
src/routes/(app)/admin/— EXISTS but imprecise. Actual target issrc/routes/(app)/admin/players/+page.svelte(8.7k, 297 lines). Currently shows player name, status badges, contract status, parent info, visibility toggle. No jersey fields displayed. - [x]
src/routes/(app)/jersey/— correctly excluded (ordering page, separate concern) - [ ] MISSING TARGET:
basketball-api/src/basketball_api/routes/admin.py— TheAdminPlayerItemresponse model (lines 289-302) does NOT includejersey_option,jersey_size,jersey_number, orjersey_order_status. These fields exist on the Player model (models.py lines 240-249) but are not serialized in the admin endpoint response. A backend change is required.
Repo Placement
Issue filed on
forgejo_admin/westside-landing which is correct (local: ~/westside-app). However, the fix also requires a change in forgejo_admin/basketball-api to add jersey fields to the AdminPlayerItem schema. Either: (a) create a separate backend ticket on basketball-api, or (b) re-scope this as a cross-repo ticket with both targets documented.Dependencies
- Backend blocker:
AdminPlayerItemmust include jersey fields before the frontend can display them. The issue's Constraints section incorrectly claims "Backend data already exists — this is frontend-only." - Item #534 (done): "Show contract status in admin CRM player list" — same WS-S9 story, same file target. Precedent for adding columns to the CRM. Good pattern to follow.
- Item #592 (in_progress): "Add age-based team reassignment clause to Queens contracts" — same story but different concern (contracts, not CRM). No blocking relationship.
Acceptance Criteria
4 criteria. All are visually verifiable. "Easy to filter or sort by jersey status" is vague — does this mean a new filter tab (like existing status tabs), a sort toggle, or just visual scanning? Needs clarification. "Works on mobile" is standard but testable. Overall: criteria are reasonable but the filter/sort criterion needs specificity.
Blast Radius
- The admin CRM is a single page (
admin/players/+page.svelte). Adding columns/badges here is isolated — no other views consume the admin player list. - Jersey data is already used in 11 other files in the app (jersey ordering, checkout, teams display, gear page) but those are read-only consumers of different API endpoints. No cross-contamination risk.
- The
JerseyOrderStatusenum has 4 values: none, pending, paid, shipped. The issue only mentions 3 (none/pending/paid). If "shipped" status exists, it should be handled in the badge display too.
Decomposition
This ticket needs 2 repos (basketball-api + westside-app). Recommend splitting into 2 tickets:
- Backend: Add jersey fields to
AdminPlayerItemin basketball-api (1 file, ~10 lines). Quick (<5 min). - Frontend: Display jersey badges in admin CRM (1 file, moderate complexity). Quick (<5 min).
As-is, the single ticket crosses 2 repos and requires sequential execution (backend first). Decomposition recommended.
Recommendation
[BODY]Fix file target:src/routes/(app)/admin/→src/routes/(app)/admin/players/+page.svelte[BODY]Remove incorrect constraint: "Backend data already exists — this is frontend-only." Replace with: "Backend needs AdminPlayerItem schema update in basketball-api first."[BODY]Add backend file target:src/basketball_api/routes/admin.py— add jersey_option, jersey_size, jersey_number, jersey_order_status to AdminPlayerItem[BODY]Clarify AC: "Easy to filter or sort by jersey status" — specify: new filter tab, sortable column, or visual badge only?[BODY]Add missing jersey_order_status value: "shipped" (4 enum values exist, issue only mentions 3)[DECOMPOSE]Split into 2 tickets: (1) basketball-api: add jersey fields to AdminPlayerItem, (2) westside-app: display jersey badges in CRM. Backend blocks frontend.