Review: Public schedule: API-driven refactor

review-649-2026-03-28 Review

review needs-refinement

Verdict: NEEDS_REFINEMENT

Template Completeness

  • [x] Type — Feature
  • [x] Lineage — Follow-up from basketball-api#230, backend merged (#232, #233)
  • [x] Repo — forgejo_admin/westside-landing
  • [x] User Story — Clear who/what/why for prospects and parents viewing schedule
  • [x] Context — Thorough, correctly identifies the auth blocker question
  • [x] File Targets — Specific files with modify/reference/do-not-touch categories
  • [x] Acceptance Criteria — 5 testable criteria including progressive enhancement
  • [x] Test Expectations — Visual verification + build command
  • [x] Constraints — Auth requirement, blocker gate, design preservation
  • [x] Checklist — PR, no unrelated changes, verify endpoint first
  • [x] Related — Links to basketball-api PRs #232, #233 and project page
All required sections present per template-issue-feature.

Traceability

  • [x] story:WS-S13 label — "As a prospect or parent, I want to see the current schedule on the public website so that I know when practices and tournaments are, without the data being stale from a previous deploy."
  • [x] arch:westside-app label — westside-landing SvelteKit app (public site)
  • [x] Forgejo issue — forgejo_admin/westside-landing#172, open

File Targets

  • [x] src/routes/(public)/schedule/+page.svelte — verified: exists in westside-landing repo, contains hardcoded HTML with Kings tournaments (Utah State Invitational, Seal Beach Classic, Vegas + Championship), practice times for travel and local teams, Queens schedule. Confirmed as the refactor target.
  • [x] src/routes/(app)/admin/schedule/+page.svelte — verified: exists, already uses apiFetch('/admin/schedule') with division filter, loading/error states, formatTime()/formatDate() helpers. Good reference pattern.
  • [ ] src/lib/api.js — INACCURATE: Issue says "may need a public fetch variant without auth" but src/lib/public-api.js already exists with a publicFetch() function used by teams/coaches pages. The issue body should reference public-api.js and clarify that the public page should use publicFetch (not apiFetch).

Repo Placement

Issue filed on forgejo_admin/westside-landing — correct for the frontend refactor. However, the ticket has an unresolved cross-repo dependency: basketball-api has no GET /public/schedule endpoint. The existing schedule endpoints are all mounted at /admin/schedule with require_role("admin"). A separate basketball-api ticket must be created and merged before this work can proceed.

Dependencies

  • BLOCKER: No GET /public/schedule endpoint exists on basketball-api. All schedule routes (/admin/schedule, /admin/schedule/practices, /admin/schedule/events) require admin auth via require_role("admin"). The public router (src/basketball_api/routes/public.py) currently only serves /public/teams, /public/coaches, and /public/interest. No open Forgejo issue or board item exists for a public schedule endpoint.
  • [x] Board item #629 (Schedule data model + migration + seed) — done, merged (PR #234)
  • [x] Board item #630 (Schedule API endpoints CRUD) — done, merged (PR #236, admin-only)
  • [x] Board item #648 (Admin nav: add Schedule link) — sibling work, backlog, no blocking dependency
  • [x] Board item #627 ([DECOMPOSED] Schedule data model + API #230) — parent, decomposed
The issue itself correctly identifies this blocker in its Context and Constraints sections ("If no public endpoint exists, this ticket is BLOCKED — create a basketball-api issue first") but does not create the prerequisite ticket.

Acceptance Criteria

5 acceptance criteria — all testable via visual verification and npm run build. The progressive enhancement AC (fallback to hardcoded data if API unavailable) is well-scoped and matches a real production concern. However, all criteria assume a public API endpoint exists. Cannot be verified until the basketball-api blocker is resolved.

Blast Radius

Low. The public pages (teams, coaches) already follow the publicFetch() pattern via src/lib/public-api.js. Adding schedule follows the identical pattern. No other consumers of the hardcoded schedule data were found. The Kings/Queens programStore toggle is shared across public pages and will continue working. Rollback is straightforward — revert the single file.

Decomposition Assessment

1 primary file target, 5 AC, single repo. Within the five-minute rule once the blocker is resolved. No decomposition needed for the westside-landing work itself.
However, the overall work requires 2 tickets across 2 repos:
  • basketball-api: Add GET /public/schedule endpoint (new ticket needed)
  • westside-landing: Refactor public schedule page to consume API (this ticket)
These are sequential — ticket 1 must merge before ticket 2 can execute.

Recommendation

  • [SCOPE] Create a prerequisite basketball-api issue for GET /public/schedule endpoint, following the pattern of existing /public/teams and /public/coaches endpoints in src/basketball_api/routes/public.py. Add it to board-westside-basketball with labels story:WS-S13,arch:basketball-api,type:feature.
  • [BODY] Fix file reference in File Targets section: replace "src/lib/api.js — may need a public fetch variant without auth" with "src/lib/public-api.js — use existing publicFetch() function (already used by teams/coaches pages, no new code needed in this file)."
  • [LABEL] Add status:blocked label to board item #649 until the public schedule endpoint exists on basketball-api.