Review: Bug: player profile page doesn't display parent phone number
Verdict: READY
Template Completeness
- [x] Type — Bug
- [x] Lineage — Standalone, discovered during admin CRM audit
- [x] Repo — forgejo_admin/westside-landing
- [x] What Broke — detailed root cause with line references
- [x] Repro Steps — step-by-step with real player data
- [x] Expected Behavior — clear target state
- [x] Environment — cluster/namespace identified
- [x] Acceptance Criteria — 5 criteria, all testable
- [x] Related — companion issue referenced
Traceability
- [x] story:WS-S12 — "As an admin, I want to manage user accounts (reset passwords, view profiles) so that I can support parents directly"
- [x] story note verified — found in project-westside-basketball user-stories section under Admin (Marcus)
- [x] arch:westside-app — references the SvelteKit frontend
- [ ] arch note MISSING — [SCOPE] Create architecture note arch-westside-app for component westside-app (pre-existing gap, not specific to this ticket)
- [x] Forgejo issue — forgejo_admin/westside-landing#203, open
File Targets
- [x]
src/routes/(app)/players/[id]/+page.svelte— verified exists (576 lines) - [x] Line 540: template checks
player.parent_phone— confirmed at line 540 - [x] Line 56:
player = await apiFetch(`/players/${id}`)— confirmed at line 56, assigns raw API response with no field mapping - [x] Line 45: mock data uses flat
parent_phoneshape — confirmed - [x] API response shape verified:
basketball-api/src/basketball_api/routes/players.pyreturns nestedparent: { id, name, email, phone }viaPlayerProfileResponse(line 40) andParentInfo(line 25)
Repo Placement
Correct. The fix belongs in westside-landing (the SvelteKit frontend). The data shape mismatch is on the consumer side — the API returns a well-structured nested response; the frontend needs to map
player.parent.phone to player.parent_phone (or update template references). Companion issue basketball-api#276 is separate (admin list endpoint, different code path).Dependencies
- [x] Board item #736 (basketball-api#276: "parent phone missing from /admin/players list endpoint") — companion but not a blocker. That issue is about the admin list endpoint; this issue is about the individual player profile page. They use different API endpoints and different response schemas.
- No unresolved blockers.
Acceptance Criteria
All 5 criteria are testable by an agent:
- [x] AC1: Phone link in Admin Actions — verifiable via DOM inspection after login
- [x] AC2: Specific player 111 phone — verifiable with known data
- [x] AC3: Parent name/email still display — regression check
- [x] AC4: Mock player 999 still renders — route to /players/999
- [x] AC5: Coach roster unaffected — uses different endpoint/data shape, no risk
Blast Radius
- parent_email has the same bug: Line 546 checks
player.parent_emailbut API returnsplayer.parent.email. The issue only mentions phone, but email is equally broken with real API data. - parent_name has the same bug: Not rendered in Admin Actions card, but the fallback error handler (line 76) sets flat
parent_name: ''— inconsistent with API shape. - Coach page (
/coach/+page.svelte) uses flatparent_phonebut consumes a different endpoint (/roster) that returns flat fields — no blast radius there. - Admin players page (
/admin/players/+page.svelte) uses flatparent_name/parent_phonefrom/admin/playersendpoint which also returns flat — no blast radius there. - Rollback is straightforward — single file, UI-only change.
Decomposition Assessment
Apply the three-thing limit and five-minute rule:
- 1 file target, 1 repo — well under the 3-file threshold
- 5 acceptance criteria — at the limit but all are simple verification checks
- Estimated agent work: <5 minutes (add field mapping after apiFetch on line 56)
- No independent subtasks to parallelize
- No decomposition needed.
Recommendation
- [BODY] Add note to issue body: "parent_email (line 546) and parent_name (line 76 fallback) have the same nested-vs-flat mismatch. Fix should map all three parent fields from
player.parent.{name, email, phone}after the apiFetch call on line 56." - [SCOPE] Create architecture note
arch-westside-appfor component westside-app (pre-existing gap across multiple tickets, not a blocker for this one).