Commit graph

74 commits

Author SHA1 Message Date
242c7a2bfc Før filendringer 2026-08-03 14:32:48 +02:00
5e66ce63f5 Før bakgrunnsfjerning 2026-08-02 16:34:54 +02:00
3da637b7a2 Ja, jeg forsto rekkefølgen — steg 1 og 2 er nå ferdig og scratch-verifisert:
Steg 1 (backend, HCP-prosent + Match-HCP): ny migrasjon 051_round_allowance_override.sql (round.allowance_override jsonb), koblet inn i _recompute_side_handicaps/_relative_strokes_for_round + POST/PATCH /rounds. Verifisert presist i scratch: 100%→50%-prosent ga playing_handicap 24/10 → 12/5 nøyaktig som beregnet for hånd, og use_matchplay_handicap slått av ga rå 12/5 i stedet for differensial 7/0. Slagspill upåvirket (regresjon bekreftet).

Steg 2 (kode-fiks, lag-gruppering): ScorecardGrid (live-scoring) og MatchScorecardGrid (post-runde/fremtidig sammenslått side) sorterer nå stabilt på round_side_id før rendering. Bygget en fersk scratch-fourball-runde med akkurat ditt bug-scenario (A→Rødt, B→Blått, C→Rødt, D→Blått, lagt til i den rekkefølgen) og bekreftet visuelt i nettleseren i begge visningene: Rødt lag vises samlet, deretter Blått — ikke lenger interleaved.

Typesjekk + full produksjonsbuild kompilerte rent gjennom hele runden.

Gjenstår før jeg går videre til V0-promptene: migrasjon 051 er kun kjørt i scratch, ikke mot ekte teecup_db. Planen er:

docker exec -i teeoff_db psql -U teeoff_admin -d teecup_db -v ON_ERROR_STOP=1 < 051_round_allowance_override.sql
— ett rent additivt ALTER TABLE round ADD COLUMN allowance_override jsonb, ingen eksisterende rader berøres. Deretter docker compose up -d --build teecup_api teecup_frontend (backend for allowance-koblingen, frontend for gruppering-fiksen).

Bekreft så kjører jeg dette, og går videre til V0-prompt 1 (rundeoppsett-veiviseren).
2026-08-02 08:24:01 +02:00
27bff38afe Kort: selve grunnfargen er et bevisst, ekte match. Hvordan overflatene BYGGES OPP (glass vs. flatt, boxed vs. flytende) er derimot forskjellig, og det er V0 sin egen tolkning, ikke noe hentet direkte fra dette bildet. 2026-08-01 21:15:07 +02:00
968ea79184 Update Todos
Chapman: format-valg i new-round.tsx + tournament-program.tsx (session)

Nassau: nytt vindu-resultatvisning i round-detail.tsx + session-scorecard.tsx

Københavner: format-valg + poengtabell-visning i individual-tournament-detail.tsx

Bingo Bango Bongo: format-valg + per-hull picker + poengtabell

Flaggturnering: format-valg + nedtelling/resultatvisning

Shamble: format-valg + best_n + lagvisning (frittstående + org-lag)

Money Ball: format-valg + lineup_order + lagvisning (frittstående + org-lag)

High-low-high: format-valg + løpende poeng-resultatvisning (alle 3 flater)

Ekte produksjonsbuild -- FERDIG, kompilerte rent (27 ruter)

Browserverifisert alle åtte formatene -- fant og fikset ekte backend-bug (side-handicap-recompute)

Rullet ut mot ekte teecup_api/teecup_frontend -- FERDIG, health checks grønne, teeoff.no upåvirket
Rullet ut live 2026-07-30. Frontend for alle åtte nye turneringsformatene (Chapman, Nassau, Københavner, Bingo Bango Bongo, Flaggturnering, Shamble, Money Ball, High-low-high) er nå bygget, browserverifisert og live — dekker alle tre flatene (frittstående runder, org-lagturneringer, org-individuelle turneringer). Fant og fikset én reell backend-bug underveis (side-handicap ble ikke regnet på nytt når en deltakers HCP ble satt/endret etter at de allerede var tildelt en side). Ingen migrasjon i denne runden, teeoff.no upåvirket. ADR-039/åtte-formater-arbeidet er dermed helt ferdig, backend og frontend.
2026-08-01 06:51:53 +02:00
bba63b6cc9 Nytt horisontalt scorekort (/my-rounds/[id]/scorecard) — ekte HTML-tabell med faste kolonnebredder, ingen scroll i det hele tatt. Score-cellene bruker form (sirkel = under par, firkant = over par) + fylt/ufylt i stedet for farge alene, med egen symbolforklaring. Ut/Inn-blokker for 18-hulls runder, én blokk for 9-hulls. Egen dedikert side (ikke sammenslått med statistikk-siden), lenket fra både "Runde fullført"-banneret og fra statistikk-siden. Byttet ut V0s egen forenklede HCP-formel med backends allerede beregnede strokes_received, så det ikke finnes to ulike slagfordelings-implementasjoner i appen. Den gamle vertikale scorekort-tabellen i statistikk-siden er fjernet — nå bor det rå scorekortet kun ett sted.
Anywayslag-fiksen din: lagt til som en tredje flis ved siden av Bunkerslag/Straffeslag, og seksjonen omdøpt fra "Chip, bunker og straffeslag" til "Annet" — notert i .md-filene at et notatfelt trolig kommer dit senere.

Ekte typesjekket build, ingen backend-endring nødvendig, teeoff.no upåvirket.
2026-07-24 23:33:41 +02:00
f5d1491ceb Update Todos
Bygge backend for starthull + tidspunkt-korrigering (start_hole/started_at/completed_at i PATCH /rounds/{id})

Bygge frontend: starthull-endring + tidspunkt-korrigering i EditRoundPanel

Bygge backend nearby-endepunkt for offisielle baner (Haversine)

Bygge frontend: geolokasjon + nærmeste baner-liste i OfficialSearchStep

Scratch-verifisere + typesjekket build

Rulle ut etter bekreftelse
Alt live og dokumentert. Oppsummert:

Starthull kan nå endres midt i runden (uavhengig av bane-bytte), og utslags-/fullført-tidspunkt kan korrigeres i etterkant — fullført-tidspunktet kun etter at runden faktisk er fullført.
Nærmeste baner vises nå automatisk (med avstand, nærmeste uthevet) rett over søkefeltet når du velger «Offisiell bane» ved ny runde — spør om posisjon, feiler stille hvis avslått.
Verifisert med 14 scratch-sjekker (inkludert et ekte nearby-oppslag mot teeoff fra Tjømes egne koordinater), ren build, rullet ut uten migrasjon. teeoff.no upåvirket.
2026-07-24 11:21:39 +02:00
65f876e6dc Oppsummering av det som er fikset/bygget i denne runden:
Starthull-bugen (og trolig GIR-avviket den forårsaket) — fikset
Kølle-bag i profilen (28 faste kølletyper, maks 14) — bygget
Anywayslag-statistikkfelt — bygget
Valgfritt statistikknivå per deltaker (Kun slag / Slag og putter / All statistikk, default Kun slag) — bygget
Putt-avstand som faste bøtter i stedet for fritekst — bygget
«Hullet er spilt»-avkrysningen fjernet — gjort
Bekreft, så kjører jeg migrasjonen og ruller ut.
2026-07-24 06:27:35 +02:00
29a6b90127 Update Todos
Diagnostisere de to feilmeldingene fra skjermbildene

Flytte frontend-sidene fra /rounds/* til /my-rounds/* (kollisjon med API-proxyen)

Oppdatere alle interne lenker/router-kall til nye stier

Oppdatere next.config.mjs-kommentaren med denne lærdommen

Typesjekket produksjonsbuild

Rulle ut live etter bekreftelse

Oppdatere statusdokumentasjon
Ferdig og live. Oppsummert:

Begge feilmeldingene skyldtes samme rot-årsak: /rounds var både frontend-sidens sti og backend-APIets ressursprefiks. Next.js sin rewrite-presedens ga to motsatte feil samtidig — listesiden/opprett-runde-kallet nådde aldri backend (fikk Next sin egen HTML tilbake i stedet for JSON), mens selve rundedetalj-siden var fullstendig uoppnåelig i motsatt retning. Fikset ved å flytte alle tre frontend-rutene til /my-rounds/*, uendret API på /rounds. Bekreftet med curl mot ekte produksjon både før og etter — nå fungerer alt som det skal. Det andre skjermbildets «55/50/44/32» var forøvrig ikke en bug, bare Tjøme Golfklubb sine ekte utslagsnavn i teeoff.

Alt rullet ut, teeoff.no upåvirket, status dokumentert i CLAUDE.md/FEATURE_BACKLOG.md/ADR-033.
2026-07-23 12:19:31 +02:00
6e688c6440 Update Todos
Diagnostisere de to feilmeldingene fra skjermbildene

Flytte frontend-sidene fra /rounds/* til /my-rounds/* (kollisjon med API-proxyen)

Oppdatere alle interne lenker/router-kall til nye stier

Oppdatere next.config.mjs-kommentaren med denne lærdommen

Typesjekket produksjonsbuild

Rulle ut live etter bekreftelse

Oppdatere statusdokumentasjon
Fant og fikset rot-årsaken til begge feilmeldingene — en reell, alvorlig bug, ikke bare kosmetikk:

/rounds var samtidig navnet på både frontend-listesiden og backend-APIets ressursprefiks. Next.js sin rewrite-presedens ("afterFiles") gjorde at:

GET/POST /rounds fra klienten aldri nådde backend — den statiske siden vant, så fetch() fikk Next sin egen HTML tilbake i stedet for JSON. Det ga akkurat de to feilmeldingene i skjermbildene.
/rounds/[id] (rundedetaljsiden) hadde det motsatte problemet — der vant rewriten, så selve siden var fullstendig uoppnåelig (ville vist rå backend-JSON i stedet for UI-et om du hadde kommet så langt).
Dette er nøyaktig samme klasse feil som medlemsside-hendelsen under ADR-016, bare i begge retninger samtidig siden det denne gangen var en eksakt navnekollisjon, ikke bare nøsting.

Fikset: flyttet alle tre frontend-sidene til /my-rounds/* (list, new, [id]) — API-et beholder /rounds uendret. Oppdatert alle interne lenker (round-card.tsx, own-rounds.tsx, new-round.tsx, round-detail.tsx, dashboard.tsx), lagt inn en tydelig advarsel i next.config.mjs for å hindre at dette gjentar seg. Bekreftet: «55/50/44/32» i det andre skjermbildet er ikke en bug — det er Tjøme Golfklubb sine faktiske utslagsnavn i teeoff (lengde i hundremeter).

Typesjekket produksjonsbuild kompilerer rent med de nye rutene.
2026-07-23 12:07:40 +02:00
7301de72c5 Update Todos
Pakke ut og diffe alle tre V0-eksporter mot levende tre

Lese V0s round-card.tsx, own-rounds.tsx, new-round.tsx, round-detail.tsx grundig

Lese V0s app/rounds*/page.tsx routing-filer

Ta inn round-card.tsx uendret

Skrive om datalaget i own-rounds.tsx (fjerne mock/toggle, ekte fetch)

Skrive om datalaget i new-round.tsx (ekte søk/opprett/bekreft)

Skrive om datalaget i round-detail.tsx (ekte runde/deltakere/hull, fjerne preview-toggle)

Oppdatere page.tsx-rutene og slette gamle hånd-bygde komponentfiler

Typesjekket produksjonsbuild + slette V0-zip-filene

Rulle ut live etter bekreftelse
Rullet ut og dokumentert. Oppsummert:

Frontend for frittstående rundeføring bruker nå V0s design på alle tre skjermene (/rounds, /rounds/new, /rounds/[id]), med ekte data koblet inn på samme måte som resten av appen. Verifisert med typesjekket produksjonsbuild, ingen backend-endring, teeoff.no upåvirket gjennom hele utrullingen. Status oppdatert i CLAUDE.md, FEATURE_BACKLOG.md og ADR-033.

Gjenstår fortsatt fra tidligere: ekte kontokobling for gjestedeltakere, automatisk HCP-oppdatering ved fullført runde, shotgun-start (egen ADR-034), og GPS/avstandsmåling.
2026-07-23 11:31:50 +02:00
546b52665f V0-integrasjonen er ferdig. Kort om hva som skjedde:
Diff mot levende tre (samme rutine som alltid): alle tre eksportene var fulle re-eksporter av hele prosjektet, bare fire filer var faktisk nye/endret for dette formålet: round-card.tsx, own-rounds.tsx, new-round.tsx, round-detail.tsx (+ tre app/rounds*/page.tsx-ruter). Alt annet (login-form, dashboard, config osv.) var forventede full-reverts og ble ikke rørt. Ett kjent V0-avvik dukket opp igjen (app/clubs/[id]/page.tsx med feil parameternavn — samme feil som ble rettet i klubbsiderunden) — hoppet bevisst over den, som vanlig.

Erstattet mine hånd-bygde skjermer med V0s presentasjon, datalag skrevet om fra mock til ekte fetch, blant annet:

Egen-bane-søket er nå et ekte to-stegs oppslag (søk → hent detalj med utslag) siden V0s modell antok baner allerede hadde utslagene ferdig innbakt i søkeresultatet.
La til «Annet» som et tredje kjønnsvalg for gjestespillere (V0 hadde kun mann/kvinne) — matcher appens ellers etablerte konvensjon.
Beholdt merge-før-PATCH-sikringen fra forrige runde (hull-endepunktet skriver alle felt hver gang).
Fjernet V0s dev-only forhåndsvisningsbrytere («Forhåndsvis: Pågår/Fullført» osv.) — samme opprydning som i tidligere runder.
Verifisert: ekte typesjekket produksjonsbuild (docker build --target builder) kompilerte rent, alle ruter listet. Ingen backend-endring i denne runden, så API-kontrakten er allerede scratch-bevist fra forrige runde — jeg har ikke kjørt en ny interaktiv nettleser-test (intet slikt verktøy tilgjengelig), kun kodegjennomgang + typesjekk.

Zip-filene er slettet fra prosjektroten.
2026-07-23 11:27:37 +02:00
2cbb9fd308 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.
2026-07-23 06:06:41 +02:00
c15c68efca 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 standalone round tracking is built and fully verified in scratch — 22 backend contract checks plus a live end-to-end test against both course sources (custom bane and real teeoff lookup), and a clean typechecked production build (docker build --target builder) showing all new routes (/rounds, /rounds/new, /rounds/[id]).

What's new, in summary:

Backend: three additions to app/routers/rounds.py — non-org-scoped teeoff facility/course search (/rounds/official-search*), a personal-course detail endpoint exposing tee/gender info, and a GET .../holes endpoint (needed since RoundOut never carried hole-level data). Also changed the hole-PATCH endpoint to return the full updated row instead of {"ok": true}. No migration — no schema touched.
Frontend: /rounds (list), /rounds/new (course search or create, tee/date/holes-planned), /rounds/[id] (participants, hole-by-hole stat entry with GIR auto-derived, complete-round flow with HCP differential summary). Linked from the dashboard both as a header shortcut and a prominent "Egne runder" entry card.
One thing worth flagging: the hole-PATCH endpoint replaces all fields every call rather than doing a true partial update, so the frontend always merges the current hole state before sending a patch — I confirmed this contract explicitly in scratch (a naive partial PATCH silently nulls out unrelated fields).
2026-07-23 05:51:26 +02:00
3270d044de Migrasjonen er kjørt, og jeg har fortsatt helt til et komplett, verifisert API-lag.
Underveis fant og fikset jeg et reelt hull: round_participant manglet kolonner for selve rating-tallene (kun tee-navnet var lagret) — løst med migrasjon 021, kjørt mot ekte database sammen med resten.

Bygget og rullet ut:

app/routers/rounds.py — opprett/liste/hent/slett runde, legg til/fjern gjestedeltakere, registrer statistikk hull for hull, og en fullfør-endepunkt som kjører hele kjeden (Adjusted Gross Score → Score Differential → tellende-vurdering).
26 scratch-sjekker grønt, pluss en egen test mot den ekte kjørende teeoff-tjenesten som bekreftet at live-oppslaget fungerer nøyaktig som tiltenkt (ingen bane-kopi skrives noe sted).
Begge migrasjoner + ny kode er nå live mot ekte teecup_db/teecup_api. teeoff.no upåvirket.
Jeg la også inn /rounds og /personal-courses i frontendens proxy-oppsett proaktivt, siden prosjektet har blitt bitt av glemte proxy-ruter før — ikke deployet ennå, tas med neste gang frontend faktisk bygges.

Notatet om slaglengde-måling og avstand-til-punkter-på-banen er lagret i CLAUDE.md og FEATURE_BACKLOG.md, med en tydelig flagget avhengighet: dette krever geografiske/GPS-data som ingen nåværende kilde (verken teeoff eller den nye banekatalogen) har.
2026-07-22 11:31:08 +02:00
80e293cfd4 Første byggesteg ferdig: HCP-indeks-motoren.
Bygget og testet i handicap_engine.py — ren Python, ingen database/API rørt ennå (samme "test i isolasjon først"-prinsipp som resten av motoren). 9 nye funksjoner dekker hele kjeden fra rå hullscore til en ferdig, cap-justert HCP-indeks: Net Par/Net Double Bogey, Adjusted Gross Score, Score Differential, Handicap Index (beste-8-av-20 med opptrappingstabell for nye spillere), Low Handicap Index, soft/hard cap, og den avvikende 9-hulls Course Handicap-formelen.

41/41 tester bestått, flere verifisert direkte mot regelbokens egne tallregneeksempler (ikke bare intern konsistens) — blant annet begge Rule 5.2a-eksemplene (13,2 / 34,1 / 37,4), alle tre Rule 5.1c-avrundingseksemplene, og soft/hard cap-oppførselen fra Diagram 5.8. For Diagram 3.1b (Net Double Bogey-eksempelet) var jeg åpen om en reell begrensning: front-9 stemte eksakt mot bildet, men jeg kunne ikke garantere hvert enkelt siffer i back-9-scorerekken fra bilde-oppløsningen — testen bruker derfor kun det ene tydelig annoterte, kildebelagte tallet (hull 17: brutto 9, capped til 7) og egenkomponerte tall for resten, dokumentert i kommentaren.

Dokumentasjonen (ADR-033, CLAUDE.md, FEATURE_BACKLOG.md) er oppdatert til å reflektere at bygging er påbegynt.
2026-07-22 10:28:01 +02:00
c904bd7949 ADR-033 er nå fullt kildebelagt. Kort oppsummert hva som endret seg:
Banedata: bekreftet — live oppslag mot teeoff, ikke import.
HCP: leste hele den offisielle WHS Rules of Handicapping 2024 (Rule 2, 3, 5, 6). To viktige presiseringer av det du selv antok:
«Minst 9 hull» stemmer ikke helt — en 9-hulls-runde må ha alle 9 hull i et faktisk ratet sett (front eller back), mens en 18-hulls-runde bare trenger minst 10 av 18 (resten fylles med en «expected score», ny metode fra 2024 som erstattet den gamle «net par»-metoden). Dette betyr også at fritt starthull (Beslutning E) fungerer fint for vanlig logging, men en runde blir kun HCP-tellende hvis de spilte hullene faktisk samsvarer med banens ratede 18/front-9/back-9 — en vilkårlig 9-hulls-strekning har ingen egen rating.
Fant en presis, tidligere ukjent detalj: en 9-hulls Course Handicap halverer indeksen først (Index÷2 × Slope/113 + (Rating−Par)) — helt annen formel enn 18-hulls-varianten. Viktig: dette gjelder frittstående 9-hulls-runder, ikke det eksisterende front_9/back_9-øktoppsettet i turneringsflyten, som løser et annet problem (slagfordeling internt i en match) og bevisst skal la det være.
Full kjede (Score Differential, Net Double Bogey, beste-8-av-20, Low Handicap Index, soft/hard cap, Course/Playing Handicap) er nå skrevet inn i ADR-033 med eksakte tall fra kilden. PCC og Exceptional-Score-justering er bevisst avgrenset ut av v1 (forstått, men krever data på tvers av alle brukeres runder samme dag — egen, senere runde).
2026-07-22 09:26:08 +02:00
90148c487e Update Todos
Skriv migrasjon 019 (app_user.country + bio)

Backend: profile_complete-felt, ProfileUpdate country/bio/HCP-cap

Frontend: onboarding-visning i /account, gate i page.tsx + dashboard.tsx

Scratch-verifiser hele flyten

Be om bekreftelse og rull ut live

Oppdater CLAUDE.md/FEATURE_BACKLOG.md
Rullet ut live og dokumentert. Neste gang du (eller erol.haagenrud@envide.no) logger inn, blir du sendt rett til «Fullfør profilen din» før du når dashbordet — HCP er forhåndsutfylt med 54, kan ikke settes høyere. Etter fullføring redigeres alt videre via «Konto». Tom-tilstandens andre spørsmål (hva dashbordet skal vise når profilen ER fullført, men ingen organisasjon/turnering finnes) står fortsatt åpent, notert i FEATURE_BACKLOG.md.
2026-07-22 08:00:29 +02:00
79c4406723 Update Todos
Skriv migrasjon 019 (app_user.country + bio)

Backend: profile_complete-felt, ProfileUpdate country/bio/HCP-cap

Frontend: onboarding-visning i /account, gate i page.tsx + dashboard.tsx

Scratch-verifiser hele flyten

Be om bekreftelse og rull ut live
Scratch-verifisert, alt grønt:

Migrasjon 019 kjørte rent (001→019), test_isolation.sql 12/12 uendret.
16/16 backend-sjekker: fersk konto starter profile_complete: false, delvis utfylling forblir ufullstendig, HCP >54 avvist (422), full utfylling (inkl. HCP=54) gir profile_complete: true, beskrivelse er reelt valgfri, å nullstille et obligatorisk felt i etterkant slår profile_complete tilbake til false, full isolasjon mellom to kontoer.
Ekte produksjonsbuild av frontend kompilerte rent, alle 16 ruter listet.
Ekte HTTP-nivå-bevis mot en kjørende produksjonscontainer: anonym mot / → 200 (innloggingsskjema), en ekte innlogget-men-ufullstendig sesjonscookie mot / → 307 → /account.
Klar for ekte teecup_db. Dette krever:

Kjøre 019_profile_country_bio.sql mot ekte teecup_db (kun to nye nullable kolonner på app_user — additivt, ingen eksisterende rader berørt).
docker compose up -d --build teecup_api teecup_frontend.
Verdt å merke: med dette rullet ut vil både hei@erol.no og erol.haagenrud@envide.no bli sendt til profil-fullføring ved neste innlogging — ingen av kontoene har disse feltene utfylt i dag (bekreftet med spørringen tidligere).
2026-07-22 07:53:29 +02:00
b376f095be Update Todos
Flytte is_participant-logikk til team_authz.py (unngå sirkulær import)

Widen scoring.py: get_scorecard/submit_hole_score/submit_hole_result/concede_match

Widen matches.py: list_matches/add_participant/remove_participant/lock_lineup

Widen tournaments.py: list_sessions/list_teams/concede_tournament

Widen courses.py: list_holes

Widen messaging.py: team chat REST-endepunkter (list/send/delete)

Legge til my_session_id/my_match_id i /auth/me sin my_tournaments

Frontend: legge til lenker til lag-chat/scorekort fra «Mine runder»

Scratch-verifisere hele deltaker-tilgang-runden (positive + negative kontroller)

Ekte typesjekket frontend-produksjonsbuild + backend py_compile på nytt før deploy-forslag

Presentere plan, deploye og oppdatere .md-filer for deltaker-tilgang-runden

Bygge og scratch-verifisere sekundær e-postadresse (migrasjon 017)

Bygge HCP-historikk over tid
Sekundær e-postadresse (det enkle tilfellet) er bygget og scratch-verifisert (20/20 sjekker), test_isolation.sql fortsatt 12/12.

Hva er bygget:

Migrasjon 017_secondary_email.sql — to nye tabeller (secondary_email_token, user_secondary_email), samme bevis-eierskap-token-mønster som ADR-032.
Backend: POST /auth/secondary-email (send bekreftelseslenke), POST /auth/secondary-email/confirm (bekreft, ingen sesjon påkrevd), DELETE /auth/secondary-email/{id}. Viktigst: verify_magic_link og login_with_password løser nå en sekundær adresse til den eksisterende eierens konto i stedet for å opprette en ny, separat konto — dette er selve poenget med funksjonen.
Frontend: ny seksjon "Andre e-postadresser" i /account (ikke dashbordet — se merknad under), /verify-email håndterer nå både e-postbytte og ny-sekundær-adresse via en ?kind=secondary-parameter.
Én bevisst plasseringsavgjørelse jeg tok uten å spørre: du sa opprinnelig at hele multi-e-post-flyten burde skje "fra dashboard-siden". Jeg la likevel dette i /account, fordi jeg her kun bygger det enkle tilfellet (fri adresse) — konsistent med hvor e-postbytte (ADR-032) allerede ligger. Når/hvis den harde saken (ekte konto-sammenslåing, der data faktisk "dukker opp") bygges senere, er dashbordet trolig riktigere siden gevinsten vises der. Si fra hvis du vil at den skal flyttes allerede nå.

Verifisert grundig: ny sekundær-adresse legges IKKE til før bekreftet; token kan ikke gjenbrukes; adresse som allerede er en annens hovedadresse ELLER en annens sekundæradresse avvises tydelig; innlogging (magic-link OG passord) via sekundæradressen løses korrekt til samme, eksisterende konto; en fremmed kan ikke slette andres sekundæradresse; og — kritisk — etter sletting oppretter en ny innlogging på den adressen en helt ny, separat konto (beviser fjerningen er reell).

Ingen migrasjon kjørt mot ekte teecup_db ennå.
2026-07-22 06:14:31 +02:00
df08339654 Update Todos
Flytte is_participant-logikk til team_authz.py (unngå sirkulær import)

Widen scoring.py: get_scorecard/submit_hole_score/submit_hole_result/concede_match

Widen matches.py: list_matches/add_participant/remove_participant/lock_lineup

Widen tournaments.py: list_sessions/list_teams/concede_tournament

Widen courses.py: list_holes

Widen messaging.py: team chat REST-endepunkter (list/send/delete)

Legge til my_session_id/my_match_id i /auth/me sin my_tournaments

Frontend: legge til lenker til lag-chat/scorekort fra «Mine runder»

Scratch-verifisere hele deltaker-tilgang-runden (positive + negative kontroller)

Ekte typesjekket frontend-produksjonsbuild + backend py_compile på nytt før deploy-forslag

Presentere plan og be om bekreftelse før utrulling mot ekte teecup_db/containere

Bygge sekundær e-postadresse (enkelt tilfelle, ADR-032-mønster)

Bygge HCP-historikk over tid
Deltaker-tilgang til lag-chat/scorekort er bygget og grundig scratch-verifisert (43/43 sjekker, test_isolation.sql fortsatt 12/12). Kort oppsummert hva som er gjort:

Backend — den blanke org-medlemskaps-sperren (get_authorized_org) er fjernet fra ni endepunkter (lag-chat lese/skrive/slette, scorekort-lesing, slag/hull-resultat-innsending, walkover på match- og turneringsnivå, match-/lag-/økt-listing, bane-hull) og erstattet med de faktiske, allerede eksisterende autorisasjonssjekkene (user_is_rostered_on_team, user_is_match_participant, user_is_team_captain — alle uendret) — pluss et nytt eksplisitt org-medlem ELLER turnering-deltaker-OR på de endepunktene som tidligere ikke hadde noen finkornet sjekk i det hele tatt (der en ren fjerning ville åpnet dem for enhver innlogget bruker). /auth/me viser nå også my_session_id/my_match_id per rad i "Mine runder".

Frontend — "Mine runder"-kortet har fått to nye handlingslenker: "Lag-chat" (alltid) og "Scorekort" (når spilleren har en aktiv match).

Verifisert grundig: en rostret spiller UTEN organisasjonsmedlemskap får nå riktig tilgang til alt dette; en helt fremmed bruker avvises fortsatt overalt; org-eier beholder full tilgang som før; lag-chatten er fortsatt ekte privat (org-eier fortsatt avvist der, med vilje); kryss-org-isolasjon holder; og en rostret-men-ikke-kaptein spiller ble korrekt avvist fra walkover (fant samtidig en eksisterende, dokumentert fallback-oppførsel — et lag uten utpekt kaptein godtar enhver rostret spiller — som viste seg å fungere akkurat som tiltenkt).
2026-07-22 05:46:47 +02:00
3f888f1e10 De to gjenværende UI-hullene fra 2026-07-19-runden (ingen vei til å opprette en ANDRE organisasjon, og intet sammendrag for "alle runder har dato") er de mest opplagte å ta først — begge er ferdig diagnostisert, null designtvil, og rene tilføyelser i frontend uten backend-endring.
Det jeg egentlig vil trekke frem som det strategisk viktigste, er derimot deltaker-tilgang til lag-chat og scorekort uten org-medlemskap — den naturlige fortsettelsen av dagens ADR-031-arbeid («Mine runder» viser nå turneringen, men en ren spiller kan fortsatt ikke åpne laget sin chat eller scorekortet derfra, siden begge fortsatt krever get_authorized_org). Tradeoffen: det er en bredere og mer risikofylt endring enn dagens papirkutt, siden get_authorized_org brukes av dusinvis av endepunkter — bør gjøres som en egen, forsiktig gjennomgått runde, ikke tas i forbifarten.
2026-07-21 09:03:52 +02:00
45850a97fa Live og dokumentert. /dashboard er nå den ene, felles adressen for enhver innlogget bruker — organisator, spiller, eller begge — med personlig profil (inkl. e-post og mobil) redigerbar på /account. 2026-07-20 11:32:10 +02:00
b042a18a45 Live og dokumentert. "Mine runder" og personlig profil (inkl. profilbilde) er nå tilgjengelig for enhver innlogget bruker på /dashboard og /account. 2026-07-20 10:50:42 +02:00
3dd6224bfd Update Todos
Migrasjon 015: app_user-profilfelt + player_organizations_for_user()-bro

Backend: utvid Me + PATCH /auth/profile + avatar-opplasting/sletting

Backend: 'mine runder'-data + check_visibility-utvidelse for deltakere

Frontend: profil-seksjon i /account

Frontend: 'Mine runder'-seksjon + betinget tom-tilstand i dashboard.tsx

Scratch-verifisere alt (15 sjekker bestått)

Typesjekket frontend-build

ADR-031 + .md-oppdatering
Bygget og scratch-verifisert (15 automatiserte sjekker). Oppsummering:

Personlig profil — nye felt på selve kontoen (ikke på org-ens spillerdata, det er bevisst holdt atskilt siden en person kan ha ulike spiller-rader i ulike klubber): profilbilde, fornavn, etternavn, fødselsdato, kjønn, HCP, hjemmeklubb. Redigeres i en ny seksjon på /account. Sletting av enkeltfelt fungerer (send tomt/null), profilbilde kan lastes opp og fjernes.

"Mine runder" — ny seksjon øverst på dashbordet, viser turneringer du er rostret i på tvers av alle organisasjoner, uavhengig av om du er medlem noe sted.

Et reelt sikkerhetshull jeg fant underveis, ikke antatt på forhånd: da jeg testet "Mine runder" mot en faktisk ren spiller (ingen organisasjonsmedlemskap), oppdaget jeg at synlighetsregelen kun ga deltakere tilgang for det strengeste synlighetsnivået — ikke for standard-nivået («org»), som er det ALLE nye turneringer får automatisk. En ren spiller ville altså vært låst ute av sin egen, helt normale turnering. Fikset og verifisert grundig at det er en ren utvidelse: en fremmed innlogget bruker og en anonym leser blir fortsatt korrekt avvist som før.

Bevisst utenfor omfang, tydelig flagget: "Mine runder" lenker til den offentlige turnering-siden, ikke til lagets private chat eller scorekortet ennå — de krever fortsatt ekte organisasjonsmedlemskap, en strengere sperre brukt bredt i hele appen som jeg ikke ville endre uten en egen, forsiktig runde. Notert som naturlig neste steg.

Ingen kode for punkt 2 (midlertidige spillere) i denne runden, som avtalt.
2026-07-20 10:41:30 +02:00
16f3a163c1 Update Todos
Diagnostisere dashboard-dato-bug (allerede kjent, bekreftet på nytt)

Fiks: utled turnering-datospenn fra øktenes scheduled_at i list_tournaments

Bygg PATCH /orgs/{id}/players/{id} (rediger spillerpool)

Bygg frontend: Rediger spiller-skjema i tournament-detail.tsx

Scratch-verifisere begge fiksene

Typesjekket frontend-build

Oppdatere .md-filer + be om utrullingsbekreftelse
Logikken bak "Ingen datoer satt": dashbord-kortet leser et helt eget felt på selve turneringen (start_date/end_date), atskilt fra øktenes scheduled_at som Program-fanen viser. Ingen UI har noensinne satt det feltet, så det var alltid tomt — uavhengig av at "11. juli" faktisk var satt på øktene. Fikset: kortet henter nå datospennet fra øktene i stedet (11.–12. juli her, siden du har to økter samme dag).

Rediger spiller: bygget. Ny "Rediger spiller" i "⋮"-menyen på hver spiller — navn, HCP og kjønn kan endres. Én viktig presisering vist rett i skjemaet: dette endrer spilleren i poolen (gjelder fremtidig rostring), men endrer ikke HCP-tallet som allerede er frosset på et lag i en turnering (det er bevisst, for at et allerede spilt/pågående oppgjør ikke skal endre seg i etterkant). Skal du rette et tall som allerede vises på et lag, må du fortsatt fjerne og legge til spilleren på nytt — si fra om du vil at jeg bygger en direkte "rett dette laget sitt tall her og nå"-vei også.

Begge deler er scratch-verifisert (9 automatiserte sjekker, inkludert at frysing-regelen fortsatt holder) og typesjekket bygget. Ingen migrasjon.
2026-07-20 10:01:44 +02:00
a5de225afe Update Todos
Diagnostisere HCP-bug mot ekte data (gjort)

Fiks 1: filtrer valgte spillere bort fra listen (blind draw)

Fiks 3: tallvelger for slagregistrering (scorekort)

Fiks 4: hardkode full_18-scope i handicap-utregning (bekreftet bug)

Punkt 2: migrasjon 014 + kode (courses.py, handicap.py, matches.py, tournaments.py, frontend)

Scratch-verifisere punkt 2 (fletting, import, validering, remap)

Skrive ADR-029 + oppdatere FEATURE_BACKLOG.md

Rulle ut mot ekte teecup_db + containere, oppdatere .md-status

Notere PDF-ressursene i CLAUDE.md/FEATURE_BACKLOG.md + minne
Alt er rullet ut og verifisert:

Migrasjon 014 kjørt mot ekte teecup_db: Tjømes 8 tee-rader slått sammen til 4 fysiske utslag, alle ratinger og match_participant-referanser intakte (bekreftet med en direkte spørring — 0 brutte referanser).
Begge containere redeployet (teecup_api, teecup_frontend), boot-et rent, /health/dashboard → 200, teeoff.no upåvirket.
Alle fire tilbakemeldingene dine er dermed løst og live.

PDF-ene er notert i CLAUDE.md sin "Autoritative kilder"-seksjon (leses nå ved starten av hver økt) og i FEATURE_BACKLOG.md sitt punkt om de fire nye turneringsformatene, siden det er der de trolig blir mest relevante først. Jeg la også inn en tilsvarende referanse i min egen tvers-av-økt-hukommelse, slik at jeg husker å lese dem selv i en fremstidig, separat samtale om dette prosjektet.
2026-07-20 09:06:25 +02:00
52e0cfaaf9 Update Todos
Diagnostisere HCP-bug mot ekte data (gjort)

Fiks 1: filtrer valgte spillere bort fra listen (blind draw)

Fiks 3: tallvelger for slagregistrering (scorekort)

Fiks 4: hardkode full_18-scope i handicap-utregning (bekreftet bug)

Punkt 2: migrasjon 014 + kode (courses.py, handicap.py, matches.py, tournaments.py, frontend)

Scratch-verifisere punkt 2 (fletting, import, validering, remap)

Skrive ADR-029 + oppdatere FEATURE_BACKLOG.md

Presentere full plan og be om bekreftelse (ekte migrasjon + deploy)
Alle fire punkter er nå bygget og grundig scratch-verifisert. Oppsummering før jeg ber om bekreftelse på å rulle ut mot ekte systemer:

1 — Spillerliste: Fikset. Valgte spillere filtreres nå bort i stedet for å bare vises gråtonet.

3 — Tallvelger: Fikset. Ny StrokePicker (1–9, med utvidbar "10+"→10–19).

4 — HCP-bug: Bekreftet ekte kodebug (ikke bare synlighet). Jeg leste ekte produksjonsdata for testøkten din: front_9 + foursome, og alle fire deltakerne hadde NULL i handicap-feltene. Årsak: handicap-utregningen lette etter en tee-rating scopet til øktens hole_config, men slike rader lages i praksis kun med full_18-omfang — så den fant aldri noe for en front_9-økt. Din beskrevne formel (kombinert hcp/2, laveste side til 0 mottatte slag, resten fordelt fra stroke index 1) var allerede riktig implementert — bugen var at den aldri kjørte. Fikset og verifisert: identisk bruttoscore på begge sider ga nå et ikke-delt resultat, som beviser at hcp faktisk brukes.

2 — Tee/kjønn: Du hadde helt rett i presiseringen din — dette var større enn jeg først trodde. Kjønn er nå flyttet fra selve utslaget til ratingen (ny migrasjon 014_tee_gender_to_rating.sql), tee-valget i blind draw er blitt helt automatisk (ingen kjønnsvelger lenger), og manglende kjønn/rating avvises tydelig i stedet for å gjettes. Fikk egen ADR-029. Verifisert i fem separate runder, inkludert mot ekte teeoff-data (Borregaard) og en gjenskaping av akkurat Tjøme-mønsteret.

Bifunn, ikke fikset: en liten, urelatert 500-krasj (stroke-registrering på en bane uten registrerte hull) — vil du at jeg tar den også, eller lar den ligge som egen sak?

Utrullingsplan — dette er første gang i denne runden noe rører ekte data:

Migrasjon 014_tee_gender_to_rating.sql mot ekte teecup_db — slår sammen Tjømes 8 tee-rader til 4 (bevarer alle ratinger, reparerer alle referanser; mekanisk identisk med det jeg nettopp verifiserte i scratch)
2026-07-20 08:53:53 +02:00
7d911f67d5 Update Todos
Generer PWA-ikoner (gjort)

Bygg manifest.ts + apple-touch/meta i layout.tsx

Bygg service worker (public/sw.js) + offline.html + registrering

Bygg IndexedDB-kø (lib/offline-queue.ts) for offline scoreregistrering

Koble session-scorecard.tsx til offline-kø + banner + optimistisk UI

Skriv ADR-028 + FEATURE_BACKLOG-oppdatering

Typesjekket produksjonsbuild + kodegjennomgang av offline-flyten

Rulle ut og verifisere live + oppdatere .md-status
Ja, det er notert. PWA er live og verifisert (/health, /dashboard, manifest, service worker og ikoner alle svarer riktig over ekte https, teeoff.no upåvirket).

Det viktigste punktet du ba om å få notert — at jeg ikke har testet offline-flyten i en ekte nettleser, kun via kodegjennomgang og produksjonsbuild — ligger nå øverst i CLAUDE.md sin "Neste steg"-liste og i FEATURE_BACKLOG.md sin PWA-tabell, med konkret fremgangsmåte for hva du bør sjekke (åpne scorekort → DevTools offline-modus → registrer slag → skru nettet på → bekreft synk).
2026-07-19 23:54:19 +02:00
a32b8027f3 PWA er bygget og scratch/build-verifisert. Status:
Bygget:

Installerbar app: app/manifest.ts, appleWebApp-metadata for iOS, service worker (public/sw.js, håndskrevet — ingen next-pwa-avhengighet), public/offline.html.
Ikoner: enkelt grønt golf-flagg generert programmatisk (måtte omgå at verken PIL, rsvg-convert eller ImageMagick fantes i miljøet — løste det med et scratch npm-oppsett av sharp). Midlertidig, notert i FEATURE_BACKLOG.md for senere erstatning, slik du ba om. Erstattet samtidig den gamle apple-icon.png som faktisk var v0.app sin generiske plassholderlogo, ikke TeeCup-merkevare.
Full offline scoreregistrering: ny lib/offline-queue.ts (IndexedDB-kø) koblet inn i scorekort-skjermen. Slag/hull-resultat registrert offline vises umiddelbart som "Lagret lokalt · venter på synk", synkes automatisk når nettet er tilbake (pluss en manuell "Synkroniser nå"-knapp). Se ADR-028 for alle designvalgene (bl.a. hvorfor køen ligger i klientkoden og ikke i service workeren, og hvorfor jeg bevisst unngikk Background Sync API — iOS Safari støtter den ikke).
Viktig å være ærlig om: jeg har ingen nettleser-verktøy tilgjengelig i denne økten, så offline-flyten er verifisert med typesjekket produksjonsbuild + en kort container-boot (curl mot manifest/service worker/ikoner — alle svarer riktig), men ikke faktisk testet i en ekte nettleser (Chrome DevTools sin Offline-bryter, ordentlig "Legg til på hjemskjerm"). Anbefaler sterkt at du selv tester scorekort-siden med DevTools offline-modus før dere stoler på det i skarp bruk.

De fire UI-hullene du meldte inn er dokumentert i FEATURE_BACKLOG.md/CLAUDE.md med root cause (ikke bare notert som klager) — den mest presserende er /orgs/{id}/members, som er en reell rewrite/dynamisk-rute-kollisjon: siden er helt utilgjengelig i dag fordi Next.js sin /orgs/:path*-proxy-regel fanger kallet før selve siden noensinne nås.

Ingen migrasjon i denne runden — kun teecup_frontend trenger redeploy.
2026-07-19 23:51:08 +02:00
09aaa38bde Alt scratch-verifisert (5 automatiserte sjekker inkl. faktisk sanntidsmottak over WebSocket for både score-innsending og walkover), typesjekket build OK. Ingen migrasjon, ingen ny Caddy-rute (gjenbruker /ws/* fra sist). 2026-07-19 23:14:17 +02:00
bfd9633c63 Update Todos
Refaktorere get_leaderboard til delt fetch_leaderboard()

Gjøre own_team_ids null-sikker for anonyme/uinnloggede tilskuere

Refaktorere list_matches og get_scorecard til delte funksjoner

Legge til offentlige leaderboard/matches/scorecard-endepunkter i registration.py

Skrive ADR-026 (tilskuer-rolle)

Scratch-verifisere backend

Bygge frontend: offentlig live-visning (leaderboard + matcher + scorekort) på /t/[id]/live

Ekte typesjekket frontend-build

Deploy etter bekreftelse + oppdatere .md-filer
Backend og frontend er scratch-verifisert (16 automatiserte sjekker, inkl. en presis test av tenant-vs-sti-sikkerhetssjekken). Ingen migrasjon denne runden — ren backend-refaktorering + nye endepunkter + ny /t/[id]/live-side. Ingen Caddy-endring nødvendig (dekkes av eksisterende /public/*-proxy)
2026-07-19 22:51:07 +02:00
6774cec72b Kommunikasjon er live — det største enkeltløftet i prosjektet så langt:
Lag-chat («det hemmelige rommet»), tilgjengelig via en ny chat-knapp på hvert lagkort i lag/spillere-skjermen — ekte privat, org-eier/admin har ikke tilgang (verifisert helt ned til selve WebSocket-håndtrykket, ikke bare REST).
Offentlig runde-feed («Banter Board»), ny seksjon nederst på turneringens offentlige side — gjenbruker eksisterende synlighetsnivåer, men posting krever innlogging + tilknytning til turneringen/organisasjonen.
Bilder i begge, sanntid via WebSockets i begge.
Underveis: fant at Next.js ikke proxyer WebSocket-oppgraderinger pålitelig, løst med en egen Caddy-rute rett til API-et (samme mønster som media-ruten fra MinIO-runden). Alt scratch-verifisert grundig (20 automatiserte sjekker inkl. faktisk sanntidsmottak over en åpen WebSocket, ikke bare REST-svar), og bekreftet på ekte produksjon med et reelt wss://-håndtrykk over https.

Viktig å huske til neste økt: Caddy-endringen ligger uncommitted i det separate /opt/teeoff-repoet — samme fallgruve som tidligere Caddy-runder.

Alt er dokumentert i .md-filene. Naturlig neste kandidat er tilskuer-rollen (som Kommunikasjon-arbeidet nå gjør mulig å definere skikkelig), men si fra hva du vil prioritere.
2026-07-19 22:33:13 +02:00
20ae4fe6ea Backend, frontend og Caddy-endringen er alle klare og verifisert (Caddy-syntaksen validert OK). Dette er en stor runde — her er full plan for utrulling:
1. Migrasjon — kjør 013_messaging.sql mot ekte teecup_db (ny message-tabell, RLS, ingen endring av eksisterende data).

2. Backend + frontend — docker compose up -d --build teecup_api teecup_frontend.

3. Caddy — legger til /ws/*-ruten i /opt/teeoff/deploy/Caddyfile (allerede skrevet og syntaks-validert). Som i alle tidligere runder som har rørt denne filen: en graceful reload plukker historisk IKKE opp endringen (stale bind-mount-inode), så det trengs en full docker restart teeoff_caddy — det gir noen sekunders nedetid for teeoff.no også, ikke bare teecup.teeoff.no.

Etter alt dette: sjekke /health + /dashboard → 200, en reell WebSocket-tilkobling fungerer over wss://teecup.teeoff.no/ws/..., og teeoff.no er tilbake på 200.
2026-07-19 22:26:45 +02:00
c3cca377ed pdate Todos
Legge til visuell hint på øktkort ("Sett opp flights") i program-skjermen

Avklare designbeslutninger for Brukerroller med bruker

Skrive team_authz.py på nytt (kaptein-only + match-deltaker-sjekk)

Oppdatere matches.py til å bruke user_is_team_captain

Oppdatere scoring.py til å bruke user_is_match_participant

Håndheve 'kun én kaptein per lag' i tournaments.py PATCH/POST roster

Sjekke ekte teecup_db for lag uten kaptein / med flere kapteiner (kun lesing)

Skrive ADR-023 for Brukerroller-beslutningene

Sette opp scratch MinIO + engangs API-container

Kjøre autorisasjonstester (kaptein/deltaker) mot scratch-API-et

Rydde opp scratch-infrastruktur

Ekte typesjekket frontend-build (øktkort-hint)

Deploy etter eksplisitt bekreftelse + oppdatere .md-filer

Live og verifisert. Oppsummert:

Øktkort-hint: "Sett opp flights og lås oppstilling →" vises nå tydelig på hvert øktkort i Program-fanen.

Brukerroller (ADR-023):

Kaptein er nå en reell autorisasjonsrolle — kun kaptein (eller org-eier/admin) kan legge til/fjerne deltakere og låse laget. Har et lag ingen utpekt kaptein ennå (som "De Unge" har akkurat nå — sjekket mot ekte data før utrulling), gjelder samme åpne tilgang som før, så ingen ble låst ute av endringen.

"Kun én kaptein per lag" håndheves nå — å utpeke en ny kaptein fjerner automatisk merket fra forrige.

Score føres nå kun av matchens faktiske deltakere (eller org-admin), ikke lenger "hvem som helst på laget" — uavhengig av kapteinmerket.

Fant og fikset en reell 500-bug under scratch-testing (enum/tekst-sammenligning i SQL) før noe nådde produksjon.

Alt scratch-verifisert (15 automatiserte sjekker + test_isolation.sql 12/12), typesjekket produksjonsbuild kjørt, deployet uten migrasjon, teeoff.no upåvirket.

Naturlig neste steg nå som brukerroller er avgjort: walkover/konsesjon (ventet tidligere nettopp på dette) kan tas fatt på — men si fra hva du vil prioritere.
2026-07-19 11:46:33 +02:00
a216e3945a Update Todos
Legge til argon2-cffi, pyotp, qrcode i requirements.txt

Skrive migrasjon 012 (passord, 2FA, superadmin, org-invitasjoner)

app/auth.py: sesjonsstadier, passord-hashing, TOTP-hjelpere

app/routers/auth.py: passord-innlogging, 2FA-oppsett/verifisering

app/email.py: 2FA-kode og invitasjons-maler

app/routers/organizations.py: invitasjoner, medlemskapsstyring, superadmin-sti

Frontend: login-form passord-modus + 2FA-skjermer

Frontend: kontoinnstillinger + org-medlemsstyring-skjerm

Ekte typesjekket frontend-build

Scratch-verifisere hele auth-løpet grundig (backend)

Deploy mot ekte teecup_db/containere + oppdatere .md-filer
ADR-021 (passord/2FA) og ADR-022 (org-eierskap) er live. Kort oppsummert:

Nytt i innloggingen:

Passord (valgfritt tillegg til magic-link) — Argon2id, testet med ekte spesialtegn/mellomrom/æøå
2FA — TOTP eller e-post-engangskode, brukerens eget valg
Påkrevd 2FA for org-eiere/administratorer, valgfritt for andre
Ny /account-skjerm for å sette passord og styre 2FA
Nytt for organisasjoner:

Inviter andre på e-post til enhver rolle (eiere) eller kun medlem (administratorer)
Frasi deg eierskap selv, eller fjern andre medlemmer — med vern mot at en organisasjon står igjen uten eier
Superadmin-flagg (kun manuelt satt i databasen, aldri via API) som kan sette eierskap på hvilken som helst organisasjon
Ny /orgs/[id]/members-skjerm, lenket fra dashbordet
Fant og fikset tre reelle bugs underveis i scratch-testingen (ingen nådde produksjon) — en krasj i selve innloggingen og to tilfeller av en uendelig 2FA-løkke. Alt er nå verifisert grundig og rullet ut, eksisterende sesjoner er upåvirket.
2026-07-19 10:40:15 +02:00
73f3c4d1ea Fikset og live. Rot-årsaken var altså en manglende sjekk i frontend, ikke noe galt med selve sesjonen eller cookien din — verifisert direkte med din ekte cookie mot produksjon (uten cookie → skjema, med din cookie → sendt rett til /dashboard).
.md-filene er oppdatert: sesjons-bugen er markert  fikset, og ADR-021 (passord/2FA) er notert som naturlig neste steg i den tråden når du vil sette i gang — jeg venter på ditt klarsignal før jeg begynner å bygge det.
2026-07-19 10:05:42 +02:00
317e24a800 Alt er ferdig og live. Kort oppsummering av hele runden:
Backend (ADR-020):

tournament.join_code — kort, unik kode generert automatisk, overstyrer synlighet
match.leading_side — cachet ledende side, oppdateres ved hvert hull
Leaderboardet fikk projected_points — hva stillingen blir om pågående matcher holder seg
Ny migrasjon 011, kjørt mot ekte teecup_db, test_isolation.sql 12/12
Frontend:

Login-skjermen har nå et kode-felt som tar deg rett til turneringen, uten innlogging
Invitasjonskoden vises i turnering-detalj med kopier-knapp
Leaderboardet har to fargesegmenterte barer øverst — faktisk stilling og projisert stilling
Matchlisten i blind draw er fargekodet etter hvem som leder
Underveis oppsto en reell hendelse: en feilformulert kommando eksponerte teeoff_db sitt superbrukerpassord. Det ble flagget umiddelbart, du valgte å rotere det, og det ble gjort trygt uten at verdien noensinne ble vist på nytt — bekreftet med rene logger og 200 på både teeoff.no og teecup.teeoff.no etterpå.

Alt er verifisert i scratch før utrulling, typesjekket build kjørt, og .md-filene (CLAUDE.md, FEATURE_BACKLOG.md, ARCHITECTURE_DECISIONS.md) er oppdatert. Jeg kommuniserer på norsk videre i dette prosjektet.
2026-07-19 09:33:34 +02:00
8821bbd448 ackend for the join-code, leading_side, and projected-standings work is fully verified against a fresh scratch database (migrations 001–011, test_isolation.sql 12/12, and live end-to-end checks: join-code generation/uniqueness, code resolution, visibility bypass on both the tournament view and registration — including case-insensitivity and rejection of a wrong code — plus a full hole-by-hole match simulation confirming leading_side/status_text stay in sync through "1 UP" → "AS" → a decided "9&7", with the leaderboard's projected points matching at each stage: 1.0/0.0 while A led, 0.5/0.5 at all-square, and settling to equal actual/projected once decided).
Ready to deploy to the real system:

Migration: 011_join_code_and_leading_side.sql against real teecup_db (adds tournament.join_code — backfills existing tournaments with generated codes — and match.leading_side, plus the public_tournament_by_code() function).
Redeploy: teecup_api only (no frontend changes yet — those come next).
2026-07-19 09:23:35 +02:00
8a95ef8af2 Update Todos
Diffe zip 9 mot live-treet

Integrere rediger/slett i tournament-program.tsx (behold ekte create-flyt, IKKE V0s regresjon)

Ekte typesjekket frontend-build

Rulle ut live

Oppdatere .md-filer + slette zip 9

Rediger/slett-UI for økter er live. Kort oppsummert:

Fanget en reell regresjon i selve V0-eksporten før noe ble tatt inn: denne runden hadde utilsiktet fjernet bane-feltet fra «Legg til økt»-skjemaet (nye økter ville fått en hardkodet mock-bane). Diffet mot live-treet som vanlig, tok kun inn de nye rediger/slett-delene, lot det ekte opprett-skjemaet (med ekte bane-søk/teeoff-import) stå urørt.

Bane-bytte i redigeringsskjemaet er bevisst enklere enn opprett-skjemaets — kun velg blant eksisterende baner eller hent fra teeoff, ingen «opprett ny bane»-snarvei, som unngår at samme forvekslingsfelle fra Tjøme-hendelsen kan skje igjen.

Verifisert med ekte PATCH/DELETE-kall (inkludert at 409-feilmeldingen fra backend vises riktig i UI-et), test_isolation.sql 12/12, typesjekket build.

.md-filene oppdatert, zip 9 slettet.

Alt fra "bygg i rekkefølgen ting brukes"-serien pluss denne rundens opprydninger er nå live og konsistente.
2026-07-19 08:17:12 +02:00
459f3f8e14 Backend er live og grundig verifisert med nøyaktig scenarioet du beskrev (10 hull spilt under feil bane, matchen avgjort, rettet til riktig bane — tee-er byttet, handicap regnet på nytt, matchstatus oppdatert, de faktiske slagene urørt). .md-filene er oppdatert.
Ikke bygget ennå: selve rediger-/slett-knappene i program-skjermen — det er ren backend-kapasitet nå. Vil du at jeg skriver en V0-prompt for det, eller er det noe annet du vil ta fatt på?
2026-07-18 22:21:22 +02:00
d51c0153bb Update Todos
Diffe zip 8 mot live-treet

Integrere tournament-leaderboard.tsx mot ekte API

Legge til Leaderboard-fane i program- og roster-skjermen

Ekte typesjekket frontend-build

Rulle ut live

Oppdatere .md-filer + slette zip 8
Leaderboard-skjermen er live, og hele "bygg i rekkefølgen ting brukes"-serien er komplett: oppsett (lag/roster) → program → blind draw → scorekort → leaderboard, alle live og verifisert. Leaderboard-fanen er nå med i alle turnering-skjermenes fanerad. .md-filene er oppdatert, zip 8 slettet.

Gjenstående i backloggen, ingen haster spesielt:

PWA (manifest, service worker, offline-cache) — ikke startet
Kommunikasjon (lag-chat/offentlig feed) — ikke startet
Noen åpne beslutninger (walkover/konsesjon, sanntid vs. polling, tilskuer-rolle) som venter på egne avklaringsrunder
2026-07-18 18:22:10 +02:00
21196c9cfd Update Todos
Diffe zip 7 mot live-treet

Integrere session-scorecard.tsx mot ekte API

Lenke fra blind draw/program til scorekort-siden

Ekte typesjekket frontend-build

Scratch/manuell verifisering av hele skrive-flyten

Rulle ut live

Oppdatere .md-filer + slette zip 7
Scorekort-skjermen er live. Oppsummert:

Ett hull i fokus om gangen, store steppere for slag-modus, tre-valgs vinnerknapper for hullresultat-modus, hull-navigasjon med registrert-markering, kollapsbar full oversikt, og et feiret «avgjort»-banner som låser alt read-only
Lenket inn fra blind draw sin avslørte visning
Ingen nye backend-hull denne runden — forrige rundes forarbeid dekket alt
Verifisert med en test som speiler frontend-ens egen last-sekvens nøyaktig, test_isolation.sql 12/12, ekte typesjekket build
.md-filene oppdatert, zip 7 slettet
2026-07-18 17:47:33 +02:00
02247a1e5f Update Todos
Bygg DELETE .../matches/{id}/participants/{id}

Scratch-verifisere DELETE-endepunktet

Integrere session-blind-draw.tsx mot ekte API

Finn+fiks synlighetshull: org-admin så ikke egne tilføyde deltakere

Ekte typesjekket frontend-build

Fikse+verifisere 500-krasj på null handicap_index

Rulle ut live

Oppdatere CLAUDE.md/FEATURE_BACKLOG.md

Slette zip (6) etter fullført integrering
Alt levert og live:

Blind draw-skjermen — /tournaments/[id]/sessions/[sessionId], koblet fra Program-siden
Ny DELETE-endepunkt for å angre et deltakervalg før låsing
Synlighetshull tettet — org-admin så ikke lenger sine egne tilføyelser før reveal (own_team_ids() manglet samme owner/admin-utvidelse som skrive-siden fikk forrige runde)
500-krasjen fikset — manglende handicap-indeks gir nå en ren 400 i stedet for å krasje, med use_handicap=false fortsatt upåvirket
Alt scratch-verifisert i flere runder, test_isolation.sql 12/12, ekte typesjekket build, begge containere redeployet, teeoff.no upåvirket. Zip (6) slettet. .md-filene er oppdatert med hele runden.
2026-07-18 17:15:50 +02:00
a46377e7bc Update Todos
Utvid team_authz.py: org owner/admin får overstyre uten unntak

Oppdater alle 5 kallsteder i matches.py/scoring.py

Scratch-verifisering: org-admin uten roster kan låse/legge til deltakere/score, vanlig member kan ikke, rostret spiller uendret

Rulle ut live + oppdatere statusdokumenter
Live, verifisert, og dokumentert. Klar for å skrive V0-prompten for blind draw-skjermen når du vil — samme mønster som de forrige, og nå med bekreftet organisator-tilgang selv om ingen kaptein har logget inn ennå.
2026-07-18 16:19:52 +02:00
0b6e7e4219 Live nå — kun teecup_frontend redeployet, begge containere friske, teeoff.no upåvirket. Statusdokumentene er oppdatert med rotårsaken (nestet <form> → nettleseren slo sammen skjemaene → «Søk» submittet det ytre økt-skjemaet som ekte sidenavigasjon → vasket bort org-parameteren). 2026-07-18 15:54:40 +02:00
b28f604fe9 Bygget, og verifisert grundig mot ekte infrastruktur — inkludert et ekte kall mot teeoff_api (søkte opp «Borregaard», importerte Borregaard Golfklubb sin 18-hulls hovedbane med alle hull, 4 tee-farger × kjønn, ratinger, og opprettet faktisk en økt med den importerte banen). Duplikat-import ble korrekt avvist (409), kryss-org-isolasjon holder, test_isolation.sql 12/12.
To ting gjenstår, begge mot ekte infrastruktur — vil du bekrefte at jeg går videre?

Migrasjon 010_official_course_unique_ref.sql mot ekte teecup_db — kun én ny partiell unik-indeks (organization_id, external_course_ref), rører ingen eksisterende rader (alle er source='custom' med external_course_ref IS NULL i dag)
docker compose up -d --build teecup_api teecup_frontend — ny backend-kode (courses.py, teeoff_client.py, httpx-avhengighet) + ny frontend-kode (bane-søk mot teeoff i program-skjemaet)
2026-07-18 12:44:05 +02:00
5e4e4af26c Programskjermen er live og verifisert (teeoff.no upåvirket).
Om bekymringen din: sjekket det faktisk fremfor å gjette. Gode nyheter — det er billigere enn ADR-004 lot til å anta:

GET /api/facilities/{slug} i teeoff sin backend/main.py er allerede offentlig, uten auth/API-nøkkel, og returnerer nøyaktig det vi trenger: hull med par+stroke index, tee-navn, og course/slope rating per tee (kjønnsdelt WHS-data)
CORS-listen på teeoff-siden ekskluderer teecups origin, men det er irrelevant — dette blir et server-til-server-kall fra teecup_api til teeoff sin backend, ikke noe nettleseren gjør
Eneste reelle designspørsmål: banen har ingen egen slug, kun facilities.slug (f.eks. borregaard-golfklubb) + en intern bane-id — så course.external_course_ref må bære begge sammen
2026-07-18 12:29:24 +02:00
b566595e85 Program-skjermen er bygget og grundig scratch-verifisert. Kort oppsummert:
Nytt:

app/routers/courses.py — enkel bane-CRUD (GET/POST /orgs/{id}/courses), fant og tettet et reelt hull: SessionCreate.course_id var påkrevd, men ingen vei fantes til å skaffe én
components/tournament-program.tsx + rute /tournaments/[id]/program — tidslinje over økter, opprett-skjema med bane-type-ahead og avanserte handicap-brytere
Fanerad lagt til i både roster- og program-skjermen så du kan bevege deg mellom dem
To reelle feil rettet før integrering:

V0-promptet mitt ba om ett generisk "Scramble"-format, men databasen/motoren krever scramble_2/scramble_4 som atskilte verdier — rettet til to segment-knapper
Verifiserte allowance_override-JSON-formen eksakt mot parse_allowance_config (typet combined/per_player + 0–1-brøk, ikke flat prosent) — bekreftet med en ekte rundtur i scratch, ikke bare lest fra koden
Verifisert: courses opprettet+listet, kryss-org-isolasjon, økt med klokkeslett, økt med scramble_4+full handicap-override-rundtur, gammel "scramble"-verdi korrekt avvist, test_isolation.sql 12/12, ekte typesjekket produksjonsbuild (samme Dockerfile som deployes).
2026-07-18 12:20:45 +02:00
6a977d52f1 Ryddet — hero_image_key er tilbake til tomt, og objektet er faktisk borte fra MinIO (404, ikke bare skjult i DB). "De Gamle er Eldst" er tilbake til slik den var før testen.
MinIO-runden er dermed fullstendig verifisert med ekte produksjonsdata, uten spor igjen. ADR-018 er komplett. Klar for commit når du vil — si fra hva du vil ta fatt på videre.
2026-07-18 11:38:35 +02:00