Review: Show contract status in admin CRM player list
Verdict: READY
Template Completeness
- [x] Type — Feature
- [x] Lineage — Standalone, discovered during contract data audit
- [x] Repo — forgejo_admin/westside-app
- [x] User Story — As Marcus (admin), see contract status on player cards
- [x] Context — Thorough: explains API field exists, 10 signed / 45 unsigned, billing relationship
- [x] File Targets — Two files with specific guidance + explicit "do NOT touch" list
- [x] Acceptance Criteria — Three clear criteria
- [x] Test Expectations — Acknowledges no test harness, provides manual validation path
- [x] Constraints — Five constraints including no-Tailwind, enum values, no new filter
- [x] Checklist — Present
- [x] Related — project-westside-basketball referenced
All sections from
template-issue-feature are present and well-populated.Traceability
- [x] story:WS-S9 label — present on board item #534
- [x] arch:westside-app label — present on board item #534
- [x] Forgejo issue — forgejo_admin/westside-app#137, open
All three legs of the traceability triangle are satisfied.
File Targets
- [x]
src/routes/(app)/admin/players/+page.svelte— verified: file exists. Already containsgetContractBadgeClass(line 59),getContractLabel(line 67),signedCountderived (line 128), and badge rendering in card template (line 180). Implementation already complete on branch137-contract-status-admin-crm. - [x]
src/app.css— verified: file exists. Badge classes.badge-signed,.badge-offered,.badge-no-contractalready present at lines 1348-1350, alongside existing badge definitions (lines 1329-1347). Issue reference "lines ~1316-1334" is approximately correct (actual badge section starts line 1326).
"Do NOT touch" files correctly identified —
src/lib/api.js and backend files are not modified.Repo Placement
OK. Issue is filed on
forgejo_admin/westside-app, which is the correct repo. All changes are frontend-only — no backend/basketball-api modifications needed since contract_status is already in the API response. Single-repo scope is correct.Dependencies
- Phase 14 (Billing Tiers & Contracts, board item #556) is in_progress — this ticket is a child of that phase's scope, but has no blocking dependency on incomplete Phase 14 work. The API field already exists.
- No blocking items identified. The
GET /admin/playersendpoint already returnscontract_statusper player. - Phase 15 (Production Port, board item #545) is also in_progress but is independent — SPA rebuild would carry these changes forward.
Acceptance Criteria
Three criteria, all verifiable by visual inspection:
- Contract status badge per card (Signed/green, No Contract/gray, Offered/yellow) — verifiable by admin login and checking player cards
- Signed count in header summary — verifiable by checking header text
- Badge styling matches existing patterns — verifiable by comparing badge CSS classes against existing
getStatusBadgeClasspattern
All criteria are agent-verifiable. No automated test expectation (correctly noted — static-adapter SvelteKit app with no test harness).
Blast Radius
- The player detail page (
/players/[id]) has its owngetStatusBadgeClassbut does NOT yet show contract_status. This is separate scope — not a concern for this ticket. - The
/my-playerspage usesbadge-offeredclass for a different purpose (team offers). No conflict — CSS class is shared but semantically appropriate. - Contract badge CSS classes are global in
app.cssand could be consumed by future pages without additional CSS work. No downstream risk.
Decomposition
2 file targets, 1 repo, 3 acceptance criteria. Well within the 5-minute rule. No decomposition needed.
Implementation Status
NOTE: This work has already been implemented. Commit
1d81ef5 on branch 137-contract-status-admin-crm fulfills all acceptance criteria. PR #141 is open and awaiting review/merge. The scope review confirms the ticket was well-scoped — the implementation matches the spec exactly.Recommendation
No action needed. Scope is solid, all file targets verified, traceability complete, implementation already done. Ticket can proceed through QA/merge on PR #141.