Commit graph

127 commits

Author SHA1 Message Date
dd974678fa Skjul HCP på offentlig leaderboard for rene bruttoslagspill-turneringer
Bruker: "når det er brutto som er hovedkonkurransen trenger vi ikke se
hcp i leaderboarden" -- HCP er kun meningsfullt der den faktisk brukes
til slagfordeling (netto/stableford/Københavner/BBB), ikke ren brutto/
eclectic-gross. PublicTournamentInfo += scoring_method (manglet før),
leaderboard-raden skjuler nå HCP-teksten når turneringens scoring_method
er stroke_gross eller eclectic_gross. Verifisert mot ekte Klubbmesterskap
2026 (bekreftet stroke_gross) i scratch før utrulling.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-21 20:20:22 +02:00
9fad4b3f38 Offentlig "Følg live" for individuelle turneringer: V0-UI + full kobling
Fullfører ADR-098. Ny components/public-individual-live.tsx (V0-bygget,
presentasjonslaget uendret fra eksporten) koblet til de ekte endepunktene
fra forrige commit. Rettet en reell modellmismatch underveis: V0-mock-en
modellerte hver runde som sitt eget separate leaderboard, den ekte
backend-beregningen er ett samlet, kumulativt turnering-leaderboard --
rundevelgeren styrer nå kun hvilken rundes hull-for-hull som lastes.

Ny offentlig GET .../rounds/{round_id}/participants/{tournament_participant_id}
/holes for hull-for-hull-utvidelsen (egen rute, ikke gjenbruk av
frittstående-runders tilsvarende -- ulik datamodell).

app/t/[id]/live/page.tsx avgjør nå format SERVER-side før noe rendres,
unngår klient-side-feilklassen fra forrige commit helt for denne siden.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-21 19:50:35 +02:00
f207be374f Offentlig "Følg live" for individuelle turneringer: backend + Program-fiks
Org-individuelle turneringer manglet en fungerende offentlig tilskuerside
helt (bevisst utsatt i FEATURE_BACKLOG.md 2026-08-14, "hvis/når etterspurt"
-- nå etterspurt). Denne runden bygger backend-grunnmuren:

- PublicTournamentInfo += format_type (manglet, landingssiden kunne ikke
  skille format offentlig).
- Ny GET /public/tournaments/{id}/rounds -- rundeliste med utledet status
  (ikke startet/pågår/fullført).
- Ny GET /public/tournaments/{id}/individual-leaderboard -- gjenbruker
  _compute_individual_standings uendret, fjerner kun player_id, inkluderer
  HCP (bruker bekreftet eksplisitt).
- Sanntid: broadcast_live_update() koblet inn i _recompute_round_score,
  gjenbruker samme WebSocket-kanal Cup-siden allerede bruker (ADR-027-
  mønsteret), ingen ny WS-infrastruktur.
- public-tournament.tsx sin "Program"-seksjon viser nå rundeliste for
  individuelle turneringer i stedet for en alltid-tom Cup-økt-liste.

Selve "Følg live"-sidens UI (V0) og /t/[id]/live sin format-forgrening
gjenstår -- egen commit når V0-eksporten er klar.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-21 19:44:13 +02:00
1e3ffe634b Ærlig feilmelding for ugyldig kilde-data ved baneimport (EXTERNAL_DATA_INVALID)
Rotårsak for "banen er allerede importert"-forvirringen rundt Tjøme-baner:
teeoffs egen hull-data hadde en duplisert hcp-indeks (13 to ganger, 14
manglet). Manglende validering lot dette komme gjennom og feile stille på
en UNIQUE-constraint, oversatt til den misvisende DUPLICATE-meldingen.
Legger til eksplisitt 1-18-validering før lagring, med en ærlig feilkode/
-melding, i både teeoff- og GolfAPI-import-stiene og alle fire frontend-
kallstedene.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-21 17:11:41 +02:00
546900c2d6 Før endringer i turneringsoppsettet
Some checks failed
Backend-tester / test (push) Successful in 1m8s
Frontend-tester / test (push) Failing after 20s
2026-08-21 13:54:01 +02:00
f1575c9b42 Shotgun-start: backend (migrasjon 088, ADR-096)
Ny start_mode ('consecutive'/'shotgun') på tournament_round + session,
og valgfri start_hole på tournament_round_group + match. Shotgun: alle
grupper/matcher går ut samtidig, sortert etter starthull i stedet for
klokkeslett. Reverserer/utvider migrasjon 084s bevisste "ikke shotgun"
fra 2026-08-18 -- nytt behov oppdaget under utskrift-planlegging.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-21 08:59:48 +02:00
a0163eaa16 Ny runde-veiviseren: tre fikser (overleggsmeny, HCP-overstyring, statistikk-default)
- "Administrer runde"-dialogen lukker seg nå automatisk ved navigasjon
  til "Spillere og runde" (var stående åpen ved samme-rute-navigasjon).
- HCP kan nå overstyres for en kontokoblet medspiller fra første stund
  i veiviseren, ikke bare senere via "Runde og runde". Backend sitt
  add_participant æret aldri en eksplisitt overstyring for user_id,
  ulikt PATCH-endepunktet (ADR-038-avvik, nå rettet).
- Standard statistikknivå for en NY medspiller er nå "Kun slag" i
  stedet for å arve scoreførerens eget valg.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-21 08:05:05 +02:00
544c952cab Kaskader cut-resultatet til alle senere runder (ADR-095)
Overlevere auto-legges til runder etter cut (tee kopiert fra cut-runden),
kuttede spilleres rundedeltakelse fjernes -- med mindre de allerede har
scorer der, da beskyttes dataene av eksisterende cut-sperre i stedet.
Bruker bekreftet eksplisitt: kaskade til ALLE runder, ikke bare neste.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-21 08:04:53 +02:00
5355aba75d Ekte i18n (next-intl) + hjelpeside/FAQ + Spillere-tabellen slått videre sammen (ADR-094)
Grunnmur for oversettelse (cookie-basert, ingen URL-endring), ny
/hjelp-side med oversikt+FAQ på norsk og engelsk, og Deltakere+
Rundedeltakelse slått sammen til én bred tabell i Spillere-steget.
Resten av appens ~2200 strenger og 479 backend-feilkoder er bevisst
utsatt til senere, avgrensede runder -- se FEATURE_BACKLOG.md.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-19 07:54:07 +02:00
5daf2a764a Rundedeltakelse som bulk-tabell i Spillere-steget (ADR-093)
Oppfølger til ADR-092: fant og fikset misvisende "alle er gruppert"-
tekst i Utslagsgrupper-panelet (viste seg egentlig å bety "ingen
deltakere i runden ennå"). Egentlig årsak: å tilordne en deltaker til
en runde var kun mulig ett om gangen, gjemt bak et rundekort. Ny
bulk-tabell i "Spillere" (V0-generert) med sjekkbokser per runde,
kjønn/alder/utslagssted redigerbart samme sted. Nytt PATCH-endepunkt
for å endre utslagssted uten å miste gruppemedlemskap.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-19 06:21:58 +02:00
396fe40b7c Manuell deltakerstatus (DSQ/RTD/DNF/DNS) + spillerpool-kobling (ADR-091)
Ny status-kolonne på tournament_participant, overstyrer leaderboardets
total og blokkerer score i alle runder. Ny direkte lenke fra
turneringens Deltakere-liste til riktig rad i org-spillerpoolen.
Migrasjon 087 lagt til, men IKKE anvendt mot ekte teecup_db ennå.
2026-08-18 18:06:49 +02:00
0c864f0705 Omspill-tiebreak for vinneren + direkte HCP-retting per deltaker (ADR-090)
'playoff' som ny tiebreak_winner_method-verdi -- rangeres som 'none'
(appen kan ikke avgjøre et omspill selv), men regelen vises proaktivt i
Oppsett og som banner på leaderboardet. HCP: la til handicap_index_
snapshot i TournamentParticipantUpdate + inline redigering i
Deltakere-lista, uten å røre allerede frosne runde-verdier. Migrasjon
086 lagt til, men IKKE anvendt mot ekte teecup_db ennå.
2026-08-18 17:29:59 +02:00
18bfe555a0 Gjør turneringsnavn/-datoer PATCH-bare, kartlegg org-oppsett-gapet
name/start_date/end_date manglet helt fra TournamentUpdate. Påmeldings-/
synlighetsfeltene var allerede fullt fungerende på backend (ekte
selvregistrerings-logikk), men uten UI noe sted -- V0-prompt skrevet for
en ny TournamentSettingsCard, ikke bygget ennå.
2026-08-18 16:33:41 +02:00
300cb8aeaf Tiebreak ved likt resultat: countback eller laveste HCP (ADR-089)
Organisator velger metode fritt i Oppsett, uavhengig for vinner og
resten av feltet. Countback er kaskaderende siste 9->6->3->1 hull i
siste runde. Påvirker aldri Cut-grensen -- strukturelt håndhevet, ikke
bare avtalt ved konvensjon. Migrasjon 085 lagt til, men IKKE anvendt mot
ekte teecup_db ennå -- venter på bekreftelse.
2026-08-18 16:29:10 +02:00
9a9fcc84c0 Utslagsgrupper for individuelle turneringer: hvem spiller med hvem (ADR-088)
Tradisjonelt utslag (samme starthull, staggerte klokkeslett med fast
intervall), manuell gruppesammensetning med et forslag å justere, fast
gruppestørrelse. Fire ekte bugs funnet og fikset før utrulling via egen
scratch-verifisering (FK-korrupsjon, str/datetime-mismatch, tidssone,
React state). Migrasjon 084 lagt til, men IKKE anvendt mot ekte
teecup_db ennå -- venter på bekreftelse.
2026-08-18 15:43:39 +02:00
19c527f834 Cut i individuelle turneringer: topp N og delt plass (ADR-087)
Manuelt anvendt (organisator trykker "Anvend cut"), etter et valgt
rundenummer. Kuttede spillere blokkeres fra scoring i senere runder og
vises i egen seksjon på leaderboardet. Migrasjon 083 lagt til, men IKKE
anvendt mot ekte teecup_db ennå -- venter på bekreftelse.
2026-08-18 15:07:21 +02:00
accf5efd41 Spør organisator om merge/overskriv/dobbel ved e-postløs spillerimport
create_players_bulk matchet kun på e-post -- rader uten e-post ble alltid
satt inn på nytt selv om en identisk spiller allerede fantes (ni ekte
dubletter funnet i produksjon). Bulk-endepunktet tar nå et eksplisitt
match_player_id/duplicate_action per rad; frontend oppdager mulige
duplikater (navnetreff, ingen e-post) og spør organisator eksplisitt før
lagring, i stedet for å gjette.
2026-08-18 14:44:42 +02:00
54795065ef Nøytral "ikke startet"-rad + tee-tid/starthull i leaderboardet
Deltakere som ikke har spilt noe ennå fikk feilaktig totalLabel "E"/"0 p"
(til forveksling likt en ekte, jevn score) og en tallfestet sisteplass.
Vises nå nøytralt: total/posisjon null/None, og runde-nivåets tee-tid/
starthull (hvis satt) i stedet for score-cellen.
2026-08-18 14:23:03 +02:00
207750acba Slett en hel turnering, permanent (ADR-086)
Nytt DELETE /orgs/{id}/tournaments/{id}, kun org-eier/admin. Eksplisitt
riktig-rekkefølge-sletting (ikke naiv kaskade) siden to RESTRICT-FK-er
sitter midt inni kaskade-grafen for begge turneringsformater -- verifisert
med fire nye backend-tester mot ekte populerte data. Søppelbøtte-ikon i
begge turnering-headerne med sterk confirm()-tekst.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-18 12:59:37 +02:00
84f11e1a45 Hull-diagram v2: kategoriske venstre/senter/høyre-akser (ADR-084)
Erstatter ADR-083 sin kontinuerlige crossMeters-forskyvning, som ga for
liten synlig venstre/høyre-forskjell på ekte banedata (Tjøme hull 18).
Baner velges nå kategorisk via side_fairway; green/tee/spiller alltid
på senterakse. Ny hazard_group-kolonne (migrasjon 080, ikke rullet ut
mot ekte DB ennå) lar to punkter eksplisitt pares til én carry-hindring
(forkant+bakkant) uten å risikere å slå sammen to atskilte hindringer
på samme side.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-17 23:36:28 +02:00
00809d6817 Massimport av spillere til turneringer (CSV) + redigerbar spillertabell
Ny POST /orgs/{id}/players/bulk (samme e-post-match-dedup-mønster som
selvregistreringens ADR-017 Beslutning B, utvidet til alle felt).
CSV parses klient-side (papaparse), enkel kolonnegjetting, redigerbar
forhåndsvisning før lagring. Dekker både lagturneringer (lagtildeling)
og individuelle turneringer (klassetilknytning) i samme flyt -- begge
steg samlet (org-pool + turneringspåmelding).

Midlertidig hånd-kodet UI (player-import-panel.tsx) bygget for å bevise
hele kjeden ende-til-ende -- venter på V0-eksport for den polerte
visningen før samlet utrulling, samme rekkefølge som FlagPlantSheet.

5 nye backend-tester (111/111 totalt), tsc rent, 45/45 vitest, full
scratch-verifisert i begge turneringsformater.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-17 14:53:55 +02:00
93af7c5bef Rangefinder-koordinater for offisielle (TeeOff-koblede) baner
Rangefinder-funksjonalitet fantes til nå kun for GolfAPI-importerte
personlige baner. Offisielle teeoff-koblede baner (org-turneringer OG
frittstående runder spilt på en ekte teeoff-bane) hadde aldri noen
koordinatkilde. Ny migrasjon 079: delte domener (course_poi_type/
location/side) for å unngå duplisert CHECK-vedlikehold på tvers av
tabeller, ny global tabell teeoff_course_coordinate.

Ny delt modul app/target_points.py + resolve_match_course_key() i
hole_history.py (tredje søster til de to eksisterende bane-bro-
funksjonene) -- alle tre kallesteder (frittstående runder, individuell
org-turnering, lag-matchplay) bruker nå samme CourseKey-abstraksjon.
rounds.py sitt eksisterende endepunkt refaktorert til samme mønster --
sideeffekt: frittstående runder på en ekte teeoff-bane får nå også
rangefinder (var alltid tom liste før).

Ny skrive-vei i courses.py (PUT/GET .../coordinates) -- generell,
gjenbrukbar mulighet for å legge inn koordinater på enhver offisiell
bane, ikke en engangsfiks. HoleTargetDistance generalisert (roundId ->
baseUrl) og wiret inn i begge org-turnering-scoringsflytene.

11 nye tester (106/106 backend totalt), full scratch-verifisert
ende-til-ende i nettleser i alle tre flyter inkl. lys/mørk og
selvskjuling, regresjonssjekk av eksisterende GolfAPI-rangefinder
bekreftet uendret oppførsel.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-17 12:06:47 +02:00
7d28727cb7 Kontosammenslåing, selvbetjent (ADR-080, "Del 2" av flere e-postadresser)
Selvbetjent sammenslåing av to TeeCup-kontoer: keeper (initiativtaker)
ber om sammenslåing, bekreftelseslenke sendt til taperens e-post beviser
eierskap, taperens data (org-medlemskap/spillerkoblinger/runder/venner)
flyttes over og taperens konto slettes. Ny migrasjon 077 (account_merge_
token, ikke kjørt mot ekte teecup_db ennå), ny app/account_merge.py
(N+1-transaksjoner per RLS-grensen, fullt konfliktkart), nye endepunkter
i app/routers/account_merge.py, ny frontend-seksjon i kontoinnstillinger
+ egen bekreftelsesside.

Fant og fikset en reell RLS-relatert bug via testsuiten før produksjon:
seks RLS-beskyttede tabeller var feilaktig plassert i den globale
"trygt å re-peke"-løkken, forårsaket et krasj pga. en Postgres GUC-kvirk
på pooled forbindelser. Se ADR-080 for full begrunnelse.

12 nye tester (95/95 backend totalt), full scratch-verifisert
ende-til-ende inkl. lys/mørk, ekte teecup_db urørt.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-17 07:56:41 +02:00
f740814833 Order of Merit: offentlig/delt visning (ADR-076)
Siste av de tre gjenstående OOM-punktene fra ADR-043 (lag-OOM ADR-074,
eclectic på tvers av turneringer ADR-075, offentlig visning her).

Migrasjon 076: SECURITY DEFINER-bro public_order_of_merit_by_id, samme
anti-enumerering som public_org_by_slug/public_tournament_by_code. Ny
/public/order-of-merits/{id}-endepunkt (gjenbruker den eksisterende
leaderboard-beregningen direkte). Ny uautentisert frontend-side
modellert på public-club.tsx, "Del offentlig lenke" i innstillinger.

83/83 backend-tester, 45/45 vitest, scratch-verifisert i egen inkognito-
nettleserkontekst (ingen session-cookie). Migrasjon vist og bekreftet
før kjøring mot ekte teecup_db. Rullet ut.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-15 21:20:23 +02:00
fe13a82009 Order of Merit: eclectic-aggregering på tvers av lenkede turneringer (ADR-075)
Sesong-"drømmerunde" -- beste resultat per hull på tvers av ALLE lenkede
turneringer (stableford/brutto/netto), med samme-bane-håndheving ved
lenking og modus-bytte. Gjenbruker eclectic_best_per_hole() uendret fra
handicap_engine.py. Frontend: "Eclectic" lagt til i både opprettelses-
skjema og innstillinger, gated til gyldige kind/resultattype-kombinasjoner.

80/80 backend-tester, 45/45 vitest, scratch-verifisert i nettleser
(lys+mørk). Rullet ut.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-15 17:38:00 +02:00
5d502f305a Order of Merit: lag-leaderboard + eclectic-total-bug fikset (ADR-074)
Fikser først en reell bug: en lenket eclectic-scoret turnering bidro med
rå slagsum i stedet for eclectic_total (turneringens faktiske
"drømmerunde"-resultat) i stableford/brutto/netto-OOM-er -- bugen fantes
siden Eclectic-formatet ble bygget (ADR-068), OOM ble aldri revidert.

Bygger deretter lag-OOM sin leaderboard (ADR-043 Beslutning C, skjema
fantes fra migrasjon 055): ny CRUD for team/medlemmer, og leaderboard-
grenen for kind='team' som summerer/velger-beste-N-av medlemmenes
allerede beregnede individuelle OOM-resultater -- samme
order_of_merit_aggregate-kall gjenbrukt på lagnivå med OOM-ens allerede
lagrede aggregeringsvalg. Frontend: fjernet "ikke bygget ennå"-
plassholderen, den eksisterende leaderboard-tabellen var allerede
generisk nok. Ny lag-administrasjonsseksjon lagt til.

Ingen migrasjon. Se ADR-074/CHANGELOG for full detalj og verifisering.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-15 16:52:37 +02:00
bb087b4437 Spillerens per-hull-historikk på tvers av alle runder/turneringer (ADR-072)
Ny delt app/hole_history.py bygger broen mellom frittstående runders og
org-turneringers to ulike bane-identitetssystemer (teeoff facility+course-id
vs. org-scopet course.external_course_ref, og tilsvarende for GolfAPI) --
custom/håndlagde baner ekskluderes bevisst, ordinære baner telles med fra
begge kilder og slås sammen. Turneringssiden håndterer at spilleren kan ha
spilt i flere organisasjoner via samme N+1-per-org-mønster /auth/me
allerede bruker (player_organizations_for_user, migrasjon 015).

To nye GET .../history-endepunkt (rounds.py og individual_tournaments.py)
returnerer samme kombinerte historikk uansett hvilken side som spør. Nytt
HoleHistoryPanel i hole-stat-inputs.tsx viser et ekspanderbart sammendrag
(antall ganger, snitt slag, GIR%, putter) + enkeltinstanser, lagt til i
ScoringWizard og det nye HoleStatsSheet (ADR-071).

Ingen migrasjon -- ren lesefunksjon oppå migrasjon 075. Se ADR-072/
CHANGELOG for full detalj og verifisering (73 backend-tester, inkl.
integrasjonstest som beviser selve bane-broen på tvers av organisasjoner).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-15 06:51:51 +02:00
60ee6a7d16 Full statistikkdybde i org-turneringers hull-scoring (ADR-071)
tournament_round_hole hadde siden opprettelse (migrasjon 040) kun
gross_strokes -- ingen putts/utslag/innspill/bunker/straffeslag-detalj
slik frittstående runder (round_hole) allerede har. Migrasjon 075 gir
turneringssiden samme feltsett + en ny optimistisk-lås-kolonne (endepunktet
var til nå rent siste-skriver-vinner). tournament_participant.stat_level
styrer om HoleGrid åpner det uendrede inline-tallfeltet eller det nye
HoleStatsSheet. NumberPicker/ChoiceRow/DirectionCross/Stepper trukket ut
til en delt hole-stat-inputs.tsx for gjenbruk mellom begge scoringsflytene.

Dette er Steg 1 av to mot spillerens per-hull-historikk på tvers av alle
runder/turneringer -- se ADR-071/CHANGELOG for full detalj og verifisering.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-15 06:32:17 +02:00
a8a2c602ce Utvidet spillerskjema i "Deltakere" -- bla i eksisterende + nye felt (ADR-070)
Migrasjon 074 legger til first_name/last_name/paid/comment på player
(resten av de 11 ønskede feltene fantes allerede, bare ikke eksponert i
denne UI-flyten). AddParticipantControl fikk et "available"-fallback
slik at eksisterende org-spillere vises direkte ved tomt søk (tidligere
kun mulig å opprette ny), pluss et progressivt avslørt skjema for de nye
feltene. Se ADR-070 og CHANGELOG #86 for full detalj og verifisering.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-14 15:08:45 +02:00
dd8a8c133d Offline kommentar-/bildeposting i rundefeeden (ADR-069)
Utvider den eksisterende offline-skrivekøen (ADR-028, hittil kun
hull-scoreføring) til også å dekke rundefeedens kommentarer/bilder.
offline-queue.ts fikk et isMultipart-flagg (Blob-verdier lagres nativt
i IndexedDB, flushQueue bygger FormData ved synk). round-messages.tsx
fikk sin egen isolerte kø (matchId scoped til "{roundId}:messages",
ikke bare roundId) og et optimistisk "Venter på synk"-kort.

Migrasjon 073: round_message.client_message_id (nullbar uuid) + delvis
unik indeks -- POST /messages er ulikt hull-score-PATCH IKKE naturlig
idempotent, så en avbrutt synk kunne duplisert en kommentar uten dette.
Klienten sender en selvgenerert id ved både første forsøk og et evt.
køet gjenforsøk; serveren deduplikerer på den.

Se ARCHITECTURE_DECISIONS.md (ADR-069) og CHANGELOG.md (punkt 85) for
full begrunnelse og verifiseringslogg (inkl. et reload-mens-offline-
scenario som beviser fravær av duplikater).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-14 11:51:30 +02:00
9b7ff8e2ef Eclectic-format for org-individuelle turneringer (Del C) + tre UI-rettelser
Del C (ADR-068, migrasjon 072, siste del av den tredelte utvidelsen som
startet med Flaggturnering GPS/kart, se ADR-066/067): nytt format
eclectic_gross/eclectic_net/eclectic_stableford -- beste resultat per
hull på tvers av en turnerings egne runder, krever samme bane (avvist
tydelig ved rundeopprettelse ellers). Regnes ut ved lesing, ingen nye
tabeller. Bevisst avvik fra opprinnelig plan: integrert som en ny gren
i eksisterende individual-leaderboard-endepunkt fremfor et nytt eget
endepunkt -- se ADR-068 for begrunnelsen.

Tre ikke-relaterte, brukerrapporterte UI-rettelser tatt med i samme
runde: avstandsindikatoren brukte "grønn"/"Midt" i stedet for riktige
golf-uttrykk "green"/"senter", og "Oppdateres live"-badgen fjernet.
"Antall hull"-bryteren i Ny runde-veiviseren fikk samme grønne
aksent-valgt-stil som resten av samme skjerm (delt Segmented-primitiv).

Se ARCHITECTURE_DECISIONS.md (ADR-068) og CHANGELOG.md (punkt 84) for
full begrunnelse og verifiseringslogg.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-14 11:12:25 +02:00
25bdabe3ea Flaggturnering: GPS-flaggplanting (Del A) + kartoversikt (Del B)
Del A (ADR-066, migrasjon 069/070, allerede rullet ut mot teecup_db):
"Plant flagget" via GPS, med en interaktiv "Hullet du ut?"-bekreftelse
før posisjonen registreres, pluss full runde 2+-scoreføring for
spillere som fullfører 18 hull med slag igjen. Ny, isolert overflow-
tabell (rører ikke delt round_hole/tournament_round_hole). Bygget for
både frittstående runder og org-individuelle turneringer. UI-sheeten
er en Claude-skrevet V0-eksport (zip 11).

Del B (ADR-067, migrasjon 071, klar for utrulling): av/på-bryter
(standard AV) for en satellittkartoversikt over ALLE deltakeres
plantede flagg, lap 1 skilt fra lap 2+ med farge+tekstbadge. Frittstående
runder får full tilskuerstøtte (/watch/[id]); org-individuelle
turneringer er bevisst avgrenset til medlemmer/deltakere, siden ingen
offentlig spectator-side finnes for det turneringsformatet ennå.

Se ARCHITECTURE_DECISIONS.md (ADR-066/067) og CHANGELOG.md (punkt 82/83)
for full begrunnelse og verifiseringslogg.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-14 10:38:54 +02:00
0f0ddca7f4 Fullt scorekort (alle stats, matcher Scorekort-siden visuelt) i scorekort-e-posten
Bygget om fra en enkel slag/netto-liste til samme Ut/Inn-blokk-oppsett
med fargede score-merker, fairway/GIR/innspill-glyffer og total-tiles
som selve appens Scorekort-side, etter to runder brukerfeedback
(først "all statistikk", deretter et skjermbilde av ønsket visuell
match). Fant og fikset underveis at round.played_at kun er en dato
(ikke klokkeslett) og en relatert type-bug i spilletid-utregningen.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-14 07:21:03 +02:00
baa1c42d24 Per-deltaker-fullføring av runder + scorekort på e-post; Larvik/Nesbyen via GolfAPI
Backend (ADR-065): round_participant.completed_at (migrasjon 066),
flight-styrt PATCH-tilgang, scorekort-e-post til gjest/lenket bruker
ved individuell fullføring og ved rundefullføring, samt et nytt
on-demand send-scorecard-endepunkt som virker uansett fullføringsstatus.
Frontend-UI kommer i egen runde.

Nye baner Larvik (Seasidebanen) og Nesbyen (manuelt GPS-registrert,
124 punkter) importert til produksjon. Fant og fikset en reell
GolfAPI-datakvalitetsbug underveis: tomme strenger i stedet for
null/fraværende på course rating/slope for begge kjønn (migrasjon
067/068, defensiv parsing + import-endepunkter).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-13 21:24:25 +02:00
410eaa60ae GolfAPI-søk i den primære Ny runde-veiviseren + fiks ruting-bug
Søk-og-koble-UI-en for GolfAPI (ADR-064) var kun koblet inn i "endre
bane"-skjemaet, ikke i /my-rounds/new (components/ny-runde/) -- den
faktiske primære inngangen. Lagt til der (international-search-
delstilstand + InternationalSearch-komponent).

Fant og fikset en reell 500-feil under verifisering: GET
/personal-courses/{personal_course_id} var registrert før den nye,
mer spesifikke GET /personal-courses/international-search -- FastAPI
matcher ruter i registreringsrekkefølge, så den generiske ruten fanget
"international-search" som en ugyldig UUID. Flyttet de nye
endepunktene foran.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-13 07:39:29 +02:00
a9abe86116 Avstand til mål via GolfAPI.io (Tjøme) + statistikk-graf-finpuss
Ny tredje banekilde (ADR-064) for baner utenfor TeeOffs dekning: delt
GolfAPI-cache (migrasjon 065), import til både org-turneringer og
frittstående runder, target-points-endepunkt, og en rangefinder-
visning i scorekortet (V0-generert target-distance.tsx + hånd-koblet
GPS/Haversine-wrapper). Fant og fikset at TEECUP_GOLFAPI_TOKEN aldri
ble videreført til teecup_api-containeren i docker-compose.yml.

I samme runde: y-akse-benevnelser og verdi i begge ender på
statistikk-trendgrafene (rounds-stats-summary.tsx).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-12 21:39:13 +02:00
a65858af84 Statistikk: lineær regresjon i stedet for glidende snitt, trend på alle variabler
Brukeren påpekte (med rette) at det glidende 3-runde-snittet i "Utvikling"
bare gjentok stolpediagrammet med én runde forsinkelse -- for få punkter
til at det smoothet noe reelt. Foreslo tre alternativer via
AskUserQuestion (lineær regresjon / eksponentielt glidende snitt /
kumulativt løpende snitt); brukeren valgte lineær regresjon.

Lineær regresjon (minste kvadraters metode) gir en rett linje --
stigningstallet leses direkte som "endring per runde" og vises nå i
bildeteksten (f.eks. "+7 pp per runde"). Visuelt en helt annen form enn
stolpene (rett strek vs. hakkete stolper), som løser selve klagen.

Bruker ba samtidig om trend på ALLE variabler, ikke bare snitt til par.
Lagt til stolpe+trend for: Fairwaytreff, Greentreff (GIR), Putt/18,
Én-putt, Chip/runde, Bunkerslag/runde, Straffeslag/runde, Anywayslag/
runde -- hver plassert i det eksisterende kortet for akkurat den
metrikken. Scrambling/sand save er unntaket (brukervalg via
AskUserQuestion): for få kvalifiserte hull per runde (0-2) til at et
per-runde-tall er meningsfullt, vises i stedet som én kumulativ linje
("raten din til og med hver runde"), ingen stolper.

Backend: RoundStatsSummary sitt gamle round_series-felt (kun snitt til
par) erstattet av et nytt round_series på RoundStatsWindowSummary-nivå,
med per-runde-tall for alle variabler pluss kumulativ scrambling/sand
save. Fanget og rettet en enhets-bug selv under scratch-verifisering:
scrambling/sand save ble først bygget som 0-1-brøker (kopiert fra en
boolsk 1.0/0.0-sjekk) i stedet for samme 0-100-skala som resten av
API-et -- rettet før commit.

Verifisert: tsc --noEmit rent, 45/45 vitest, 31/31 backend-tester. Full
scratch-stack med åtte syntetiske runder (bevisst støyende fremgang, for
å faktisk se at regresjonslinjen skiller seg fra stolpene) browser-
verifisert lys+mørk: regresjonslinje bekreftet rett og visuelt distinkt
fra stolpene på alle variabler, riktig fortegn/farge på stigningstall,
ingen dobbel enhet i bildetekstene, kumulative linjer for scrambling/
sand save konvergerer som forventet. Ingen konsollfeil. teecup_db urørt.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-12 11:17:00 +02:00
c967ed11da Statistikk: ekspandert trekkspill, spilt-til-HCP, omstrukturert /my-rounds/stats
Tre brukertilbakemeldinger etter gjennomgang av statistikksidene:

1. round-stats.tsx: trekkspillseksjonene starter nå ekspandert (reverserer
   en tidligere beslutning fra 2026-07-25 om å vise dem sammenslått).

2. Dashbordets "HCP nå" viser nå computed_handicap_index ("spilt til"-HCP,
   beregnet fra faktiske runder) i stedet for det manuelt satte tallet i
   profilen -- historikk-sparklinen filtreres til samme kilde (source=
   "computed"), så den ikke lenger blander manuelle og beregnede punkter.

3. /my-rounds/stats:
   - Alle "vs. forrige periode"-deltaer (pil+tall+pp) er nå synlig
     selvforklarende -- teksten fantes tidligere kun som skjermleser-tekst,
     seende brukere så bare et ikon og et tall uten kontekst.
   - Greentreff (GIR) og Innspill splittet i to kort (GIR er en beregnet
     andel, Innspill er en retningsbeskrivelse -- samme prinsipp som
     round-stats.tsx sin eksisterende splitt). Utslag flyttet først.
     Redning og "Til par: med vs. uten" flyttet ned under Annet.
   - Ny stolpegraf med glidende snitt-trendlinje (snitt til par per runde,
     eldste til venstre) -- tidligere bevisst utsatt pga. for lite
     rundehistorikk (se CHANGELOG 2026-07-28), bygget nå. Backend:
     RoundStatsSummary fikk et nytt round_series-felt (kronologisk
     snitt-til-par per runde i valgt vindu).

Verifisert: tsc --noEmit rent, 45/45 vitest, 31/31 backend-tester (inkl.
det nye round_series-feltet via en scratch-DB-kjøring). Full scratch-
stack med seks syntetiske runder (varierende dato/resultat) browser-
verifisert lys+mørk: HCP-bytte bekreftet (computed 5,3 vist i stedet for
manuelt satt 15,0), ny kortrekkefølge, splittet GIR/Innspill, synlige
delta-bildetekster, graf med trendlinje. Ingen konsollfeil. teecup_db
urørt.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-12 09:12:49 +02:00
aaec9c811d @-tagging (frontend): egen-implementert etter V0-credits tomme
Fullfører ADR-063 -- backend var allerede committet (206beef). Bruker
ba eksplisitt om at Claude selv implementerer frontend-promptet siden
V0-kreditter var oppbrukt.

lib/mentions.ts: ren offset-/diff-logikk (deteksjon, innsetting,
diff-justering ved redigering, tekst-segmentering), 15 enhetstester.
components/mention-input.tsx: MentionTextarea (autocomplete-dropdown,
tastaturnavigasjon) + TaggedText (lenker til /my-friends/{id}). Koblet
inn i round-messages.tsx (innlegg) og post-engagement.tsx (kommentarer,
delt av flere meldingssystemer -- roundId/tags gjort valgfrie for å
ikke bryte de org-scopede callerne uten tagging).

Rettet også et hull oppdaget underveis: backendens GET /feed manglet
tags (kun list_round_messages/comments hadde det) -- det er nettopp
/my-feed-siden som var det opprinnelige brukseksempelet.

Scratch-verifisert (egen DB/rolle/MinIO/API-/frontend-container, to
ekte testbrukere, venn-relasjon, felles runde): autocomplete, tagging
i både innlegg og kommentar, rendring som lenke i rundevisning OG i
aggregert feed, varsel opprettet, personvern-scoping bekreftet (kun
faktiske relasjoner tilbys, ikke seg selv, ikke fremmede), lys+mørk.
tsc --noEmit rent, 45/45 vitest grønt. teecup_db urørt.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-11 10:15:02 +02:00
206beefbc5 @-tagging (backend): medspillere/venner i runde-feeden
All checks were successful
Backend-tester / test (push) Successful in 21s
Migrasjon 064 (round_message_tag/round_message_comment_tag), nytt
GET /rounds/{id}/taggable-people-endepunkt, validering (kun faktiske
relasjoner er taggbare, ugyldige tags forkastes stille), varsling ved
gyldig tag. Se ADR-063/CHANGELOG punkt 72. 8 nye pytest-tester, 31/31
grønt. Frontend (autocomplete + rendering) sendes som eget V0-prompt --
ikke deployet ennå, migrasjon venter til frontend-delen er klar.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-11 09:10:17 +02:00
5c2455c1fe Optimistisk versjonssjekk for org-turneringers match-scoring
All checks were successful
Backend-tester / test (push) Successful in 21s
Fortsetter robusthetslinjen fra ADR-057: hole_score/match_hole_result
(scoring.py) hadde ingen samtidighetsvern, ren siste-skriving-vinner --
den siste dokumenterte, kjente svakheten fra den opprinnelige
"harde kjerner"-vurderingen. Samme version-kolonne-mønster, tilpasset
UPSERT (INSERT ... ON CONFLICT DO UPDATE ... WHERE) i stedet for ren
UPDATE. Offline-kø-kjedingen generalisert til å nøkle på ressurs
(resourceKey), ikke bare URL -- nødvendig siden disse to endepunktene
deler samme URL for alle hull i en match. Se ADR-060/CHANGELOG punkt 69.
23/23 backend-tester grønne, tsc rent. Migrasjon 063 kjørt mot ekte
teecup_db, teecup_api/teecup_frontend rebygget, ingen konsollfeil.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-10 23:19:29 +02:00
17fac05ddc Alt kompilerer rent. Oppsummering av denne runden:
1. WHS Rule 3.1b — ferdig, testet (117/117), rullet ut... nei, venter fortsatt (se under).
2. round.tee_name_snapshot-synk — ferdig, scratch-verifisert.
3. Optimistisk versjonssjekk for samtidig hull-redigering — ferdig bygget, og jeg fant og rettet en reell UX-bug underveis (en fullskjerm-feilvisning i stedet for en liten banner) som ellers ville gjort funksjonen verre enn ingenting.

Alt er dokumentert i ADR-056/057 og CHANGELOG punkt 65–66.

Deploy — rekkefølgen har betydning (migrasjonen må kjøre først, siden ny kode leser version-kolonnen):

# 1. Migrasjon mot ekte teecup_db
docker exec teeoff_db psql -U teeoff_admin -d teecup_db -f /opt/teecup/062_round_hole_version.sql

# 2. Backend
docker compose build teecup_api
docker compose up -d teecup_api

# 3. Frontend
docker compose build teecup_frontend
docker compose up -d teecup_frontend
Og fortsatt uavklart fra tidligere: datakorreksjonen for din spesifikke runde

UPDATE round SET tee_name_snapshot = '55'
WHERE id = '520f9681-6e7f-49bf-8504-9ab223874285';
2026-08-10 18:34:31 +02:00
2562e20ec3 13-årsgrense — håndhevet server-side (eneste vei inn i appen, ADR-051) og med umiddelbar rød feilmelding klientside i begge profil-skjemaer. Testet på nøyaktig dagsgrensen.
PWA-installasjonstekst — skiller nå Safari/Chrome på iOS, ikke lenger feilaktig Safari-only.
Beskrivelsestekst — "golfklubber" fjernet, nytt punkt om at turneringsadmin/-presentasjon fungerer godt på PC.
Dette krever både teecup_api og teecup_frontend (ingen migrasjon).
2026-08-10 07:00:11 +02:00
26313c8017 Kort på hull-kortet: "end"-steget (ballens posisjon) tilbyr nå samme valg som utslags-steget: GPS ("Jeg er ved ballen nå") eller kart ("Vis kart mens jeg går").
Velger du kart, vises utslagspunktet som en fast oransje referansemarkør, og kartet zoomer/panorerer automatisk slik at både din posisjon og utslagspunktet er synlige med det samme. Du trykker der ballen ligger — markøren blir grønn for å skille den fra referansen.
2026-08-08 21:38:10 +02:00
8b1c73cf4f Fiks rundedeling: minst én kategori er nok, ikke alle (ADR-036 E)
Bruker rapporterte at en runde delt med kategorien "Make" ikke ble
synlig for vedkommendes ektefelle. Diagnostisert direkte mot ekte
teecup_db (skrivebeskyttede spørringer): eieren hadde kategorisert
ektefellen under tre kategorier, mens runden kun delte to av dem.
_can_view_round krevde at ALLE en venns kategorier måtte være i
rundens synlige sett -- en presisering fra 2026-07-29 som kun ble
dokumentert i kode-kommentarer, aldri i denne ADR-en, og som strammet
inn utover ADR-036 Beslutning B sin opprinnelige "minst én
kategori"-regel fra 2026-07-25.

Reversert til den opprinnelige regelen i alle fire duplikate SQL-steder
(_can_view_round, _friends_who_can_see_round, list_friends_on_course i
rounds.py; feed-listingen i round_messages.py) -- fra "NOT EXISTS en
kategori utenfor synlig sett" til "EXISTS en kategori innenfor synlig
sett". Scratch-verifisert i begge retninger: venn med overlappende
kategori slipper nå inn, venn med ingen overlappende kategori fortsatt
korrekt avvist.

Se CHANGELOG.md punkt 44 for full verifiseringsdetalj og bekreftelse
mot de ekte, virkelige dataene etter utrulling.
2026-08-08 12:37:09 +02:00
12f10d92a3 Før redesign 2026-08-07 22:02:56 +02:00
f55a51e9e2 e reelle bugger (500 på /feeds paginering, en rute-/rewrite-kollisjon på /feed, og manglende WS-refetch-kobling for kommentarer) — se ADR-044/CHANGELOG for detaljer. Før jeg ruller dette ut mot ekte teecup_db, her er planen:
Kommandoer jeg vil kjøre mot ekte teecup_db/teecup_api/teecup_frontend:

psql migrasjon 058_round_messages.sql mot ekte teecup_db (ny round_message-tabell, ingen endring i eksisterende tabeller).
docker compose up -d --build teecup_api teecup_frontend (begge containere, siden dette er backend+frontend sammen).
Etterpå: bekreft round_message-tabellen finnes, /health//my-rounds/new//my-feed → 200 over https, teeoff.no upåvirket.
2026-08-06 07:01:22 +02:00
038516d236 All five tasks from the original list are complete, plus one critical production bug found and fixed along the way. Summary:
Fullført:

TeeCup-beskrivelse for logo — levert tidligere.
Migrasjon 056 (scramble_solo) — kjørt og live.
Matchspill-varianten (scramble_solo_match, migrasjon 057) — bygget, verifisert, live.
Kritisk bug funnet og rettet: lagspillere kunne ikke registrere score i det hele tatt for scramble_solo-formatene (evig spinner, ingen feilmelding) — var allerede live og ødelagt for ekte lagspillere. Rettet for begge varianter, rullet ut.
"Bruk som mal for egen bane" — vises nå kun i "Opprett ny bane"-flyten (ny lenke "Basér på en eksisterende bane i stedet"), ikke i det vanlige søket.
Alt er rullet ut live på teecup.golf, verifisert i nettleser mot isolerte scratch-miljøer (ryddet opp etterpå), og dokumentert i CHANGELOG.md (punkt 22–24) og FEATURE_BACKLOG.md.
2026-08-05 21:37:32 +02:00
fea701091c Bygg Order of Merit: sesong-sammenlagt spillerrangering på tvers av turneringer
Ny funksjon (ADR-043, migrasjon 055): organisatorer kan opprette en
Order of Merit, lenke individuelle turneringer til den, og få en
sesong-sammenlagt rangering regnet ut ved lesing -- fem resultattyper
(poeng etter plassering, Stableford-, brutto- og nettoscore-sum,
pengeliste), sum/snitt-aggregering, med valgfri behold-N-beste,
minimum antall resultater og aldersgrense. Motor i handicap_engine.py
(9 nye enhetstester), ny app/routers/order_of_merit.py, og to nye
håndkodede frontend-sider under /organizations/[id]/order-of-merit.

Eclectic-aggregering og lag-OOM sin faktiske resultatberegning er
bevisst ikke bygget denne runden (skjema/CRUD for lag finnes, men
leaderboardet avviser kind='team' med en tydelig feilmelding).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-04 14:19:30 +02:00
aee1662de2 Fiks turneringsoppsett-rekkefølge, koble til TeeOff-import, og bygg delt bane-mal-bibliotek
Klasser vises nå etter bane-/rundeoppsett (var meningsløst å velge
standardutslag før banen fantes). TeeOff-import koblet inn i
individuelle turneringer. Ny mal-basert baneoppretting i
turneringsmodulen (fra bunnen av / TeeOff / offentlig custom-bane),
med personal_course gjenbrukt som et delt, plattform-omfattende
bane-bibliotek på tvers av org- og single-runde-modulen (ADR-042,
migrasjon 054).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-04 11:34:28 +02:00