Update Todos
Add non-org-scoped teeoff search + personal-course detail endpoints to rounds.py Build /rounds list page + component Build /rounds/new creation flow (course search/create, tee, date, holes) Build /rounds/[id] detail page (participants, hole-by-hole stats, complete) Link new feature from dashboard Scratch-verify backend additions + typecheck production build Deploy live after user confirmation Update ADR-033/FEATURE_BACKLOG/CLAUDE.md status Frontend for frittstående rundeføring er nå live på teecup.teeoff.no. Oppsummert: /rounds — liste over egne runder, med «Ny runde»-knapp /rounds/new — velg bane (søk i teeoff live, eller søk/opprett egen bane), utslag (filtrert til ditt registrerte kjønn), dato, starthull, 9/18 hull /rounds/[id] — deltaker-faner (deg + gjester), hull-for-hull-registrering med slag/putt-tallvelgere, utvidbare detaljer (kølle, utslagsretning, innspill, chip, bunker, straffeslag, putt-avstand), automatisk GIR-visning, og «Fullfør runde» som beregner HCP-differensial Lenket fra dashbordet som «Egne runder» — bevisst adskilt fra det eksisterende «Mine runder» (turnering-deltakelse) for å unngå forveksling. Underveis fant jeg og fikset et reelt kontraktshull: hull-PATCH-endepunktet skriver alle felt ved hvert kall, ikke bare det som sendes — jeg bekreftet dette eksplisitt i scratch (et PATCH med kun score nullstiller stille putts) og bygget derfor inn en merge-før-send i frontend-koden. Alt er scratch-verifisert (22 sjekker + en egen test av hele teeoff-baserte oppretteflyten mot ekte teeoff_api), typesjekket med ekte produksjonsbuild, og rullet ut uten migrasjon. teeoff.no upåvirket gjennom hele runden. Status oppdatert i CLAUDE.md, FEATURE_BACKLOG.md og ADR-033.
This commit is contained in:
parent
c15c68efca
commit
2cbb9fd308
4 changed files with 126 additions and 10 deletions
|
|
@ -355,7 +355,10 @@
|
||||||
"Bash(docker run -d --name teecup_api_scratch --network teeoff_default \\\\ *)",
|
"Bash(docker run -d --name teecup_api_scratch --network teeoff_default \\\\ *)",
|
||||||
"Bash(docker rm -f teecup_api_scratch >/dev/null 2>&1 *)",
|
"Bash(docker rm -f teecup_api_scratch >/dev/null 2>&1 *)",
|
||||||
"Bash(python3 test_rounds_frontend_endpoints.py)",
|
"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": [
|
"additionalDirectories": [
|
||||||
"/opt/teeoff/deploy",
|
"/opt/teeoff/deploy",
|
||||||
|
|
|
||||||
|
|
@ -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
|
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-side bygges) — denne ENDRINGEN ligger IKKE deployet ennå (ingen
|
||||||
frontend-kode bruker den), tas med i neste frontend-runde.
|
frontend-kode bruker den), tas med i neste frontend-runde.
|
||||||
**Gjenstår:** hele frontend-en for frittstående rundeføring — ingenting
|
**Frontend BYGGET OG RULLET UT 2026-07-23** — fjerde og siste lag
|
||||||
bygget ennå.
|
(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,**
|
**Motor-komponenten (punkt 1-11) er ✅ BYGGET OG TESTET 2026-07-22,**
|
||||||
som første, isolerte byggesteg (ren Python, ingen DB/API/frontend ennå —
|
som første, isolerte byggesteg (ren Python, ingen DB/API/frontend ennå —
|
||||||
|
|
|
||||||
51
CLAUDE.md
51
CLAUDE.md
|
|
@ -2346,14 +2346,59 @@ Neste steg:
|
||||||
`teecup_db`/`teecup_api` 2026-07-22, `/health`/`/dashboard` → 200,
|
`teecup_db`/`teecup_api` 2026-07-22, `/health`/`/dashboard` → 200,
|
||||||
`teeoff.no` upåvirket. `frontend/next.config.mjs` fikk `/rounds`/
|
`teeoff.no` upåvirket. `frontend/next.config.mjs` fikk `/rounds`/
|
||||||
`/personal-courses` lagt til i `rewrites()` proaktivt (ikke deployet
|
`/personal-courses` lagt til i `rewrites()` proaktivt (ikke deployet
|
||||||
ennå, ingen frontend bruker den før neste runde). **Frontend for
|
ennå, ingen frontend bruker den før neste runde).
|
||||||
frittstående rundeføring er fortsatt HELT ubygget** — neste steg.
|
|
||||||
Se ADR-033 i ARCHITECTURE_DECISIONS.md for full detalj.
|
|
||||||
**Notat fra bruker, IKKE designet:** planer om å måle lengde på slag +
|
**Notat fra bruker, IKKE designet:** planer om å måle lengde på slag +
|
||||||
opplyse avstand til ulike punkter på banen (golf-GPS/rangefinder-type
|
opplyse avstand til ulike punkter på banen (golf-GPS/rangefinder-type
|
||||||
funksjonalitet) — krever geografiske/GPS-data ingen kilde har i dag
|
funksjonalitet) — krever geografiske/GPS-data ingen kilde har i dag
|
||||||
(verken teeoff eller `personal_course`). Se FEATURE_BACKLOG.md for
|
(verken teeoff eller `personal_course`). Se FEATURE_BACKLOG.md for
|
||||||
full detalj.
|
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,
|
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
|
se status over). **Del 2 (ekte konto-sammenslåing) fortsatt IKKE
|
||||||
designet:** hva skjer hvis den ønskede adressen ALLEREDE tilhører en
|
designet:** hva skjer hvis den ønskede adressen ALLEREDE tilhører en
|
||||||
|
|
|
||||||
|
|
@ -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
|
**Fremdrift 2026-07-22:** HCP-indeks-motor (43/43 tester), databaseskjema
|
||||||
(`020`+`021`, sistnevnte en fiks for manglende rating-snapshot-kolonner),
|
(`020`+`021`, sistnevnte en fiks for manglende rating-snapshot-kolonner),
|
||||||
OG et fullt API-lag (`app/routers/rounds.py`) er alle bygget,
|
OG et fullt API-lag (`app/routers/rounds.py`) er alle bygget,
|
||||||
scratch-verifisert og rullet ut mot ekte `teecup_db`/`teecup_api`. Se
|
scratch-verifisert og rullet ut mot ekte `teecup_db`/`teecup_api`.
|
||||||
ADR-033 i ARCHITECTURE_DECISIONS.md for full detalj. **Gjenstår: hele
|
|
||||||
frontend-en** — ingenting bygget ennå.
|
**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):**
|
**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
|
brukeren har tenkt å ha med (a) måling av lengde på slag, og (b) å kunne
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue