Review: Bug: GET /teams/{id} returns 422 -- tenant_id not auto-resolved like admin routes
Verdict: READY
Re-review after refinement. Previous verdict: NEEDS_REFINEMENT (review-877-2026-04-07). All recommendations addressed.
Template Completeness
Issue body not directly readable via MCP toolset (list_issues returns titles only). Refinements confirmed via prompt context: expanded scope to all routes in teams.py, added file targets, referenced schedule.py _get_tenant helper, fixed story label.
- [x] Type -- Bug (from title prefix)
- [x] Repo -- forgejo_admin/basketball-api (correct)
- [x] File Targets -- teams.py + test_teams.py (verified in codebase)
- [x] Fix pattern -- schedule.py _get_tenant helper referenced
- [?] Remaining template sections -- cannot verify body directly, accepted based on refinement confirmation
Traceability
- [x] story:WS-S10 label -- "As an admin, I want to manage coaches and assign them to teams so that teams have leadership." Teams routes serve admin team management. Acceptable fit.
- [x] story note verified -- WS-S10 found in project-westside-basketball user-stories section under Admin (Marcus) stories
- [x] arch:basketball-api label present
- [ ] arch note MISSING -- search for "arch-basketball-api" returned zero results. Pre-existing gap, not introduced by this ticket. Non-blocking for this review.
- [x] Forgejo issue -- forgejo_admin/basketball-api#372, confirmed open
File Targets
- [x]
src/basketball_api/routes/teams.py-- verified: 8 routes taketenant_id: stras explicit query param (lines 273, 293, 341, 372, 386, 463, 493, 541). create_team takes it in request body (TeamCreate model) which is a different pattern. - [x]
tests/test_teams.py-- verified: 878 lines, 41 test functions. Extensivetenant_id={tenant.id}in query strings throughout. All need mechanical update. - [x]
src/basketball_api/routes/schedule.py-- verified:_get_tenanthelper at line 128-132 usesDEFAULT_TENANT_SLUGfrom registration service. This is the fix pattern.
Repo Placement
OK. Issue filed on forgejo_admin/basketball-api, fix is in basketball-api. Single repo scope.
Dependencies
- Issue #262 (Extract shared _resolve_player helper) -- related DRY refactoring in same domain but independent. Not blocking.
- No blocking dependencies identified.
Acceptance Criteria
Expected AC (inferred from bug description + codebase analysis):
- All 8 GET/PATCH/DELETE/POST routes in teams.py auto-resolve tenant via DEFAULT_TENANT_SLUG (like schedule.py)
- tenant_id query parameter removed from all 8 route signatures
- create_team body.tenant_id may remain (creation explicitly specifies tenant) or be made optional with default -- agent should decide
- All 41 existing tests updated to remove tenant_id from query strings
- No regression in downstream consumers (westside-app, admin routes)
All criteria are agent-verifiable via test execution.
Blast Radius
Contained.
tenant_id: str as a query parameter is isolated to teams.py -- no other route files use this pattern. admin.py, schedule.py, register.py, and password_reset.py all auto-resolve via DEFAULT_TENANT_SLUG already.Clarification on "9 routes": The scope says all 9 routes, but create_team (POST "") takes tenant_id in the request body via TeamCreate model, not as a query param. The actual query-param fix applies to 8 routes. create_team is a judgment call for the implementing agent -- it can remain body-based or be made optional with a default.
Decomposition
No decomposition needed. 2 files (teams.py + test_teams.py), mechanical transformation (same pattern x8 routes + x41 tests). Single _get_tenant helper addition. Estimated agent time: 3-5 minutes. Fits within the 5-minute rule.
Recommendation
No action needed. All previous NEEDS_REFINEMENT items addressed:
- [LABEL] story:WS-S1 -> story:WS-S10 -- DONE
- [BODY] Scope expanded to all routes in teams.py -- DONE
- [BODY] File targets added (teams.py + test_teams.py) -- DONE
- [BODY] Fix pattern referenced (schedule.py _get_tenant) -- DONE
Pre-existing scope gap (arch note arch-basketball-api) is tracked but non-blocking.