Promote playground dashboard to westside-app (Phases 1-3) #5

Closed
opened 2026-03-13 20:10:09 +00:00 by forgejo_admin · 0 comments

Lineage

plan-2026-03-08-tryout-prep → Phase 6a (SvelteKit scaffold) → Promotion from playground

Repo

forgejo_admin/westside-app

User Story

As a coach or admin
I want the proven tryout-day dashboard running as its own SSR app
So that it loads instantly with real data, persists check-ins, and doesn't depend on a shared nginx playground

Context

The SvelteKit dashboard was prototyped in ~/html-playground/3-westside-dashboard/ and used live at tryouts on 2026-03-13. It works — 45 players, admin triage (ready/needs-waiver/needs-everything), coach card view, search, check-in, assign-number.

westside-app exists on Forgejo with a basic scaffold (3 commits): Dockerfile, k8s manifests, CI pipeline. But it connects to Postgres directly via pg and has placeholder pages. The architecture decision: use basketball-api as the data layer — the frontend calls API endpoints, not Postgres directly.

Key decisions:

  • Keep adapter-node (SSR) — the app has its own container, not shared nginx
  • Use +page.server.js to fetch from basketball-api server-side (no loading spinner)
  • Mutations (check-in, assign-number) via client-side fetch to SvelteKit API proxy routes or form actions
  • BASKETBALL_API_URL env var for internal service URL
  • Tenant hardcoded to westside-kings-queens (single-tenant app)

File Targets

Files to create:

  • src/lib/server/api.js — basketball-api client helper (fetch roster, check-in, assign-number)
  • src/routes/admin/+page.server.js — SSR load + form actions for admin mutations
  • src/routes/coach/+page.server.js — SSR load for coach view

Files to rewrite:

  • src/routes/+page.server.js — fetch stats from basketball-api instead of direct Postgres
  • src/routes/+page.svelte — landing page with stats + nav links to /admin and /coach
  • src/routes/admin/+page.svelte — port admin triage view from playground (ready/needs-waiver/needs-everything, check-in toggle, assign-number, walk-up, copy reg link)
  • src/routes/coach/+page.svelte — port coach card view from playground (player cards, search, position filter, checked-in/not sections)
  • src/routes/+layout.svelte — update global styles to match playground dark theme
  • package.json — remove pg dependency

Files to delete:

  • src/lib/server/db.js — remove direct Postgres connection

Files NOT to touch:

  • Dockerfile — works as-is with adapter-node
  • k8s/ — deployment changes are Phase 4 (separate issue)
  • .woodpecker.yml — CI changes not needed for code promotion

Reference design: ~/html-playground/3-westside-dashboard/src/routes/+page.svelte (698 lines, both admin + coach views)

Acceptance Criteria

  • Landing page (/) shows player count stats from API (SSR, no spinner)
  • /admin shows triage view with ready/needs-waiver/needs-everything sections
  • Check-in button toggles checked_in status and persists via basketball-api
  • Assign-number button assigns next tryout number via basketball-api
  • /coach shows player cards with photos, search, position filter
  • Coach view separates checked-in vs not-checked-in players
  • No direct Postgres dependency (pg removed from package.json)
  • BASKETBALL_API_URL env var configures API base URL (default: http://localhost:8000)
  • graduating_class field displays correctly (Phase 3)
  • Dark theme matches playground design (black bg, red accents, mobile-first)

Test Expectations

  • Manual: npm run dev with BASKETBALL_API_URL pointing at running basketball-api
  • Manual: verify /, /admin, /coach all render with real data
  • Manual: check-in toggle persists (refresh confirms)
  • No automated tests for this phase — frontend E2E deferred

Constraints

  • Use Svelte 5 runes ($state, $derived, $props) — match playground patterns
  • basketball-api endpoints are public-but-unlisted (no auth needed from the frontend)
  • API contract: GET /api/roster/{tenant}, POST /api/roster/{tenant}/check-in/{id}, POST /api/roster/{tenant}/assign-number/{id}
  • RosterPlayer fields: id, name, tryout_number, division, date_of_birth, age, current_school, position, height, photo_url, checked_in, graduating_class, parent_name, parent_email, parent_phone, registration_token, waiver_signed, payment_status

Checklist

  • PR opened
  • No unrelated changes
  • pg dependency removed
  • All three routes render with API data
  • westside-basketball — project this affects
  • plan-2026-03-08-tryout-prep — parent plan
### Lineage `plan-2026-03-08-tryout-prep` → Phase 6a (SvelteKit scaffold) → Promotion from playground ### Repo `forgejo_admin/westside-app` ### User Story As a coach or admin I want the proven tryout-day dashboard running as its own SSR app So that it loads instantly with real data, persists check-ins, and doesn't depend on a shared nginx playground ### Context The SvelteKit dashboard was prototyped in `~/html-playground/3-westside-dashboard/` and used live at tryouts on 2026-03-13. It works — 45 players, admin triage (ready/needs-waiver/needs-everything), coach card view, search, check-in, assign-number. `westside-app` exists on Forgejo with a basic scaffold (3 commits): Dockerfile, k8s manifests, CI pipeline. But it connects to Postgres directly via `pg` and has placeholder pages. The architecture decision: **use basketball-api as the data layer** — the frontend calls API endpoints, not Postgres directly. Key decisions: - Keep `adapter-node` (SSR) — the app has its own container, not shared nginx - Use `+page.server.js` to fetch from basketball-api server-side (no loading spinner) - Mutations (check-in, assign-number) via client-side fetch to SvelteKit API proxy routes or form actions - `BASKETBALL_API_URL` env var for internal service URL - Tenant hardcoded to `westside-kings-queens` (single-tenant app) ### File Targets Files to create: - `src/lib/server/api.js` — basketball-api client helper (fetch roster, check-in, assign-number) - `src/routes/admin/+page.server.js` — SSR load + form actions for admin mutations - `src/routes/coach/+page.server.js` — SSR load for coach view Files to rewrite: - `src/routes/+page.server.js` — fetch stats from basketball-api instead of direct Postgres - `src/routes/+page.svelte` — landing page with stats + nav links to /admin and /coach - `src/routes/admin/+page.svelte` — port admin triage view from playground (ready/needs-waiver/needs-everything, check-in toggle, assign-number, walk-up, copy reg link) - `src/routes/coach/+page.svelte` — port coach card view from playground (player cards, search, position filter, checked-in/not sections) - `src/routes/+layout.svelte` — update global styles to match playground dark theme - `package.json` — remove `pg` dependency Files to delete: - `src/lib/server/db.js` — remove direct Postgres connection Files NOT to touch: - `Dockerfile` — works as-is with adapter-node - `k8s/` — deployment changes are Phase 4 (separate issue) - `.woodpecker.yml` — CI changes not needed for code promotion Reference design: `~/html-playground/3-westside-dashboard/src/routes/+page.svelte` (698 lines, both admin + coach views) ### Acceptance Criteria - [ ] Landing page (`/`) shows player count stats from API (SSR, no spinner) - [ ] `/admin` shows triage view with ready/needs-waiver/needs-everything sections - [ ] Check-in button toggles checked_in status and persists via basketball-api - [ ] Assign-number button assigns next tryout number via basketball-api - [ ] `/coach` shows player cards with photos, search, position filter - [ ] Coach view separates checked-in vs not-checked-in players - [ ] No direct Postgres dependency (`pg` removed from package.json) - [ ] `BASKETBALL_API_URL` env var configures API base URL (default: `http://localhost:8000`) - [ ] `graduating_class` field displays correctly (Phase 3) - [ ] Dark theme matches playground design (black bg, red accents, mobile-first) ### Test Expectations - [ ] Manual: `npm run dev` with `BASKETBALL_API_URL` pointing at running basketball-api - [ ] Manual: verify `/`, `/admin`, `/coach` all render with real data - [ ] Manual: check-in toggle persists (refresh confirms) - No automated tests for this phase — frontend E2E deferred ### Constraints - Use Svelte 5 runes (`$state`, `$derived`, `$props`) — match playground patterns - basketball-api endpoints are public-but-unlisted (no auth needed from the frontend) - API contract: `GET /api/roster/{tenant}`, `POST /api/roster/{tenant}/check-in/{id}`, `POST /api/roster/{tenant}/assign-number/{id}` - RosterPlayer fields: id, name, tryout_number, division, date_of_birth, age, current_school, position, height, photo_url, checked_in, graduating_class, parent_name, parent_email, parent_phone, registration_token, waiver_signed, payment_status ### Checklist - [ ] PR opened - [ ] No unrelated changes - [ ] `pg` dependency removed - [ ] All three routes render with API data ### Related - `westside-basketball` — project this affects - `plan-2026-03-08-tryout-prep` — parent plan
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
forgejo_admin/westside-landing#5
No description provided.