diff --git a/.claude/settings.local.json b/.claude/settings.local.json index 89e3dd0..21a523e 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -355,7 +355,10 @@ "Bash(docker run -d --name teecup_api_scratch --network teeoff_default \\\\ *)", "Bash(docker rm -f teecup_api_scratch >/dev/null 2>&1 *)", "Bash(python3 test_rounds_frontend_endpoints.py)", - "Bash(TEECUP_API_ORIGIN=http://localhost:8000 npx next build)" + "Bash(TEECUP_API_ORIGIN=http://localhost:8000 npx next build)", + "Bash(curl -s -o /dev/null -w \"teecup.teeoff.no/health: %{http_code}\\\\n\" https://teecup.teeoff.no/health)", + "Bash(curl -s -o /dev/null -w \"teecup.teeoff.no/dashboard: %{http_code}\\\\n\" https://teecup.teeoff.no/dashboard)", + "Bash(curl -s -o /dev/null -w \"teecup.teeoff.no/rounds: %{http_code}\\\\n\" https://teecup.teeoff.no/rounds)" ], "additionalDirectories": [ "/opt/teeoff/deploy", diff --git a/ARCHITECTURE_DECISIONS.md b/ARCHITECTURE_DECISIONS.md index 2c7d0b2..063cafc 100644 --- a/ARCHITECTURE_DECISIONS.md +++ b/ARCHITECTURE_DECISIONS.md @@ -1901,8 +1901,66 @@ skjerm bygget for dette ennå), boot-et rent, `/health`/`/dashboard` → 200, ADR-016/medlemsside-hendelsen — enhver ny API-prefiks MÅ inn her FØR en frontend-side bygges) — denne ENDRINGEN ligger IKKE deployet ennå (ingen frontend-kode bruker den), tas med i neste frontend-runde. -**Gjenstår:** hele frontend-en for frittstående rundeføring — ingenting -bygget ennå. +**Frontend BYGGET OG RULLET UT 2026-07-23** — fjerde og siste lag +(engine → skjema → API → frontend). Tre nødvendige tillegg til +`app/routers/rounds.py` funnet og bygget UNDER frontend-designet, ikke +antatt på forhånd: `GET /rounds/official-search`/`{slug}` (samme +teeoff-søkemønster som `courses.py`, men uten org-kontekst — frittstående +runder har ingen), `GET /personal-courses/{id}` (detalj med +utslag+kjønn — søk-endepunktet returnerte kun navn), og +`GET .../participants/{id}/holes` (et reelt hull: `RoundOut` bar aldri +hull-nivå-data, så ingen skjerm kunne vise gjeldende tilstand ved +gjenlasting). Hull-PATCH endret til å returnere hele den oppdaterte raden +i stedet for `{"ok": true}`. +**Reelt kontraktsfunn, bekreftet i scratch FØR frontend stolte på det:** +hull-PATCH-endepunktet er IKKE et ekte delvis-PATCH — det skriver ALLE +felt ved hvert kall (arvet fra hvordan `HoleUpdate`-modellen alltid har +defaultverdier for utelatte felt). Et PATCH som kun sender `score` ville +derfor stille NULLSTILT `putts` og alle andre allerede lagrede felt. +Løst ved at `round-detail.tsx` alltid slår sammen med gjeldende +hull-data før hver PATCH, aldri sender et isolert feltnavn alene — +verifisert eksplisitt i en egen scratch-test som FØRST beviste +nullstillings-oppførselen uten merge, DERETTER beviste at +merge-mønsteret unngår den. +**Nye sider:** `/rounds` (liste over egne runder), `/rounds/new` +(bane-kilde teeoff vs. egen — for egen bane: søk-før-opprett, samme idé +som org-banenes gjenbrukbare katalog; utslag filtrert til kun de som har +rating for brukerens registrerte kjønn, ADR-029s automatikk-prinsipp +gjenbrukt her selv om HCP-motoren er en helt annen), `/rounds/[id]` +(deltaker-faner — eier + gjester, ingen ekte kontokobling i v1 per +Beslutning D; hull-navigasjon fra runde-ens starthull; slag/putt- +tallvelgere i samme visuelle stil som `session-scorecard.tsx` sin +`StrokePicker`; kølle/retning/innspill/chip/bunker/straffeslag/ +putt-avstand bak en «flere detaljer»-utvidelse; GIR utledet og vist +KLIENTSIDE ved lesing, aldri lagret — nøyaktig Beslutning B sitt prinsipp; +fullfør-runde med HCP-differensial-sammendrag, låser videre redigering). +Lenket fra dashbordet som «Egne runder» (header-lenke + en egen kort på +forsiden) — bevisst adskilt navn fra det eksisterende «Mine runder» +(ADR-031, turnering-deltakelse) for å unngå at de to konseptene blandes +sammen i UI-et, selv om begge bokstavelig talt handler om "runder". +**Scratch-verifisert grundig** (isolert `teecup_app_scratch`-rolle + +isolert scratch-MinIO + engangs API-container, samme mønster som resten +av ADR-033): 22 automatiserte sjekker (egendefinert-bane-opprettelse med +to utslag/to kjønn, søk, detalj, PATCH-kontraktsbeviset over, +GIR-derivering for et konstruert par4/score3/putt1-tilfelle, gjest- +fjerning, kryss-bruker-autorisasjon 403, full fullføring med differensial) +PLUSS en separat, egen test av HELE teeoff-baserte opprettelsesløpet mot +den ekte kjørende `teeoff_api`-containeren (Borregaard Golfklubb, samme +anlegg som tidligere ADR-019/033-verifiseringer) som bekreftet +`course_handicap_snapshot` ble beregnet riktig fra live-hentet +rating. Ekte typesjekket PRODUKSJONSBUILD kjørt via +`docker build --target builder` (nøyaktig samme steg `Dockerfile` bruker +i prod, ikke `next dev`) — kompilerte rent, alle nye ruter listet. +**Rullet ut live 2026-07-23**, bruker bekreftet eksplisitt: ingen +migrasjon i denne del-runden, `docker compose up -d --build teecup_api +teecup_frontend`, begge containere boot-et rent, `/health`/`/dashboard`/ +`/rounds` → 200 over ekte https, `teeoff.no` upåvirket. +**Bevisst utenfor omfang, ikke bygget denne runden:** ekte kontokobling +for gjeste-deltakere (Beslutning D), automatisk oppdatering av +`app_user.handicap_index`/`handicap_history` ved fullført tellende runde +(åpent spørsmål i Beslutning G, fortsatt ubesvart), shotgun-start +(egen, separat ADR-034), GPS/avstandsmåling (se eget notat i +FEATURE_BACKLOG.md, krever data ingen kilde har i dag). **Motor-komponenten (punkt 1-11) er ✅ BYGGET OG TESTET 2026-07-22,** som første, isolerte byggesteg (ren Python, ingen DB/API/frontend ennå — diff --git a/CLAUDE.md b/CLAUDE.md index aafa5e9..a06e7c2 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -2346,14 +2346,59 @@ Neste steg: `teecup_db`/`teecup_api` 2026-07-22, `/health`/`/dashboard` → 200, `teeoff.no` upåvirket. `frontend/next.config.mjs` fikk `/rounds`/ `/personal-courses` lagt til i `rewrites()` proaktivt (ikke deployet - ennå, ingen frontend bruker den før neste runde). **Frontend for - frittstående rundeføring er fortsatt HELT ubygget** — neste steg. - Se ADR-033 i ARCHITECTURE_DECISIONS.md for full detalj. + ennå, ingen frontend bruker den før neste runde). **Notat fra bruker, IKKE designet:** planer om å måle lengde på slag + opplyse avstand til ulike punkter på banen (golf-GPS/rangefinder-type funksjonalitet) — krever geografiske/GPS-data ingen kilde har i dag (verken teeoff eller `personal_course`). Se FEATURE_BACKLOG.md for full detalj. + **Frontend bygget og rullet ut 2026-07-23, samme rekkefølge-prinsipp + (engine → skjema → API → frontend) fullført:** tre nye, + organisasjonsuavhengige endepunkter lagt til i `rounds.py` + (`GET /rounds/official-search`/`{slug}` — samme mønster som + `courses.py` sitt org-scopede søk, men uten org-kontekst, siden + frittstående runder ikke har noen; `GET /personal-courses/{id}` — + detalj med utslag+kjønn, manglet fra søk-runden) og en fjerde, + nødvendig tilføyelse oppdaget UNDER frontend-designet: `RoundOut` bar + aldri hull-nivå-data i det hele tatt — ny + `GET .../participants/{id}/holes`. Hull-PATCH-endepunktet endret til å + returnere hele den oppdaterte raden i stedet for `{"ok": true}`. + **Reelt kontraktsfunn, bekreftet i scratch FØR frontend stolte på det:** + hull-PATCH er IKKE et ekte delvis-PATCH — den skriver ALLE felt ved + hvert kall, så et utelatt felt (f.eks. putts) nullstilles stille hvis + frontend ikke sender det. Løst ved at `round-detail.tsx` alltid slår + sammen med gjeldende hull-data før hver PATCH, aldri sender et isolert + feltnavn alene — verifisert eksplisitt med en egen scratch-test som + FØRST beviste nullstillings-oppførselen, DERETTER beviste at + merge-mønsteret unngår den. + Nye sider: `/rounds` (liste), `/rounds/new` (bane-kilde teeoff/egen, + søk-før-opprett for egen bane samme idé som org-banene, utslag filtrert + på brukerens registrerte kjønn, dato/starthull/hull-antall), `/rounds/ + [id]` (deltaker-faner, hull-navigasjon fra starthull, slag/putt- + tallvelgere i samme stil som `session-scorecard.tsx` sin `StrokePicker`, + kølle/retning/innspill/chip/bunker/straffeslag bak en «flere detaljer»- + utvidelse, GIR utledet og vist klientside — aldri lagret, kun beregnet + fra `approach_result`+slag+putt ved lesing, fullfør-runde med HCP- + differensial-sammendrag). Lenket fra dashbordet som «Egne runder» + (bevisst adskilt navn fra det eksisterende «Mine runder», som gjelder + turnering-deltakelse — samme ord, to ulike konsepter). + **Scratch-verifisert grundig** (isolert `teecup_app_scratch`-rolle + + isolert scratch-MinIO + engangs API-container, samme mønster som hele + økten ellers): 22 sjekker som dekker egendefinert-bane-opprettelse med + to utslag/kjønn, søk, detalj, PATCH-kontrakten (inkl. det bevisste + nullstillings-beviset over), GIR-derivering, gjest-fjerning, + kryss-bruker-autorisasjon (403), og full fullføring med differensial + — PLUSS en egen, separat test av hele teeoff-baserte opprettelsesløpet + mot den ekte kjørende `teeoff_api`-containeren (Borregaard Golfklubb), + som bekreftet course_handicap ble beregnet riktig. Ekte typesjekket + PRODUKSJONSBUILD (`docker build --target builder`, samme steg som + `Dockerfile` faktisk bruker) kjørt og bekreftet — alle nye ruter listet. + **Rullet ut live 2026-07-23**, bruker bekreftet eksplisitt: ingen + migrasjon, `docker compose up -d --build teecup_api teecup_frontend`, + begge containere boot-et rent, `/health`/`/dashboard`/`/rounds` → 200, + `teeoff.no` upåvirket. **Frittstående rundeføring har dermed backend + OG frontend live** — se ADR-033 i ARCHITECTURE_DECISIONS.md for full + detalj om alle fire lagene (engine/skjema/API/frontend). 4. **Del 1 (fri, ukrevd sekundær-e-post) er nå BYGGET OG LIVE** (2026-07-21, se status over). **Del 2 (ekte konto-sammenslåing) fortsatt IKKE designet:** hva skjer hvis den ønskede adressen ALLEREDE tilhører en diff --git a/FEATURE_BACKLOG.md b/FEATURE_BACKLOG.md index 53c99a2..d9d5241 100644 --- a/FEATURE_BACKLOG.md +++ b/FEATURE_BACKLOG.md @@ -1366,14 +1366,24 @@ tom-skjermens endelige form kan bestemmes. --- -## Frittstående rundeføring + detaljert statistikk (uten turnering/organisasjon) — 🔨 ADR-033 SKREVET OG KILDEBELAGT, BYGGING PÅBEGYNT 2026-07-22 +## Frittstående rundeføring + detaljert statistikk (uten turnering/organisasjon) — ✅ BACKEND + FRONTEND LIVE (2026-07-23) **Fremdrift 2026-07-22:** HCP-indeks-motor (43/43 tester), databaseskjema (`020`+`021`, sistnevnte en fiks for manglende rating-snapshot-kolonner), OG et fullt API-lag (`app/routers/rounds.py`) er alle bygget, -scratch-verifisert og rullet ut mot ekte `teecup_db`/`teecup_api`. Se -ADR-033 i ARCHITECTURE_DECISIONS.md for full detalj. **Gjenstår: hele -frontend-en** — ingenting bygget ennå. +scratch-verifisert og rullet ut mot ekte `teecup_db`/`teecup_api`. + +**Frontend bygget og rullet ut 2026-07-23** — se ADR-033 i +ARCHITECTURE_DECISIONS.md for full detalj om alle tre lagene (engine, +skjema, API) og hele frontend-runden (nye endepunkter, komponenter, +verifisering, utrulling). Kort: `/rounds` (liste), `/rounds/new` +(bane-søk teeoff/egen + opprett egen bane, utslag/dato/hull), `/rounds/[id]` +(deltakere, hull-for-hull-registrering med automatisk GIR-visning, +fullfør-runde med HCP-differensial). Lenket fra dashbordet som «Egne +runder». Ingen migrasjon i denne del-runden — kun tre nye, +organisasjonsuavhengige endepunkter i `rounds.py` +(`official-search`/`official-search/{slug}`/`personal-courses/{id}`/ +`.../holes`) og en endring av hull-PATCH-responsen. **Notat fra bruker, IKKE designet/bygget ennå (fanget 2026-07-22):** brukeren har tenkt å ha med (a) måling av lengde på slag, og (b) å kunne