SYSTEM OVERVIEW
Legend
Cloudflare Pages
Pages buildnpm run build in client/(tsc + vite build → dist/)
React + Vite SPAldt.zbarchibald.comAPI URL baked in at build(VITE_API_BASE_URL)
Player's browserruns the draft UI;champion iconsload straight fromData Dragon
Google Cloud · us-central1
Cloud Run: lol-draft-apiFastAPI, public (no auth), CORS allowlistmax 1 instance, scales to zero30 s timeout, $1 spend cap
Cloud Build → Artifact Registrybuilds the backend-only Docker image
Secret Managersecret: database-url
Neon Postgresmetadata · championschallenger_playersmatcheschampion_role_statschampion_relationships
GitHub · ZBArchibald/lol_draft_tool
main branchbackend/ + client/
deploy.ymlpush to main touching backend/
daily-maintenance.ymlcron 10:10 UTC: daily-maintenance,then update-challengers
match-sync.ymlcron 10:15 + 22:15 UTC: run-match-sync
ubuntu-latest runneruv run ldt <command>secrets: RIOT_API_KEY, DATABASE_URLshared concurrency group ldt-db,so the two jobs never overlap
Riot APILEAGUE-V4 + MATCH-V5
Data Dragon CDNpatch, champions, icons
runtime request / data
build, deploy, trigger
header color = provider
loads the app
GET /api/champions
POST /api/recommend
SQL over a psycopg pool
DATABASE_URL
SQL reads +
batched writes
push to main
push to main
gcloud run deploy (Workload Identity)
new revision