Multi-tenant AAU basketball program management API
Find a file
forgejo_admin 197a89b717
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
fix: add retry loop to CI wget for update-kustomize-tag (#216)
2026-03-28 20:07:45 +00:00
alembic docs: add downstream consumer check to migration workflow (#199) 2026-03-28 11:48:05 +00:00
docs doc: auth architecture with management paths and key decisions (#200) 2026-03-28 11:55:22 +00:00
k8s fix: use full SHA for image tag (Harbor requires full SHA) 2026-03-24 02:34:26 -06:00
scripts feat: standardize ruff config to platform standard (#214) 2026-03-28 19:10:23 +00:00
src/basketball_api feat: standardize ruff config to platform standard (#214) 2026-03-28 19:10:23 +00:00
tests feat: standardize ruff config to platform standard (#214) 2026-03-28 19:10:23 +00:00
.gitignore fix: coach Stripe retry + backfill scripts (#40) 2026-03-10 05:28:32 +00:00
.pre-commit-config.yaml feat: standardize ruff config to platform standard (#214) 2026-03-28 19:10:23 +00:00
.woodpecker.yaml fix: add retry loop to CI wget for update-kustomize-tag (#216) 2026-03-28 20:07:45 +00:00
alembic.ini Add pal-e-auth integration to gate roster endpoints (#5) 2026-02-24 04:55:03 +00:00
CLAUDE.md Add pal-e-auth integration to gate roster endpoints (#5) 2026-02-24 04:55:03 +00:00
Dockerfile fix: add Forgejo PyPI index URL for groupme-sdk dependency 2026-03-24 02:19:34 -06:00
pyproject.toml feat: standardize ruff config to platform standard (#214) 2026-03-28 19:10:23 +00:00
README.md Replace pal-e-auth with Keycloak OIDC JWT validation (#78) 2026-03-14 18:55:04 +00:00

basketball-api

Multi-tenant AAU basketball program management API. Handles registration (via Stripe webhooks), roster management, coach onboarding, and automated communications (via Gmail) for AAU basketball programs.

First Client

Westside Kings & Queens (Marcus Draney) — AAU basketball in Farmington, NM.

Live site: https://basketball-api.tail5b443a.ts.net

What Link
Coach signup (share with ALL coaches) https://basketball-api.tail5b443a.ts.net/coach/signup
Parent registration (walk-up / QR) https://basketball-api.tail5b443a.ts.net/register
Stripe test coupon (100% off, 5 uses) TESTFREE
Tryout payment link ($30) https://buy.stripe.com/aFa8wRbky5KwgL0bI60VO01

Endpoints

Method Path Auth Description
GET /healthz None Health check
GET /register None Parent registration (email gate → form → waiver)
GET /register?token=xxx None Pre-filled registration from email link
POST /webhooks/stripe Stripe sig Stripe webhook receiver
GET /coach/signup None Coach contractor agreement + Stripe Connect
GET /coach/onboard?token=xxx None Coach onboarding (token-based, legacy)
GET /tenants/{slug}/roster None Roster JSON API
GET /tenants/{slug}/roster/view None Roster HTML page
POST /admin/generate-tokens Admin JWT Generate registration tokens for paid parents
POST /admin/invite-coach Admin JWT Create individual coach invite

Architecture

Stripe Payment Link → Stripe webhook → basketball-api → Postgres
                                            ↓
                                    gmail-sdk → draneylucas@gmail.com (POC)
                                               westsidebasketball@gmail.com (production)

Deployment

Deployed to pal-e k3s cluster via Forgejo → Woodpecker CI → Harbor → ArgoCD.

Setup

Prerequisites

  • basketball-api-secrets K8s secret with: postgres-password, stripe-webhook-secret, stripe-api-key
  • BASKETBALL_KEYCLOAK_REALM_URL env var pointing to the Keycloak realm (e.g. https://keycloak.tail5b443a.ts.net/realms/pal-e)
  • Gmail OAuth token for tenant (via gmail-sdk authorize flow)
  • Tenant seeded in DB: INSERT INTO tenants (slug, name, contact_email, gmail_account) VALUES ('westside-kings-queens', 'Westside Kings & Queens', 'westsidebasketball@gmail.com', 'draneylucas')

Local Development

pip install -e ".[dev]"
export BASKETBALL_DATABASE_URL=postgresql://basketball:basketball@localhost:5432/basketball
alembic upgrade head
python scripts/seed.py
python -m basketball_api.main

Auth

Protected endpoints require a Keycloak-issued JWT (RS256). The API validates tokens against the realm's public JWKS endpoint (BASKETBALL_KEYCLOAK_REALM_URL). No client secret is needed -- only the RS256 public keys are used for verification. Realm roles (e.g. admin) are extracted from the realm_access.roles claim.