Spørsmålene dine avdekket en reell bug (ikke bare et åpent spørsmål): siden ingenting eksplisitt lukker en match, kan noen fortsette å legge inn hull etter at matchen matematisk er avgjort, og det kan endre den cachede marginen ved neste omregning. Fanget i FEATURE_BACKLOG.md. Basert på svarene dine: Match-lås bygges snart — neste lille runde, tetter spøkelses-hull-buggen. Walkover/konsesjon venter til brukerroller (kaptein/organisator) er avgjort. Alt er dokumentert i FEATURE_BACKLOG.md under en ny seksjon, og CLAUDE.md er oppdatert.
5.2 KiB
5.2 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 ekteteecup_dbuten 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 somteeoff_admin/superuser i runtime.
Arkitektur-invarianter (ikke bryt uten en ny ADR)
- Tenant = organisasjon.
organization_idpå alle domenetabeller, håndhevet av RLS. App-koden setterapp.current_orgmedSET LOCALper 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+ roller002+ scoring/blind draw003. Isolasjon bevist medtest_isolation.sql(RLS-oppførsel, ikke bare at skjemaet kjører). - 002 hadde en reell bug (psql interpolerer ikke
:'var'inne iDO $$...$$) — 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 medFOR UPDATE-lås),matches.py(matcher/ deltakere/blind draw-lås, ADR-013-synlighet push-down i SQL). Delt feiloversettelse iapp/errors.py, delte synlighetsspørringer iapp/blind_draw.py.main.pyer nå bare app-factory +include_router. - Scoring-runden er bygget og verifisert for ekte mot scratch-db (18-hulls
bane med
tee_rating, 4 spillere for fourball-testing):app/handicap.py(ADR-014 fire brytere viaparse_allowance_config, handicap beregnes icompute_and_store_side_handicapsrett etter deltaker-innsetting — singles/fourball per spiller umiddelbart, foursome/greensome/scramble kun når siden er komplett),app/routers/scoring.py(hole-scores/hole-results-upsert,scorecard-GET, matchstatus-recompute medFOR UPDATE-lås mot race og SAMMENHENGENDE-prefiks-regel for uferdige hull).app/team_authz.pyskilt ut framatches.py(delt medscoring.py). Alle 10 planlagte tester bestått, inkl. fourball better-ball-aggregering (MIN av to nettoer, venter til begge partnere har registrert), poeng-caching ved tidlig avgjort match, og ADR-014-bryterenuse_handicap=false. Fant og fikset underveis:tournaments.pysinSessionCreatemangletscoring_modehelt (økter kunne aldri opprettes ihole_result-modus via API-et) — lagt til. Bevisst utelatt/kjente begrensninger: en side som aldri når forventet deltakerantall (no-show) får aldri beregnet handicap og matchen kan da aldri avgjøres — ingen manuell overstyring bygget. Score-skriving er upsert (ingen avvisning ved duplikat) — ingen audit-trail på rettelser. Kapteins-only autorisasjon fortsatt ikke bygget (FEATURE_BACKLOG ❓); bar er «rostret på laget».
Neste steg:
- Containerisere TeeCup-API-et (Dockerfile + compose-tjeneste), koble mot
teecup_dbmedteecup_app, rute via eksisterende Caddy tilteecup.teeoff.no. (Under scratch-verifisering måtte hele/opt/teecupmonteres, ikke bareapp/, fordihandicap_engine.pyer et toppnivå-søskenmodul tilapp-pakken — Dockerfilen måCOPYbegge inn med samme relative plassering.) - Deretter frontend (PWA, offline-first) og kommunikasjon (migrasjon 004).