fix: populate team_name in PracticeScheduleResponse from Team join #342

Merged
forgejo_admin merged 1 commit from 341-populate-team-name into main 2026-04-05 18:55:58 +00:00
Contributor

Summary

Adds team_name to PracticeScheduleResponse so the frontend can group practices by team name without a separate lookup.

Changes

  • src/basketball_api/routes/schedule.py -- Added team_name: str | None = None field to PracticeScheduleResponse. Updated _practice_to_response() to populate team_name from practice.team.name. Added joinedload(PracticeSchedule.team) to admin get_schedule and list_practices queries. Added joinedload to imports.
  • src/basketball_api/routes/public.py -- Added joinedload(PracticeSchedule.team) to the public schedule query.

Test Plan

  • 39 schedule tests pass, 23 public endpoint tests pass (430 total pass, 1 pre-existing failure unrelated to this change)
  • curl /public/schedule | jq '.practices[0].team_name' should return the team name string instead of null
  • Verify admin /schedule and /schedule/practices endpoints also return team_name

Review Checklist

  • ruff format and ruff check pass
  • All schedule and public tests pass (62 total)
  • Eager loading added to all three query sites (public schedule, admin get_schedule, admin list_practices)
  • No N+1 query regressions -- joinedload on all paths that call _practice_to_response
  • None

Closes #341

## Summary Adds `team_name` to `PracticeScheduleResponse` so the frontend can group practices by team name without a separate lookup. ## Changes - `src/basketball_api/routes/schedule.py` -- Added `team_name: str | None = None` field to `PracticeScheduleResponse`. Updated `_practice_to_response()` to populate `team_name` from `practice.team.name`. Added `joinedload(PracticeSchedule.team)` to admin `get_schedule` and `list_practices` queries. Added `joinedload` to imports. - `src/basketball_api/routes/public.py` -- Added `joinedload(PracticeSchedule.team)` to the public schedule query. ## Test Plan - 39 schedule tests pass, 23 public endpoint tests pass (430 total pass, 1 pre-existing failure unrelated to this change) - `curl /public/schedule | jq '.practices[0].team_name'` should return the team name string instead of null - Verify admin `/schedule` and `/schedule/practices` endpoints also return `team_name` ## Review Checklist - [x] ruff format and ruff check pass - [x] All schedule and public tests pass (62 total) - [x] Eager loading added to all three query sites (public schedule, admin get_schedule, admin list_practices) - [x] No N+1 query regressions -- joinedload on all paths that call _practice_to_response ## Related Notes - None ## Related Closes #341
feat: include is_public in admin players list response
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
3c167eae94
The AdminPlayerItem model and GET /admin/players response now include
the is_public boolean field, enabling the westside-app admin UI to
display and toggle player visibility state.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
fix: populate team_name in PracticeScheduleResponse from Team join
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
39a69c098c
Add team_name field to PracticeScheduleResponse and populate it via
practice.team.name in _practice_to_response(). Add joinedload(PracticeSchedule.team)
to public and admin schedule queries to avoid N+1 queries.

Closes #341

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Author
Contributor

QA Review -- PR #342

Scope Check

PR targets issue #341 (populate team_name in PracticeScheduleResponse). The core commit (39a69c0) addresses exactly the three changes specified in the issue.

Note: The diff includes an unrelated commit (3c167ea -- is_public in admin players) that was on the local main ahead of origin/main. This will resolve cleanly once that commit lands on the remote main. Not a blocker.

Code Review

Schema -- team_name: str | None = None added to PracticeScheduleResponse in the correct position (after team_id, before is_active). Optional field with None default means zero breaking change for existing consumers.

Population -- team_name=ps.team.name if ps.team else None in _practice_to_response() is correct. Handles the null case when no team is assigned.

Eager loading -- joinedload(PracticeSchedule.team) added to all three query sites:

  • public.py public_schedule() -- correct
  • schedule.py get_schedule() (admin combined) -- correct
  • schedule.py list_practices() (admin list) -- correct

This prevents N+1 queries when iterating practices. CUD endpoints (create_practice, update_practice) use db.refresh() which will lazy-load the team within the same session -- acceptable for single-object returns.

Tests

  • 39 schedule tests pass
  • 23 public endpoint tests pass
  • 430/431 total pass (1 pre-existing groupme_sdk import failure)
  • ruff format and ruff check clean

Nits

None. Clean, minimal change.


VERDICT: APPROVED

## QA Review -- PR #342 ### Scope Check PR targets issue #341 (populate `team_name` in `PracticeScheduleResponse`). The core commit (`39a69c0`) addresses exactly the three changes specified in the issue. **Note:** The diff includes an unrelated commit (`3c167ea` -- `is_public` in admin players) that was on the local main ahead of `origin/main`. This will resolve cleanly once that commit lands on the remote main. Not a blocker. ### Code Review **Schema** -- `team_name: str | None = None` added to `PracticeScheduleResponse` in the correct position (after `team_id`, before `is_active`). Optional field with None default means zero breaking change for existing consumers. **Population** -- `team_name=ps.team.name if ps.team else None` in `_practice_to_response()` is correct. Handles the null case when no team is assigned. **Eager loading** -- `joinedload(PracticeSchedule.team)` added to all three query sites: - `public.py` `public_schedule()` -- correct - `schedule.py` `get_schedule()` (admin combined) -- correct - `schedule.py` `list_practices()` (admin list) -- correct This prevents N+1 queries when iterating practices. CUD endpoints (`create_practice`, `update_practice`) use `db.refresh()` which will lazy-load the team within the same session -- acceptable for single-object returns. ### Tests - 39 schedule tests pass - 23 public endpoint tests pass - 430/431 total pass (1 pre-existing `groupme_sdk` import failure) - ruff format and ruff check clean ### Nits None. Clean, minimal change. --- **VERDICT: APPROVED**
forgejo_admin force-pushed 341-populate-team-name from 39a69c098c
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
to 706a7b3687
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
2026-04-05 18:53:02 +00:00
Compare
forgejo_admin deleted branch 341-populate-team-name 2026-04-05 18:55:58 +00:00
Sign in to join this conversation.
No description provided.