Review: Schedule API endpoints (CRUD)

review-233-2026-03-28 Doc

review ready

Verdict: READY

Template Completeness

  • [x] Type -- Feature
  • [x] Lineage -- child of #230, depends on #232
  • [x] Repo -- forgejo_admin/basketball-api
  • [x] User Story -- story:WS-S13, admin CRUD for schedule entries
  • [x] Context -- thorough, includes design decisions from decomposed parent
  • [x] File Targets -- 3 files (create/modify), pattern references, exclusions listed
  • [x] Acceptance Criteria -- 10 items, all verifiable
  • [x] Test Expectations -- 5 categories + run command
  • [x] Constraints -- 4 items, pattern refs for structure (jersey.py) and auth (admin.py)
  • [x] Checklist -- present
  • [x] Related -- parent, sibling blocker, project, follow-up noted

Traceability

  • [x] story:WS-S13 label -- "As an admin, I want API endpoints to manage schedule entries"
  • [x] arch:basketball-api label -- basketball-api routes layer
  • [x] Forgejo issue -- forgejo_admin/basketball-api#233, open

File Targets

  • [x] src/basketball_api/routes/schedule.py -- NEW file, confirmed does not exist. Parent directory routes/ exists with 18 sibling route files.
  • [x] src/basketball_api/main.py -- EXISTS, verified. Router imports at lines 13-28, router includes follow. Registration point is clear.
  • [x] tests/test_schedule.py -- NEW file, confirmed does not exist. tests/ directory exists.
  • [x] Pattern ref: routes/admin.py -- verified 1048 lines (matches ticket claim), has require_admin = require_role("admin") at line 48, tenant_id scoping throughout.
  • [x] Pattern ref: routes/jersey.py -- verified: APIRouter, inline Pydantic models, dedicated route file. Note: jersey.py has NO auth (only get_db dependency). Ticket correctly separates concerns: jersey.py for file structure, admin.py for auth pattern.
  • [x] Pattern ref: routes/checkout.py -- verified: another dedicated route file with require_admin auth.
  • [x] Division enum -- verified at models.py:52, values: boys/girls. Ticket's mention of Division filter is accurate.
  • [x] No PracticeSchedule/EventSchedule models exist yet -- correct, #232 will create them.
Targets are specific enough for an agent to act without guessing. Pattern references are accurate and well-differentiated (structure vs. auth).

Repo Placement

OK. Issue filed on basketball-api, all work targets basketball-api. Single-repo scope. The ticket notes a downstream follow-up (admin schedule view in westside-app) but correctly defers it as separate work.

Dependencies

  • [x] blocked-by:232 -- Board item #629 (Forgejo #232, data model + migration + seed) is in todo column, not yet in progress. This ticket cannot begin until #232 merges. Dependency is documented in board labels, issue Lineage, Context, Checklist, and Related sections.
  • [x] Parent #230 -- Board item #627, marked status:decomposed in backlog. Correctly decomposed into #232 and #233.
No unresolved dependency ambiguity. The blocker is clear and tracked.

Acceptance Criteria

10 AC items covering 9 CRUD endpoints + 1 cross-cutting auth/tenant requirement. Each is testable via HTTP assertions in pytest:
  • GET/POST/PUT/DELETE for practices (4 endpoints)
  • GET/POST/PUT/DELETE for events (4 endpoints)
  • Combined GET /admin/schedule (1 endpoint)
  • All endpoints tenant-scoped + admin-authenticated (1 cross-cutting)
Test expectations add 5 verification categories: happy path, tenant isolation, filter tests, 404 handling, and Pydantic validation. Run command provided. All criteria are specific and machine-verifiable.

Blast Radius

Low risk:
  • No existing schedule route code in basketball-api -- pure greenfield addition.
  • westside-app has a public /schedule page but it uses hardcoded HTML, not API calls. Unaffected.
  • No other services reference schedule endpoints.
  • New router registration in main.py is additive (one import + one include_router line).
  • Rollback: revert the PR. No migrations in this ticket (handled by #232).

Decomposition Assessment

Applying the three-thing limit and five-minute rule:
  • Discrete changes: 3 file targets (1 new route file, 1 main.py registration, 1 test file). Meets the three-thing limit.
  • AC count: 10 acceptance criteria + 5 test categories = 15 checkable items. This is on the upper boundary. However, the 9 endpoints follow 2 identical CRUD patterns (practices, events) with strong codebase precedent. An agent templates one resource and replicates.
  • Estimated agent time: Under 5 minutes. Mechanical CRUD with explicit pattern references, inline Pydantic schemas (no separate file), and clear constraint boundaries.
  • Parallelizable subtasks: None -- the route file, registration, and tests are tightly coupled.
No decomposition needed. The high AC count is offset by the mechanical, pattern-following nature of the work.

Recommendation

No action needed.