Project: Westside Kings & Queens

project-westside-basketball Project Page

active project-page

Vision

Westside Kings & Queens is a youth AAU basketball program in West Valley, Utah. One production app with three concerns: public landing page (marketing), tryout registration (acquisition funnel → account creation), and member area (player/parent, coach, admin dashboards). Built on the Pal-E platform.

Plan

Sprint Plan (continuous kanban, no internal deps per sprint):
Sprint Theme Pts Status
3 Foundation — email, CI, DNS proxy 15 DONE
4 Auth — Keycloak OIDC, pipeline fixes 9 DONE
5 Admin UI — player list, Harbor, TLS, CI 14 DONE
6 Foundation + IaC — detail page, webhook, Apple model, iOS repo, API key, Keycloak self-reg 22 DONE
7 UI + Fastlane — badges, detail subscription UI, status page, Fastlane IaC 4 DONE
8 Purchase + Routing — StoreKit purchase, role-based routing 5 todo
9 Pipeline + Native Auth — SSH build pipeline, OIDC-in-Turbo-Native spike 4 todo
Plan Status Summary
<a href="/notes/arch-app-store">App Store Billing Architecture</a> active iOS-only subscriptions (Apple recurring, Stripe one-off). Enum: subscribed/expired/billing_retry/grace_period/revoked/none. Sprints 6-9.
<a href="/notes/plan-wkq">Plan: WKQ (legacy phases)</a> superseded 19 phases. Phases 1-9 completed. Replaced by sprint-based kanban.
<a href="/notes/plan-2026-02-25-stripe-connect-payouts">Stripe Connect Payouts</a> completed Research done. Decisions carried forward.
<a href="/notes/plan-2026-03-07-westside-app">Westside App</a> completed (absorbed) User stories absorbed into plan-wkq.

Board

board-westside-basketball — 21 items. 9 phases done (57 pts), 1 in progress (playground), 1 next up (girls tryout with blockers), 7 backlog (47 pts), 2 Forgejo issues.

Sub-project boards:
board-westside-sheet-sync — DB → Google Sheet append-only jersey sync. 5 backlog tickets on basketball-api (story:sheet-sync). Separate project westside-sheet-sync.

Status

Quick Links
Active Plan | Tryout Day Ops Guide | User Stories
Rails App (active): westside-ror.tail5b443a.ts.net
Playground: playground.tail5b443a.ts.net/westside/
SvelteKit App: westsidekingsandqueens.tail5b443a.ts.net — being replaced by westside-basketball
API: basketball-api.tail5b443a.ts.net — DOWN (CrashLoopBackOff, being replaced)
Keycloak: keycloak.tail5b443a.ts.net
Public domain: westsidekingsandqueens.com (GoDaddy → Tailscale redirect)


  • westside-basketball (Active): Rails 8.1 monolith, replaces basketball-api + westside-app. Rails 8.1 monolith with Hotwire + Semantic CSS + Postgres. Homepage live at westside-ror.tail5b443a.ts.net. Schema dumped (23 tables, all enums/FKs). 5 models wired. Sprint in progress: #1 (DB + remaining models), #8 (static public pages), #9 (dynamic public pages).
  • basketball-api (DOWN): Three pods failing — CrashLoopBackOff (Alembic migration mismatch), ImagePullBackOff (Harbor 401), Init stuck (missing hostPath). Not being revived — westside-basketball replaces it.
  • westside-app (ARCHIVED): SvelteKit SPA being replaced by westside-basketball. Landing pages are the priority; dashboards will be rebuilt in Rails with proper UX.
  • Auth: Keycloak OIDC still deployed and will be reused. 50+ accounts live. Roles: admin, coach, player. westside-basketball will integrate via Issue #7 after public pages ship.
  • Payments: Stripe checkout for tryout ($30) + jersey ordering ($90/$130/opt-out). Monthly dues $200/mo standard. Will be re-integrated in Rails (Issue #2).
  • Contracts: westside-contracts SvelteKit app still deployed and independent (adapter-node, direct Postgres). Not affected by migration.
  • Email: MJML branded email service (westside-emails repo). Gmail OAuth sending. Will be re-integrated in Rails.
  • CSS: Semantic CSS design system — no Tailwind. Conventions in ~/ror-css-guide. SvelteKit and Rails share identical design tokens (same color palette, spacing, typography).

Milestones

Architecture

  • Domain Model — entities and relationships (still accurate, shared Postgres schema)
  • Data Flowstale — describes FastAPI+SvelteKit flow. Rails uses direct ActiveRecord queries instead of API calls.
  • Deploymentpartially stale — westside-basketball deployed via k8s dev overlay. basketball-api deployment is down.
  • Auth Architecture — Keycloak OIDC still valid. Rails integration (Issue #7) will use server-side OIDC instead of keycloak-js + PKCE.
  • New architecture (westside-basketball): Rails 8.1 MVC monolith. Direct Postgres access via ActiveRecord replaces the FastAPI API layer. Hotwire (Turbo + Stimulus) replaces SvelteKit SPA. Semantic CSS design system (no Tailwind). Multi-tenant via tenant_id scoping. CSS conventions: ~/ror-css-guide.

Repos

Repo Platform Subproject Role Status
<code>ldraney/westside-basketball</code> Forgejo westside-basketball Rails 8.1 monolith — replaces basketball-api + westside-app. Hotwire + Semantic CSS + Postgres. MVC direct DB access. <strong>ACTIVE</strong> — primary app, deployed, public homepage live
<code>forgejo_admin/basketball-api</code> Forgejo shared backend (legacy) FastAPI backend — auth, registration, Stripe, teams, profiles, email sending <strong>DOWN</strong> — CrashLoopBackOff + ImagePullBackOff. Being replaced by westside-basketball.
<code>forgejo_admin/westside-app</code> Forgejo westside-app (legacy) SvelteKit SPA — authenticated member area (admin, coach, parent dashboards). adapter-static + keycloak-js + PKCE. <strong>ARCHIVED</strong> — replaced by westside-basketball
<code>forgejo_admin/westside-contracts</code> Forgejo westside-contracts Contract e-sign SvelteKit app (adapter-node, direct Postgres) deployed, 12 tests
<code>forgejo_admin/westside-emails</code> Forgejo shared MJML email templates — branded emails compiled to HTML new, CI configured
<code>forgejo_admin/westside-playground</code> Forgejo shared HTML/CSS prototypes — design iteration active
<code>ldraney/west-side-basketball</code> GitHub legacy Original landing page — deprecated retired

User Stories

Role Tier Actor(s) Scope
Superadmin Platform Lucas All projects, infra, deployments, observability
Admin Organization Marcus Teams, players, payments, communications, coaches
Coach Team Assigned coaches Roster, playbooks, attendance, parent contact
Parent Account Registered parents Registration, payments, profiles, email actions
Player Member Registered players Profile (read), team, schedule
Prospect Public Unregistered families Public site, program info, staff bios, schedules, contact

Superadmin (Lucas)

  • story:WS-S1 As superadmin, I want to deploy platform changes via IaC so that infrastructure is reproducible and auditable
  • story:WS-S2 As superadmin, I want to monitor service health via Grafana so that I catch issues before users do
  • story:WS-S3 As superadmin, I want to manage Keycloak realms so that each project has isolated auth
  • story:WS-S4 As superadmin, I want to serve static assets via public CDN so that emails and apps can reference images without auth
  • story:WS-S5 As superadmin, I want basketball-api's database on the CNPG shared cluster so that player data has daily backups, WAL archiving, and automated restore verification

Admin (Marcus)

  • story:WS-S5 As an admin, I want to view registration stats on a dashboard so that I know signup progress at a glance
  • story:WS-S6 As an admin, I want to assign players to teams via draft board so that placement is transparent and trackable
  • story:WS-S7 As an admin, I want to send branded email announcements so that parent comms are professional and consistent
  • story:WS-S9 As an admin, I want to track payment status per player so that I know who owes what
  • story:WS-S10 As an admin, I want to manage coaches and assign them to teams so that teams have leadership
  • story:WS-S11 As an admin, I want to create Stripe checkout sessions for one-off purchases (jerseys, tournament fees) so that non-subscription payments are automated
  • story:WS-S12 As an admin, I want to manage user accounts (reset passwords, view profiles) so that I can support parents directly
  • story:WS-S13 As an admin, I want to view and manage the program schedule (practices, tournaments, games) so that I have a single source of truth for all planned activities
  • story:WS-S14 As an admin, I want an AI agent to research potential sponsors and draft personalized outreach emails so that I can send targeted pitches without hours of manual research
  • story:WS-S15 As an admin, I want Westside to be a registered 501(c)(3) nonprofit so that sponsors get tax deductions, fundraising is tax-free, and we qualify for facility access and grants
  • story:WS-S23 As an admin, I want to configure custom contract terms per player (different fee, tournaments, practice schedule) so that custom deals render correctly without code changes
  • story:WS-S29 As an admin, I want to manage sponsor relationships — track their tier, what they've paid, their logo, and whether they show on the website — so that I always know what we owe each sponsor and what they've committed
  • story:WS-S30 As an admin, I want to see which parents have joined their team's GroupMe so that I can follow up with those who haven't and ensure all families are connected
  • story:WS-S31 As an admin, I want a long-standing public jersey order link I can share with any player (known or new) so that recipients self-identify and submit their own sizes, number preferences, and tier without me collecting details manually
  • story:WS-S32 As an admin, I want a generic email blast system with pluggable audience queries so that new email types ship as config, not code changes
  • story:WS-S33 As an admin, I want to bill players for tournament entry fees at team-specific rates via Stripe so that event costs are collected before registration deadlines
  • story:WS-S35 As an admin, I want to set and manage subscription pricing on a player's detail page so that I control what each family pays for their program tier
  • story:WS-S36 As an admin, I want to see Apple subscription lifecycle states (subscribed, grace period, billing retry, expired) per player so that I know who's current, who's in grace, and who's delinquent

Coach

  • story:WS-S13 As a coach, I want to view my team roster with player photos so that I know my players on sight
  • story:WS-S14 As a coach, I want to upload playbooks so that players can study game plans before practice
  • story:WS-S15 As a coach, I want to see parent contact info so that I can communicate directly about my team
  • story:WS-S16 As a coach, I want to track attendance so that I know who shows up consistently
  • story:WS-S27 As a coach, I want to see my team's practice schedule and upcoming events so I know when and where my teams practice and play

Parent

  • story:WS-S17 As a parent, I want to register my child online (info + photo + payment + waiver) so that signup is one seamless flow
  • story:WS-S18 As a parent, I want to receive a branded email with jersey ordering link so that I can order without bringing cash
  • story:WS-S19 As a parent, I want to see my child's team assignment and coach so that I know the season plan
  • story:WS-S20 As a parent, I want to sign contracts digitally so that paperwork is handled online
  • story:WS-S21 As a parent, I want to manage my login credentials so that I control my own access
  • story:WS-S22 As a parent, I want to receive clear email communications with action links so that I never miss a deadline
  • story:WS-S28 As a parent, I want to see my child's team practice schedule so I know when and where to take them
  • story:WS-S34 As a parent, I want to subscribe to my child's team program through the iOS app so that Apple handles monthly billing and automatically enforces the delinquency gate if I fall behind on payments
  • story:WS-S38 As a parent, I want to create an account, log in through the iOS app, and be routed to my subscription status page so I can manage payments and see where I stand

Player

  • story:WS-S23 As a player, I want to see my team and practice schedule so that I know when and where to show up
  • story:WS-S24 As a player, I want to view my profile with photo and team info so that I can share it
  • story:WS-S25 As a player, I want to access playbooks my coach uploaded so that I can study before games
  • story:WS-S37 As a player or parent, I want to log in and see my subscription status and payment history so that I know where I stand and can take action if needed

Prospect

Key People

  • story:WS-S26 As a prospective parent who received a link from Marcus, I want to see a professional landing page with current program details (practice schedule, fees, divisions) so that I take the program seriously and don't have to text Marcus back with basic questions
  • story:WS-S27 As a prospective parent, I want to see coaching staff with bios and credentials so that I trust the people who will coach my child
  • story:WS-S28 As a prospective parent, I want to see team structure, tournament circuits, and travel schedule so that I understand the competitive level and time/travel commitment
  • story:WS-S29 As a prospective parent, I want a clear way to contact the program (email, phone) so that I can ask questions or sign up without hunting for info
  • story:WS-S30 As a prospect who expressed interest, I want to receive a welcome email introducing the team, schedule, and membership options so that I feel welcomed and know how to join
  • story:WS-S31 As a prospect who can't attend regular practices, I want a tournament-only membership at a reduced monthly fee so that I can still participate competitively
  • story:WS-S26 As a prospect, I want to browse team rosters on the public site so that I can evaluate the program before committing
  • story:WS-S27 As a prospect, I want the landing page to guide me toward registration so that I can take action without hunting for a signup link
  • Lucas Draney — Founder, platform architect
  • Marcus Draney — Head Coach, program director, operations
  • Coach West — Recruiting partnership
  • 5 coaches: Marcus, James Taylor, KJ Ng, Ken Seka, Abbie Sa (see Staff & Coaches)

Program Details

  • Org: Westside Kings & Queens (youth AAU basketball)
  • Location: West Valley, Utah
  • Divisions: Boys, Girls — 15U, 16U, 17U
  • Tryout fee: $30 via Stripe
  • Monthly dues: $200/mo standard, $160/mo Cyprus girls, $180/mo LCA (Phase 14)
  • Split payment: $100 beginning + $100 end of month option (Phase 14)

Sponsors & Partners

See Westside Sponsors & Partners for full tracking. 1 pending conversation (plant-powered pain relief spray, 2026-03-24).