teecup/CLAUDE.md
Erol Haagenrud d68fbd89c9 ARCHITECTURE_DECISIONS.md — ny ADR-014 dokumenterer de fire uavhengige bryterne (bruk handicap / bruk course handicap / hcp-prosent / bruk matchplay-handicap), bekreftelsen av at prosentene matcher GameBook, og at motoren allerede støtter alle fire som atskilte kall.
FEATURE_BACKLOG.md — ny rad i "Fundament"-tabellen (📋 planlagt, referer ADR-014), pluss oppdatert rad for oppsett-API () og allowance-raden nå refererer ADR-014.
CLAUDE.md — "Neste steg" punkt 1 sier nå eksplisitt at de fire bryterne skal bygges inn samtidig med scoring, ikke bare prosenten.
2026-07-16 14:03:50 +02:00

4.5 KiB

CLAUDE.md — arbeidsinstruks for TeeCup

Les dette først i hver økt. Det koder hva vi har bestemt og hvordan vi jobber.

Autoritative kilder (les før du gjør noe)

  • ARCHITECTURE_DECISIONS.md — hva som er bestemt og hvorfor (ADR-001…014). Fasit.
  • FEATURE_BACKLOG.md — hva som gjenstår, hva som er utsatt, hva som mangler.
  • Endres en beslutning: legg til en ny ADR, ikke slett historikk. Hold begge filene oppdatert når noe avgjøres.

Sikkerhetsregler (ufravikelige)

  • Rør ALDRI teeoff-databasen eller den ekte teecup_db uten at brukeren eksplisitt har bekreftet det i samme økt. Test alltid migrasjoner mot en egen scratch-database først, og rydd opp etterpå.
  • Vis planen (hvilke kommandoer, mot hvilken database) FØR du kjører noe som skriver, migrerer eller sletter. Vent på bekreftelse.
  • Hemmeligheter (passord, secrets) bor i .env (filrettigheter 600), dekkes av .gitignore, committes aldri, og skrives aldri i klartekst i chatten eller i SQL-filer. Generer dem på serveren (openssl rand -base64 32).
  • Kjør appen som databaserollen teecup_app (NOSUPERUSER, NOBYPASSRLS) — aldri som teeoff_admin/superuser i runtime.

Arkitektur-invarianter (ikke bryt uten en ny ADR)

  • Tenant = organisasjon. organization_id på alle domenetabeller, håndhevet av RLS. App-koden setter app.current_org med SET LOCAL per transaksjon.
  • Verifiser at brukeren er medlem av organisasjonen FØR org-konteksten settes. RLS stoler blindt på app.current_org.
  • Egen innlogging (uavhengig av teeoff). Banedata hentes fra teeoff via lesende API, ikke delt database.
  • v1 = nøyaktig to lag (Ryder Cup-format), håndhevet i app-laget. Match-modellen holdes generell (to sider) så knockout/flere lag kan komme senere.
  • Handicap-/matchlogikk skal ligge i handicap_engine.py (rent, testet, uten db/API-avhengigheter). Allowances er konfig, ikke hardkodet.
  • Media (bilder/video) skal i objektlagring (MinIO), ikke i Postgres. Postgres holder bare metadata + nøkkel.

Arbeidsmåte

  • Inkrementelt. Ingenting tas for gitt før det er testet. Bekreft hvert steg før du går videre.
  • Bruk git (remote: brukerens Forgejo). Commit i logiske steg med tydelige meldinger.
  • Er du usikker på omfang eller en beslutning: spør heller enn å gjette.

Status (oppdater denne når ting endres)

Ferdig og verifisert:

  • Handicap-motor + tester (24/24, R&A-verifisert).
  • Skjema 001 + roller 002 + scoring/blind draw 003. Isolasjon bevist med test_isolation.sql (RLS-oppførsel, ikke bare at skjemaet kjører).
  • 002 hadde en reell bug (psql interpolerer ikke :'var' inne i DO $$...$$) — permanent fikset, verifisert mot scratch to ganger.
  • API-et kjørt for ekte (ikke bare syntaks-sjekket) i en engangs Docker- container mot en scratch-database, RLS bevist gjennom hele asyncpg-pool-stacken (ikke bare i rå SQL).
  • Oppsett-endepunktene er bygget og verifisert: app/routers/players.py (spillerpool), tournaments.py (turnering/lag/roster/økter, ADR-011 to-lags-grense håndhevet med FOR UPDATE-lås), matches.py (matcher/ deltakere/blind draw-lås, ADR-013-synlighet push-down i SQL). Delt feiloversettelse i app/errors.py, delte synlighetsspørringer i app/blind_draw.py. main.py er nå bare app-factory + include_router. Bevisst utelatt: course_handicap/playing_handicapmatch_participant beregnes IKKE ennå (venter på motor-integrasjon i scoring-runden — flerspillerformater trenger hele sidens spillere samtidig). Bevisst minimal autorisasjon: kapteins-only er ikke bygget (se FEATURE_BACKLOG ); bar er i dag org-medlemskap for oppsett, og "rostret på laget" for deltaker-/lås-handlinger.

Neste steg:

  1. Scoring-endepunkter: hole_score/match_hole_result-skriving, matchstatus fra handicap_engine.compute_match_state, og handicap-beregning (course_handicap/playing_handicap) for match_participant via motoren. Bygg samtidig inn de fire konfigurerbare bryterne fra ADR-014 (bruk handicap / bruk course handicap / hcp-prosent / bruk matchplay-handicap) i session.allowance_override — IKKE bare prosenten. Motoren støtter allerede alle fire som atskilte kall (course_handicap_raw, en AllowanceStrategy, match_play_strokes); det som mangler er at API-et leser bryterne og hopper over/kaller riktig steg.
  2. Containerisere TeeCup-API-et (Dockerfile + compose-tjeneste), koble mot teecup_db med teecup_app, rute via eksisterende Caddy til teecup.teeoff.no.
  3. Deretter frontend (PWA, offline-first) og kommunikasjon (migrasjon 004).