feat: accept tenant slug in team endpoints (tenant_id int vs slug contract mismatch) #87
Labels
No labels
domain:backend
domain:devops
domain:frontend
status:approved
status:in-progress
status:needs-fix
status:qa
type:bug
type:devops
type:feature
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
forgejo_admin/basketball-api#87
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Lineage
plan-2026-03-08-tryout-prep→ Phase 10 → Phase 10d-1 (Fix integration bugs)First sub-phase of the integration validation + observability loop.
Repo
forgejo_admin/basketball-apiUser Story
As the westside-app frontend
I want to call team endpoints using the tenant slug
westside-kings-queensSo that the API contract matches the roster endpoints and the frontend doesn't need to know internal tenant IDs
Context
Playwright E2E validation (2026-03-15) revealed that all team endpoints return 422 Unprocessable Entity when called with
tenant_id=westside-kings-queens. The endpoints expecttenant_id: intbut the westside-app sends the tenant slug string.The roster endpoints (
/api/roster/{tenant_slug}) use the slug as a path parameter. The team endpoints usetenant_id: intas a query parameter. This contract mismatch means the frontend has no way to call team endpoints without knowing the internal numeric ID.Fix approach: Change team endpoint
tenant_idquery parameters to accept either an integer ID or a string slug. Use a helper function that resolves the input to a Tenant object: if the value is numeric, look up by ID; if string, look up by slug. This is backwards-compatible — existing integer callers still work.File Targets
Files the agent should modify:
src/basketball_api/routes/teams.py— changetenant_id: intquery params totenant_id: stron all endpoints that accept it. Add resolution logic: iftenant_id.isdigit()→ lookup by ID, else → lookup by slug. Apply to: list teams, create team, team overview, assign players, unassign player._get_tenant_or_404(db, tenant_id: int)helper — update to acceptstr | intand resolve accordingly.Files the agent should NOT touch:
src/basketball_api/routes/roster.py— already uses slug, working correctlysrc/basketball_api/models.py— no schema changes neededAcceptance Criteria
GET /api/teams?tenant_id=westside-kings-queensreturns 200 with team listGET /api/teams?tenant_id=1still returns 200 (backwards compatible)GET /api/teams/overview?tenant_id=westside-kings-queensreturns 200POST /api/teamswithtenant_id: "westside-kings-queens"in body → resolves to correct tenantTest Expectations
pytest tests/test_teams.py -vConstraints
TeamCreatePydantic model hastenant_id: int— change totenant_id: int | strand resolve in the route handler_get_tenant_or_404patternChecklist
Related
project-westside-basketball— Phase 10d-1 (integration validation)