Board: #109 — Split westside-app into westside-landing + westside-app

board-109-westside-landing-split Board

active

Parent

Forgejo issue: forgejo_admin/westside-app#109 (board item #450 on board-westside-basketball)
westside-app currently bundles the public landing site AND the authenticated member area in one repo. This ticket splits them into two separate repos so that the landing site can be static/SEO-friendly with zero auth dependency, and the app can remain a keycloak-js SPA focused on authenticated workflows. The split also retires the legacy GitHub Pages site (ldraney.github.io/west-side-basketball).

User Stories

Scoped subset from Project: Westside Kings & Queens — Prospect role stories.
Role Key Story Success Metric
Prospect <code>story:WS-S26</code> As a prospect, I want to browse the landing page so that I learn about the program without creating an account Landing loads at public URL, zero JS auth libraries in bundle
Prospect <code>story:WS-S27</code> As a prospect, I want to see coach profiles and staff bios so that I trust the program's leadership /staff route renders coach photos + bios from basketball-api public endpoint
Prospect <code>story:WS-S28</code> As a prospect, I want to view practice schedules and tryout dates so that I know when to show up /schedule and /tryouts routes render current season data
Prospect <code>story:WS-S29</code> As a prospect, I want a clear registration CTA so that I can sign up my child in one click CTA button links to westside-app registration flow with UTM tracking

Architecture

References the parent project's Deployment Architecture. This work touches three arch components and introduces westside-landing as a new deployed service.
Relevant arch: labels for all sub-tickets on this board:
  • arch:landing-site — New SvelteKit adapter-static repo. Replaces both the prototype at playground.tail5b443a.ts.net/svelte/westside/ and the legacy GitHub Pages site. Public, SEO-friendly, zero auth.
  • arch:westside-app — Existing SPA. Routes extracted to landing-site get removed. Remains keycloak-js + PKCE, adapter-static, Capacitor-ready.
  • arch:kustomize — New kustomize overlay in pal-e-deployments for westside-landing. ArgoCD Application + Tailscale funnel for the new public hostname.

Acceptance Criteria

How we know the parent ticket (#109) is done when all sub-tickets complete:
  • westside-landing is live — Public URL resolves, serves static HTML, Lighthouse SEO score >90, zero auth JS in bundle.
  • All public routes migrated/, /about, /staff, /schedule, /sponsors, /tryouts, /teams all render on westside-landing with data from basketball-api public endpoints.
  • westside-app cleaned — Extracted routes removed. Only authenticated routes remain (/dashboard, /admin, /coach, /profile, etc.). No dead imports or orphan components.
  • CI green on both repos — Woodpecker pipelines build and deploy both services independently.
  • Cross-linking works — Landing CTA links to westside-app registration. App "back to site" links to landing. No broken navigation between the two.
  • Legacy site retired — GitHub Pages (ldraney.github.io/west-side-basketball) redirects or is decommissioned.

Kanban

This note IS the board. Sub-tickets are Forgejo issues on forgejo_admin/westside-app (or the new westside-landing repo once created). Each sub-ticket links back to this board note.
Columns follow sop-board-workflow: backlog → todo → next_up → in_progress → done

Sub-ticket 1: Create westside-landing repo

Field Value
Summary Scaffold <code>forgejo_admin/westside-landing</code> — SvelteKit adapter-static, Woodpecker CI, Harbor image push
Stories <code>story:WS-S26</code>
Arch <code>arch:landing-site</code>
Column backlog
Scope Create repo on Forgejo. Init SvelteKit with adapter-static. Add <code>.woodpecker.yaml</code> (build + push to Harbor). Verify CI builds green. No routes yet — just scaffold.
AC Repo exists, CI green, Docker image pushed to Harbor on main merge.

Sub-ticket 2: Extract landing pages from westside-app

Field Value
Summary Move public routes (<code>/</code>, <code>/about</code>, <code>/staff</code>, <code>/schedule</code>, <code>/sponsors</code>, <code>/tryouts</code>, <code>/teams</code>) to westside-landing
Stories <code>story:WS-S26</code>, <code>story:WS-S27</code>, <code>story:WS-S28</code>
Arch <code>arch:landing-site</code>
Column backlog
Depends on Sub-ticket 1
Scope Copy Svelte route files + components + CSS from westside-app to westside-landing. Adapt imports, remove any auth dependencies. Verify all 7 routes render with static data or basketball-api public endpoints.
AC All 7 routes render in dev. No keycloak-js or auth imports in the landing codebase. CI green.

Sub-ticket 3: Wire deployment (kustomize + ArgoCD + Tailscale funnel)

Field Value
Summary Add kustomize overlay for westside-landing in pal-e-deployments, create ArgoCD Application, configure Tailscale funnel for public hostname
Stories <code>story:WS-S26</code>
Arch <code>arch:kustomize</code>, <code>arch:landing-site</code>
Column backlog
Depends on Sub-ticket 1
Scope Create <code>pal-e-deployments/westside-landing/</code> overlay (Deployment, Service, kustomization.yaml). Add ArgoCD Application manifest. Configure Tailscale funnel for public hostname. Verify pod runs and URL resolves.
AC ArgoCD syncs the app. Pod is healthy. Public URL serves the landing site over HTTPS via Tailscale funnel.

Sub-ticket 4: Wire public API (connect to basketball-api public endpoints)

Field Value
Summary Connect westside-landing routes to basketball-api public endpoints for staff, schedules, teams, and tryout data
Stories <code>story:WS-S27</code>, <code>story:WS-S28</code>
Arch <code>arch:landing-site</code>
Column backlog
Depends on Sub-ticket 2
Scope Replace any static/mocked data with fetch calls to basketball-api public endpoints. Wire /staff, /schedule, /tryouts, /teams to live data. Handle loading states and errors gracefully.
AC All data-driven routes render live data from basketball-api. No auth tokens required. Graceful fallback on API error.

Sub-ticket 5: Clean westside-app (remove extracted routes)

Field Value
Summary Remove migrated public routes from westside-app, keep only authenticated routes, clean dead imports
Stories <code>story:WS-S29</code>
Arch <code>arch:westside-app</code>
Column backlog
Depends on Sub-tickets 2, 3, 4 (landing site is live and verified)
Scope Delete the 7 extracted route directories from westside-app. Remove orphan components and CSS only used by those routes. Update nav to link to landing site for public pages. Add registration CTA redirect from landing. Verify all remaining authenticated routes still work.
AC No public route files remain in westside-app. No dead imports. CI green. Authenticated routes unaffected. CTA on landing links to westside-app registration.