Validation: Populate team_name in PracticeScheduleResponse from Team join

validation-341-2026-04-04 Doc

validation pass

Verdict: PASS

Ticket

forgejo_admin/basketball-api#341 (board item #827 on board-westside-basketball) — Added team_name field to PracticeScheduleResponse and populated it from the Team join, fixing null team_name in /public/schedule responses.

Environment

Production cluster (archbox k3s), namespace basketball-api. Pod: basketball-api-5ddc9f8695-s8g2m, image tag bbe2de0 (matches merge commit). Woodpecker pipeline #349: success.

Checks

# Criterion Tier How Verified Result Evidence
1 PracticeScheduleResponse includes team_name: str | None field T1 grep team_name in schedule.py (line 50) PASS <code>team_name: str | None = None</code> present in model
2 GET /public/schedule returns team_name populated from Team.name for every practice with a team_id T3 kubectl exec python3 urllib against localhost:8000/public/schedule PASS All 17 practices return non-null team_name (e.g. "16U Local Kings", "17U Local Kings", "16U Elite Kings")
3 Practices without a team_id return team_name: null T1 Code review of _practice_to_response() line 150 PASS <code>team_name=ps.team.name if ps.team else None</code> — null-safe via conditional
4 No N+1 queries — team relationship eagerly loaded via joinedload T1 grep joinedload in schedule.py and public.py PASS joinedload(PracticeSchedule.team) present at lines 217, 252 (schedule.py) and 202 (public.py)
5 Existing schedule tests pass T1 pytest tests/test_schedule.py PASS 39 passed in 3.95s
6 Woodpecker CI pipeline green T3 mcp__woodpecker__list_pipelines PASS Pipeline #349 (push to main): success
7 Pod running, 0 restarts, correct image T3 kubectl get pods -n basketball-api PASS Running, 0 restarts, image tag bbe2de0 matches merge commit

Regression Check

Verified other public endpoints still functional:
  • /public/teams: 200, returns teams object
  • /public/schedule: 200, returns practices + events
  • /docs: 200, OpenAPI docs accessible
  • 684 non-email tests pass (68 failures are all pre-existing email import errors unrelated to this change)

Discovered Issues

Pre-existing: 6 test files have broken imports from basketball_api.services.email (missing _build_player_section, _get_optional_user, _html_to_plain_text, _format_day, _format_time_12h). These are pre-existing import mismatches from prior email refactors, not caused by this PR. Should be tracked as a separate issue.