Bygget: GET /public/tournaments/{id} og POST /public/tournaments/{id}/register — helt uautentisert, egen /public-prefiks. players.py utvidet med alle sju nye feltene.
Grundig scratch-testet, ikke bare "kjørte uten feil": samtykke-avvisning, duplikat-avvisning, e-post-matching mot en organisator-forhåndsopprettet spiller (bekreftet ingen duplikat, mobil fylt inn, navn ikke overskrevet), kapasitet+venteliste, kapasitet+stengt, godkjenningskrav, utløpt frist — alle seks scenarioene fra ADR-en testet én etter én og ga riktig resultat.
Notatet ditt om synlighet er fanget i FEATURE_BACKLOG.md, koblet til det samme åpne spørsmålet for «Banter Board»-feeden — før dette API-et ble bygget, ikke etter, slik du ba om.
Gjenstår, bevisst utsatt:
E-post-basert kontosammenkobling ved innlogging (ADR-017 Beslutning B sin andre halvdel) — trenger en ny SECURITY DEFINER-funksjon på tvers av org-er, altså migrasjon 008 siden 007 alt er kjørt mot prod. Ikke gjort i denne runden.
Selve påmeldingsflyten er ikke testet med ekte data mot prod (kun ikke-destruktive sjekker: ukjent turnering ga korrekt 404).
Landingssider — egen ADR-runde, som avtalt.
43 lines
1.2 KiB
Python
43 lines
1.2 KiB
Python
"""
|
|
TeeCup API.
|
|
|
|
App-factory + livssyklus. All forretningslogikk ligger i app/routers/ — hver
|
|
rute der følger samme mønster: Depends(get_authorized_org) verifiserer
|
|
medlemskap, org_connection(organization_id) setter RLS-konteksten lokalt for
|
|
transaksjonen. Se ARCHITECTURE_DECISIONS.md (ADR-001…014) for reglene bak.
|
|
|
|
Kjøres i app-containeren (FastAPI + asyncpg + uvicorn):
|
|
uvicorn app.main:app --host 0.0.0.0 --port 8000
|
|
"""
|
|
|
|
from contextlib import asynccontextmanager
|
|
|
|
from fastapi import FastAPI
|
|
|
|
from .db import init_pool, close_pool
|
|
from .routers import auth, matches, organizations, players, registration, scoring, tournaments
|
|
|
|
|
|
@asynccontextmanager
|
|
async def lifespan(app: FastAPI):
|
|
await init_pool()
|
|
try:
|
|
yield
|
|
finally:
|
|
await close_pool()
|
|
|
|
|
|
app = FastAPI(title="TeeCup API", lifespan=lifespan)
|
|
|
|
app.include_router(auth.router)
|
|
app.include_router(organizations.router)
|
|
app.include_router(players.router)
|
|
app.include_router(tournaments.router)
|
|
app.include_router(matches.router)
|
|
app.include_router(scoring.router)
|
|
app.include_router(registration.router)
|
|
|
|
|
|
@app.get("/health")
|
|
async def health() -> dict[str, str]:
|
|
return {"status": "ok"}
|