Public coaches endpoint — GET /public/coaches #177
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#177
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?
Type
Feature
Lineage
Enables dynamic staff page on westside-app public site.
Repo
forgejo_admin/basketball-apiUser Story
As a visitor on the public website, I want to see coach bios and photos so that I can learn about the coaching staff without needing to log in.
story:WS-S26
Context
Existing coach endpoints (
GET /coaches/me,GET /coaches/{id}) require auth. The public site needs an unauthenticated endpoint returning only publicly-safe coach data.The westside-playground staff.html
@svelte-notesdefine the data contract:minio-api.tail5b443a.ts.net/assets/westside/coaches/)Security — Field Allowlist
CRITICAL: Do NOT reuse existing admin/auth response schemas. Create dedicated public schemas.
Public response MUST include ONLY:
Note on removed fields:
bio,photo_url, andslugwere originally listed but removed during scope review:bioandphoto_urldo not exist as columns on the Coach model — they would require a schema migration to addslugis included above but is runtime-derived, not a database columnMUST NOT expose: email, phone, keycloak_id, tenant_id, stripe data, onboarding status.
File Targets
src/basketball_api/routes/public.py(created by teams ticket)Acceptance Criteria
GET /public/coachesreturns coaches list, no auth requiredPublicCoachesResponse— allowlisted fields onlyrolereturns raw enum value stringbioorphoto_urlfields in response (columns don't exist on model)Test Expectations
Constraints
name.lower().replace(" ", "-")Checklist
Related
@svelte-notes— data contractpublic.pyrouter)convention-sveltekit-spa— frontend consuming this endpointScope Addition
Add
is_publicboolean column tocoachestable (defaulttrue— coaches are public by default, opposite of players). TheGET /public/coachesendpoint should only return coaches whereis_public = true.Migration needed:
ALTER TABLE coaches ADD COLUMN is_public BOOLEAN NOT NULL DEFAULT true;Scope Review: NEEDS_REFINEMENT
Review note:
review-430-2026-03-26Three issues found that prevent this ticket from being READY.
depends:bb-176— issue #176 (public teams endpoint) createspublic.pywhich this ticket modifies, but that dependency is undocumented.PublicCoachResponseschema referencesbio,photo_url, andslug— none of which exist on the Coach model.bioandphoto_urlrequire an Alembic migration or must be removed from the schema.slugis computed at runtime (acceptable, but should be documented as such).Review Response
Fixing all three findings:
1. Dependency label
Added
depends:bb-176to board item #430.2. Model field gaps (CRITICAL)
The
Coachmodel is missingbio,photo_url, andis_public. This ticket's scope now includes an Alembic migration:After migration, coach bios need to be seeded from the playground staff.html content (Marcus, James, KJ, Ken, Abbie, Manny). This is a one-time data seed, not an ongoing process.
3. slug is computed, not stored
Confirmed —
slugis derived at query time:name.lower().replace(" ", "-"). Not a column. Acceptance criterion updated: "photo_url points to MinIO path" is testable once the column exists and is populated via seed.Scope Review: READY
Review note:
review-430-2026-03-26(updated)Re-review: all three previous findings resolved. Ticket is clear for execution.
in_progress.bio,photo_url,is_publicexplicitly scoped in comments. No migration exists yet; prior art in002_add_player_profile_fields.py.Optional nit (not blocking): Consider adding "Only coaches with
is_public = trueare returned" as an explicit acceptance criterion — currently only in comment #8073.forgejo_admin referenced this issue2026-03-27 03:43:33 +00:00
Scope Reassessment — Deprioritized
Coach bios, photos, and public-facing data don't exist in the coaches table. The table is a contractor/onboarding schema (Stripe Connect, tax IDs, invite tokens). Building an API endpoint + migration + seed script to serve 6 coach cards that change once a season is overengineering.
Decision: Staff page becomes a static page in the SvelteKit port (same as index, about, sponsors). Coach bios stay as hardcoded HTML from the playground. No API endpoint needed.
This ticket moves back to todo and is deprioritized. If/when we build an admin UI for managing coach profiles, this becomes relevant. Not now.
westside-app#98 updated: staff page is static, removes dependency on this ticket.
Scope Review: NEEDS_REFINEMENT
Review note:
review-430-2026-03-27Schema references model columns that don't exist on the Coach model.
bio— no column on Coach model (models.py lines 257-283)photo_url— no column on Coach model (exists only on Player model, line 182)slug— no column on Coach model (Constraints section says derive at runtime, but schema lists it as a stored field — ambiguous)Required before READY:
bio+photo_url: Either (a) create a prerequisite migration ticket to add these columns, or (b) drop them from PublicCoachResponse for nowslug: If runtime-derived per Constraints section, update schema description to reflect this (no migration needed). If stored, migration needed.roletype: CoachRole enum values arehead_coach,assistant,director— should public endpoint return raw enum value or display-friendly string?Issue body updated per scope review corrections.