Review: Public schedule endpoint (GET /public/schedule)

review-653-2026-03-28 Review

review approved

Verdict: APPROVED

Template Completeness

  • [x] Type — Feature
  • [x] Lineage — prerequisite for westside-landing#172, admin endpoints #232/#233 merged
  • [x] Repo — forgejo_admin/basketball-api
  • [x] User Story — story:WS-S13, clear who/what/why
  • [x] Context — explains admin vs public pattern, single-tenant, is_active filtering
  • [x] File Targets — specific paths with modify/reference/do-not-touch annotations
  • [x] Acceptance Criteria — 5 testable conditions
  • [x] Test Expectations — happy path, no-auth, active filter, run command specified
  • [x] Constraints — follow existing public.py pattern, reuse schemas, keep simple
  • [x] Checklist — PR, tests, no unrelated changes
  • [x] Related — blocks westside-landing#172, references #232/#233, project-westside-basketball

Traceability

  • [x] story:WS-S13 — As a prospect or parent, I want to see the current schedule on the public website without needing to log in.
  • [x] arch:basketball-api — public routes module in basketball-api
  • [x] Forgejo issue — forgejo_admin/basketball-api#239, open

File Targets

  • [x] src/basketball_api/routes/public.py — verified: exists (290 lines), contains GET /teams and GET /coaches endpoints with no-auth pattern (hardcoded tenant_id=1). Schedule endpoint will follow same pattern.
  • [x] src/basketball_api/routes/schedule.py — verified (reference only): admin schedule endpoints exist with CombinedScheduleResponse (line 118), PracticeScheduleResponse (line 39), EventResponse (line 77). Reusable response schemas confirmed.
  • [x] src/basketball_api/models.py — verified (do-not-touch): PracticeSchedule has is_active column (line 522). Event model has no is_active — consistent with AC filtering only practices by is_active.
Targets are specific enough for agent execution. Single file to modify with clear pattern reference.

Repo Placement

Correct. Issue filed on forgejo_admin/basketball-api, fix targets basketball-api only. Public router mounted at /public prefix in main.py (line 90). No cross-repo changes needed. The downstream consumer (westside-landing#172) is a separate ticket on a separate repo.

Dependencies

  • [x] basketball-api#232 (data model) — satisfied (merged)
  • [x] basketball-api#233 (admin CRUD endpoints) — satisfied (merged)
  • [x] No unresolved dependencies blocking execution
Board item #649 ("Public schedule: API-driven refactor", arch:westside-app) is blocked-by:239 — this ticket unblocks the frontend refactor. Board item #130 ("Phase 13: Practice Schedule") is in backlog — related but not a direct dependency.

Acceptance Criteria

5 criteria, all verifiable by agent:
  • [x] GET /public/schedule returns { practices, events } — testable via HTTP client in pytest
  • [x] No authentication required — testable by omitting auth token
  • [x] Only active practices returned (is_active=true) — testable with fixture data containing inactive practices
  • [x] Response shape matches admin schedule endpoint — testable by comparing schema fields
  • [x] Existing tests still pass — testable via pytest tests/ -v
All criteria are specific and programmatically verifiable. No ambiguous language.

Blast Radius

Low. Additive endpoint on public router — no existing behavior changes. No existing /public/schedule route. No model changes. No admin endpoint changes. The public router pattern (tenant_id=1 hardcoded, no auth dependency) is well-established with teams and coaches endpoints. Rollback is trivial (revert one file).

Decomposition Assessment

No decomposition needed.
  • 1 file to modify (routes/public.py)
  • 5 acceptance criteria (at threshold but all tightly related to a single endpoint)
  • Single repo (basketball-api)
  • Estimated agent time: 2-3 minutes — well within 5-minute rule
  • No independent subtasks that warrant parallelization

Recommendation

No action needed.