Commit graph

293 commits

Author SHA1 Message Date
e48cfb8dda Dokumenter utrulling av ScrollFade-fiksen
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-11 14:44:22 +02:00
03579c9d11 Dokumenter ScrollFade-fiksen i ADR-062/CHANGELOG.md
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-11 14:42:29 +02:00
ee91d03514 Fiks ScrollFade: sprettende scroll-hint overlappet en ekte pil-knapp
Bruker (skjermbilde): "Den sprettende ned-pilen fungerer ikke. Den
ligger OPPÅ en annen nedpil." -- gjelder Retning-steget (Utslag/
Innspill) i score-registreringen, hvor "Kort"-knappen har sitt eget
ArrowDown-ikon.

To reelle feil i ScrollFade (round-detail.tsx):

1. ResizeObserver observerte scroll-BEHOLDEREN, ikke innholdet.
   Beholderens boks-størrelse er fast (flex-1), så den endrer seg
   aldri når man bytter steg i veiviseren -- observeren fyrte derfor
   ALDRI når et steg med reelt overflow-innhold ble vist. Hintet
   dukket rett og slett ikke opp der det trengtes (f.eks. nettopp
   Retning-steget). Rettet ved å observere innholds-diven i stedet.

2. Fade-/pil-overlayet er absolutt posisjonert over de siste 64px av
   scroll-området, uten noen garanti om at ekte innhold ikke havner
   der. På Retning-steget landet "Kort"-knappens egen pil nøyaktig i
   den sonen -- to piler oppå hverandre. Rettet med en usynlig
   64px-buffer etter innholdet (samme høyde som overlayet), slik at
   overlayet aldri kan dekke et ekte element. hasMore-utregningen
   trekker fra bufferhøyden så den ikke gir falske positiver på kort
   innhold som uansett får plass.

Scratch-verifisert (egen DB/rolle/MinIO/API/frontend-container, ekte
bruker med fullt kølle-utvalg for å reprodusere nøyaktig samme
rutenett som i brukerens skjermbilde): hintet vises korrekt når
Retning-steget faktisk overflower, forsvinner korrekt ved reell bunn,
"Kort"-knappen fullt synlig og utenfor overlay-sonen ved skrolling,
lys+mørk, ingen konsollfeil. tsc --noEmit rent, 45/45 vitest grønt.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-11 14:41:22 +02:00
b704a9c378 Dokumenter utrulling av @-tagging + ChoiceRow-fiks
Migrasjon 064 kjørt mot teecup_db, api+frontend bygget og restartet,
bruker bekreftet.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-11 10:28:28 +02:00
1ca27cbc09 Dokumenter @-tagging-frontenden i ADR-063/CHANGELOG.md
All checks were successful
Backend-tester / test (push) Successful in 22s
Frontend-tester / test (push) Successful in 20s
Oppdaterer status fra "sendt som V0-prompt, ikke bygget" til
selv-implementert (bruker gikk tom for V0-credits) og
scratch-verifisert i nettleser.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-11 10:16:08 +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
17e47930c0 ChoiceRow: fast 3-kolonners rutenett i stedet for flex-wrap
Avstand første putt sine seks alternativer visste seg som 5+1 (ujevn
wrap basert på tekstbredde), lite brukervennlig. Fast grid-cols-3 gir
et forutsigbart 3+3-oppsett -- visuelt uendret for de fire andre
ChoiceRow-brukene i filen (alle har nøyaktig 3 valg fra før).
Browserverifisert (lys+mørk, mobil viewport). Ikke deployet ennå.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-11 08:57:23 +02:00
3db00e72db Åtte brukerrapporterte UX-funn: ny-runde og score-registrering
Fire rettet direkte (reelle logikkfeil/tekstvalg): round-card.tsx sin
"Hull"-celle viste alltid planlagt antall, aldri faktisk spilt for
tidlig avsluttede runder; putt-avstand-etiketter gjort konsekvente
("X-Ym" i stedet for blandet "<Xm ... 8m+"); "Se feed" presisert til
"Se venneaktivitet"; @-tagging av medspillere vurdert og bevisst utsatt.

Fire sendt via V0 (reelt interaksjonsdesign), diffet mot live-treet før
integrering: ny-runde steg 2 sin rekkefølge (Antall hull/Avanserte HCP
flyttet før formatrutenettet), "detaljer"-steget delt i seksjoner med
et nytt scroll-hint, Anywayslag unifisert til samme +/--mønster som
Chip/Bunker/Straffeslag, netto par-markør + egen Putter-aksent.

Se ADR-062/CHANGELOG punkt 71 for full detalj. tsc rent, full
scratch-stack browserverifisert (lys+mørk, mobil viewport) før
utrulling.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-11 08:01:42 +02:00
7c8b352eca Frontend-testinfrastruktur (Vitest) -- geo, offline-queue, formats
All checks were successful
Frontend-tester / test (push) Successful in 41s
Fortsetter robusthetslinjen: frontend-tester var eksplisitt utenfor
omfang i ADR-058/060. 30 nye tester: lib/geo.ts (GPS-avstand/retning,
fasit-forankret), lib/offline-queue.ts (regresjonsvern for
resourceKey-fiksen fra forrige runde), lib/ny-runde/formats.ts
(fullstendighetssjekk på tvers av format-listene). Egen, lettvekts
Forgejo Actions-workflow (ingen Docker-utenfor-Docker nødvendig).

To reelle funn underveis: prosjektet bruker pnpm ikke npm (et første
forsøk med npm feilet, ingen skade); pnpm-workspace.yaml var arvet-
ignorert fra V0-malen men har nå reelt CI-relevant innhold
(allowBuilds: sharp), rettet før det kunne feile CI stille. Se
ADR-061/CHANGELOG punkt 70.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-10 23:44:30 +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
b65491afc8 Selvhostet Forgejo Actions-runner for backend-testene
Empirisk push viste at repoet ikke hadde noen aktiv runner (jobb ble
stående som "Waiting"). Satt opp act_runner lokalt på serveren
(Docker-utenfor-Docker, docker.sock automount) siden
run_backend_tests.sh er avhengig av teeoff_db/teeoff_default som kun
finnes her. Kjører nå som egen tjeneste i docker-compose.yml. Se
ADR-059 og CHANGELOG punkt 68.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-10 22:41:48 +02:00
c5eed728e1 Legg til Forgejo Actions-workflow for backend-testene
All checks were successful
Backend-tester / test (push) Successful in 54s
Empirisk test av om denne repoen faktisk har en aktiv runner (se
ADR-058) -- kjører diagnostikk (Docker-tilgang, teeoff_default-nettverk,
teeoff_db-container) før selve testsuiten, slik at et miljøavvik er
synlig i loggen fremfor en kryptisk feil.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-10 22:28:12 +02:00
d89e22f09c Automatisert backend-testinfrastruktur: RLS, versjonssjekk, aldersgrense
Svarer på det største enkeltfunnet i investor-statusrapporten (nesten
ingen automatisert testdekning utenfor HCP-motoren). 17 nye
integrasjonstester mot en automatisk opprettet/migrert/nedrevet
scratch-database (scripts/run_backend_tests.sh), som kaller de faktiske
router-/auth-funksjonene direkte -- ikke en SQL-gjenimplementering. Se
ADR-058 og CHANGELOG punkt 67 for full detalj.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-10 22:25:02 +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
21c9f17d13 Ny-runde-veiviseren er live med clubhouse-designet, bekreftet uten konsollfeil på teecup.golf.
Kontoen til Fredrik Mathisen (fødselsdato under 13 år, ingen tilknyttet aktivitet) er slettet fra ekte teecup_db, og e-posten med forklaring ble sendt til fredrik.f.mathisen@gmail.com før slettingen ble bekreftet fullført.
2026-08-10 09:07:33 +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
7bcb09a15c Dokumenter GPS-sentrering-fiksen i CHANGELOG.md
Punkt 52. Se forrige commit for koden.
2026-08-08 18:35:37 +02:00
18c7749a72 Fiks: kartet sentrerte alltid på en hardkodet Oslo-koordinat
Produksjonsbug rapportert umiddelbart etter forrige fiks: "Kartet viser
ikke hvor jeg faktisk er, men en eller annen vilkårlig by."

MapPointPicker sin center-koordinat var hardkodet til Oslo, ledsaget av
en kommentar som hevdet "real app centers on last-known position" --
den logikken fantes aldri, kun påstanden. Rettet: kartet henter nå
brukerens ekte GPS-posisjon (ett getCurrentPosition-kall, samme mønster
som "Min posisjon nå") FØR selve Mapbox-kartet initialiseres, med Oslo
kun som fallback hvis posisjon ikke kan hentes.

Scratch-verifisert: overstyrte navigator.geolocation til Bergen sentrum,
bekreftet kartet faktisk åpnet der (annen bystruktur enn forrige Oslo-
test), ikke lenger på den faste koordinaten. Se CHANGELOG.md punkt 52.
2026-08-08 18:35:21 +02:00
1c84dbd4f6 Dokumenter kart-CSS-fiksen i CHANGELOG.md
Punkt 51. Se forrige commit for koden.
2026-08-08 17:24:18 +02:00
7e7c33a724 Fiks: kart-steget kollapset til 0px høyde (mapbox-gl.css CSS-krasj)
Produksjonsbug: "Kunne ikke laste kartet" for alle, bekreftet av bruker
etter oppfølgingsspørsmål ("alle tre" -- kart-valg, resultat-forhånds-
visning, delt bilde).

Rotårsak: mapbox-gl.css sin egen ".mapboxgl-map { position: relative }"
overstyrte Tailwind sin "absolute"-klasse på kart-beholderen (samme
klassenavn Mapbox GL JS legger til ved init, senere i CSS-cascaden).
Så snart position ikke lenger var absolute, mistet inset-0 all effekt
på størrelsen -- beholderen kollapset til height:0, kartet lastet helt
fint (style/tiles/events alle 200/204) men ble klippet vekk, usynlig.
Rettet ved å bytte til h-full w-full, som løser størrelsen via prosent-
arv uavhengig av hvilken position-verdi som vinner.

Kunne ikke fanges opp i tidligere scratch-tester siden Mapbox sin
URL-restriksjon alltid avviste localhost-scratch-opprinnelser før
kartet fikk lastet/rendret. Verifisert denne runden ved å overstyre
Referer-headeren for å simulere det ekte domenet.

Bygget i samme runde (ikke opprinnelig planlagt, brukerønske): en
client-side satellitt-forhåndsvisning i resultatsteget før lagring, med
det offentlige tokenet direkte som <img src> mot Mapbox Static Images
API.

Se CHANGELOG.md punkt 51 for full diagnose, inkl. en separat snubletråd
i mitt eget scratch-testverktøy (grep uten ^-anker matchet en
kommentarlinje) og en ekte service-worker-cache-fallgruve funnet
underveis.
2026-08-08 17:23:59 +02:00
23bef24e18 Dokumenter slag-liste-funksjonen i CHANGELOG.md
Punkt 50. Se forrige commit for koden.
2026-08-08 16:45:24 +02:00
db944bc119 Slag-for-slag GPS-avstandsmåling: liste over egne slag + fiks stille del-feil
Brukertilbakemelding: "jeg burde jo se slaget selv, selv om det ikke er
delt" -- merkelappen viste tidligere kun et antall, aldri kølle/avstand
for de faktiske slagene. ShotMeasurementEntry lagrer nå hele slag-listen
(ikke bare .length), med en ny utvidbar ShotList (kølle+avstand, "Delt"-
merke eller "Del"-lenke for et ikke-delt slag, slette-knapp per slag via
det allerede eksisterende DELETE-endepunktet). Splittet den ene knappen
i en utvidbar "N slag målt"-disclosure og en separat "+"-knapp for nye
målinger.

Tredje stille-feil-bug funnet og rettet i samme runde (samme klasse som
forrige commit): re-del-fra-liste sjekket heller ikke svaret sitt. Lagt
til egen shareError-state, bevisst atskilt fra submitError (som holder
selve måle-arket åpent ved avvist innsending) -- siden slaget allerede
er lagret når en delingsfeil kan oppstå, ville gjenbruk av submitError
risikert et duplikat-slag ved gjentatt "Lagre slag".

Scratch-verifisert: to slag opprettet, listen viser riktig kølle/
avstand, re-del fra listen fungerer (bekreftet ekte melding postet),
sletting fjerner slaget fra listen. Se CHANGELOG.md punkt 50.
2026-08-08 16:45:13 +02:00
d0167b3882 Dokumenter slagmåling-produksjonsbugfiksen i CHANGELOG.md
Punkt 49. Se forrige commit for koden.
2026-08-08 15:06:59 +02:00
8da2423942 Fiks: slagmåling ga alltid 0m, delinger forsvant stille
Produksjonsbug rapportert av bruker rett etter forrige utrulling: "den
målte aldri mer enn 0 meter. Jeg så ingen bilder."

Rotårsak 1: "end"-steget (ballens posisjon) avfyrte GPS-målingen
automatisk idet steget ble aktivt, uten tid for brukeren til faktisk å
gå fra utslagsstedet til ballen -- start/slutt endte på samme sted,
samme øyeblikk. Fjernet auto-avfyringen, krever nå et eksplisitt "Jeg
er ved ballen nå"-trykk.

Rotårsak 2 (konsekvens av #1): en 0m-avstand avvist av backendens
distance_meters > 0-validering (422) gjorde at submitShot() bare lukket
arket stille, ingen feilmelding. Lagt til submitError/submitting-state,
parser både appens {detail:{message}} og FastAPI/Pydantic sin rå
{detail:[{msg}]}-valideringsform (bekreftet eksakt hvilken ved å
trigge en ekte 422), viser feilen i arket, holder det åpent ved feil.

Scratch-verifisert med navigator.geolocation midlertidig overstyrt
(ekte GPS-tillatelse permanent denied i CDP-automatiserte nettleser-
sesjoner): "Jeg er ved ballen nå" vises korrekt, et ekte gap ga
"130 m" (ikke 0) og delingen postet riktig, og en 0m-innsending viser nå
feilmeldingen i stedet for å lukke stille. Se CHANGELOG.md punkt 49.
2026-08-08 15:06:48 +02:00
70f6e92726 Dokumenter slagmåling-utrulling mot ekte teecup_db/teecup_api/teecup_frontend
Punkt 48: 060_round_shot.sql migrert (test_isolation.sql 12/12 uendret),
begge Mapbox-tokens verifisert (delings-satellittbilde bekreftet ekte,
176KB AVIF), containere bygget/restartet rent, teecup.golf bekreftet
oppe. ADR-048 er nå fullt bygget, verifisert og live.
2026-08-08 14:49:52 +02:00
861a2ec1a7 Dokumenter gjest-utslag-fiksen i CHANGELOG.md
Punkt 47. Se forrige commit for koden.
2026-08-08 13:39:31 +02:00
ad3c47bfa3 Ny-runde-veiviser: legg utslag direkte i gjesteskjemaet
Brukertilbakemelding: valg av utslag for en nyopprettet gjest var lite
intuitivt -- måtte inn i det ferdigopprettede gjestekortets "Rediger"-
visning for i det hele tatt å se hvilket utslag som ble valgt.
addGuest() valgte allerede utslag automatisk (kjønnsbasert), men helt
stille -- selve GuestForm hadde aldri et synlig Utslag-felt.

Lagt til et kontrollert teeId-felt direkte i gjesteskjemaet, samme
NativeSelect-mønster og kjønn->utslag-resynk-logikk som PlayerCards
tilsvarende felt allerede hadde -- inkludert i "Fyll inn automatisk"-
knappen for kjente gjester (samme feilklasse, ikke tidligere rettet
der).

Scratch-verifisert: kjønnsbytte i skjemaet oppdaterer utslag-valget
umiddelbart, og det ferdige spillerkortet viser riktig utslag med det
samme uten å måtte åpne redigering. Se CHANGELOG.md punkt 47.
2026-08-08 13:38:00 +02:00
43482d9ba9 Dokumenter slagmåling-inngangspunkt 2 i CHANGELOG.md
Punkt 46. Se forrige commit for koden.
2026-08-08 13:12:31 +02:00
4981c7eaed Slag-for-slag GPS-avstandsmåling: inngangspunkt 2 — merkelapp på hull-kortet (ADR-048)
Fullfører v1-kravet om å dekke begge hull-eiertyper fra start (forrige
commit dekket kun deltaker-eide hull via ScoringWizard). Refaktorerte
den inline logikken ut til en delt lokal funksjon ShotMeasurementEntry
(samme "lokal gjenbruk innad i filen"-mønster som resten av filens
komponenter) -- bygger riktig URL-base for enten
.../participants/{id}/holes/{n}/shots eller .../sides/{id}/holes/{n}/
shots fra en enkel owner:{kind,id}-prop.

Koblet inn i PlayerHoleCards (deltaker-eide hull, som søsken av kortets
store klikkbare knapp -- ikke nøstet, ugyldig å neste <button> i
<button>) og SideScorecardGrid (side-eide hull -- to merkelapper med
lag-etikett rett under scorekort-gridet, siden selve tabellen er for
tett til en knapp per rute).

Bruker satte inn et ekte Mapbox-token (NEXT_PUBLIC_MAPBOX_TOKEN) i .env
midt i denne runden. Scratch-verifisert med det ekte tokenet: kart-veien
avvist med 403 (URL-restriksjon mot scratch-miljøets localhost-
opprinnelse) -- bekreftet at feilhåndteringen i MapPointPicker fungerer
rent i stedet for å krasje. Begge merkelapper bekreftet henter og
oppdaterer riktig, uavhengig av hverandre, for både deltaker- og
side-eide hull.

Se CHANGELOG.md punkt 46 for full verifiseringsdetalj.
2026-08-08 13:12:25 +02:00
2d1d0ba1d0 Dokumenter dashbord/BottomNav/veiviser/login/deling/slagmåling i CHANGELOG.md
Punkt 39-45: dashbord+BottomNav-reskin, ny-runde-veiviser + offisiell-
banesøk-produksjonsbug, /logg-inn som ekte innloggingsside, rundedeling-
kategoriregel-fiks (ADR-036 E), og slag-for-slag-avstandsmåling
inngangspunkt 1. Se de fem foregående commitene for koden.
2026-08-08 12:38:31 +02:00
9538dfec7f Slag-for-slag GPS-avstandsmåling: entry point i scoring-veiviseren (ADR-048)
Første inngangspunkt av to planlagte: en "Mål et slag"-knapp i
ScoringWizard sitt detalj-steg, rett etter kølle-plukkeren for utslaget.
Komponentene (components/shot/shot-measurement-sheet.tsx,
map-point-picker.tsx) kommer fra en egen, teknisk V0-prompt (design-
tokens fra DESIGN_SYSTEM.md spesifisert som hard begrensning, siden
dette er et ark INNI en eksisterende Forest Green-skjerm, ikke en ny
frittstående side) -- meget tro mot spesifikasjonen: korrekt
next/dynamic({ssr:false})-lasting av kartsteget, ingen mapbox-gl-import
på GPS-only-stien, kartet mountes kun én gang per arkåpning.

components/ui/textarea.tsx (ny shadcn-primitiv) lagt til. Eksisterende,
lokale ClubPicker i round-detail.tsx trukket ut til
components/teecup/club-picker.tsx (ren utrekking, ingen atferdsendring)
slik at måle-arket kan gjenbruke den fremfor V0s egen plassholder-kopi.

Wiret mot ekte backend: POST .../holes/{n}/shots ved innsending, valgfri
etterfølgende POST .../shots/{id}/share ved deling, shot-telling hentet
og vist i selve knappen ("Mål et slag (N målt)").

Gjenstår: inngangspunkt to (alltid-synlig merkelapp på hull-kortet for
retroaktiv måling + lagformat-støtte), ekte Mapbox-tokens, og migrasjon
060_round_shot.sql mot ekte teecup_db (ingen av disse rørt ennå).
2026-08-08 12:37:30 +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
b0c65d983b Gjør /logg-inn til den ekte innloggingssiden
/logg-inn (clubhouse-palett, TeeCupAuth) var en foreldreløs V0-
utforskning -- ingenting i appen lenket eller redirectet dit, og
TeeCupAuth var 100% mock (sleep()-baserte stubber, hardkodet
demo-passord, falske invitasjonskoder, en falsk "2FA-kode sendes"-tekst
som aldri sendte noe). Flagget eksplisitt til bruker før arbeid startet,
siden dette er sikkerhetskritisk kode og omfanget var langt større enn
en ren redirect-ombytting.

Full port: ekte POST /auth/request-link, POST /auth/login-password
(identisk LoginResult-statushåndtering som den gamle LoginForm), GET
/public/tournaments/by-code/{code}. TwoFactorVerifyForm/
TwoFactorSetupForm gjenbrukt UENDRET (lavest mulig risiko for
sikkerhetskritisk 2FA-kode). app/page.tsx redusert til en tynn
videresending (autentisert -> /dashboard//account, uautentisert ->
/logg-inn), beholdt for gamle bokmerker. Gammel LoginForm slettet.
Alle ~11 uautentisert-redirect-steder (committet i forrige commit)
pekte allerede til /logg-inn.

Én reell bug funnet og rettet under scratch-verifisering:
app/logg-inn/page.tsx kalte redirect() INNI en try/catch som fanget
Next.js sin egen NEXT_REDIRECT-kontrollflyt-exception stille -- en
allerede innlogget bruker fikk se innloggingsskjemaet på nytt i stedet
for å bli sendt videre. Rettet ved å flytte redirect()-kallet utenfor
try/catch, samme mønster som den opprinnelige /-siden alltid brukte.

Se CHANGELOG.md punkt 42 for full verifiseringsdetalj.
2026-08-08 12:34:50 +02:00
11d10f7661 Erstatt /my-rounds/new med ny-runde-veiviser fra egen V0-prompt
Gammel components/new-round.tsx (3364 linjer) slettet, erstattet av
components/ny-runde/ + lib/ny-runde/ -- V0-eksporten (full teknisk spec,
null designføring) ported mot de faktiske backend-kontraktene i
app/routers/rounds.py: Gender-oversettelse, forenklet Tee-form (aldri
CR/Slope til klienten), CourseMeta-discriminated-union for teeoff- vs.
egen-bane, ekte POST /rounds -> sides -> participants-sekvens, ekte
kontosøk/gjeste-oppslag, ekte banesøk inkl. geolokasjon.

Fire bugs funnet og rettet under scratch-verifisering: manglende
forwardRef på TextInput (i selve V0-eksporten), manglende
tee-synk til eierens spillerkort etter banevalg (egen portingsfeil),
manglende Ingen/Alle-hurtigknapp i steg 5 (samme mangel rettet i appen
2026-08-06), og en produksjonsbug oppdaget EKTE brukere etter utrulling:
fetchFacilityCourses() leste responsen fra offisielt banesøk som en rå
array i stedet for {slug,name,courses}-objektet backend faktisk
returnerer -- ga en uendelig "Laster baner..."-hang for enhver runde
startet på en offisiell (teeoff-)bane. Rettet + lagt til reell
feilhåndtering i OfficialCourses (manglet helt, feilen ble tidligere
en stille, ufanget promise-rejection).

Se CHANGELOG.md punkt 41 og 43 for full verifiseringsdetalj.
2026-08-08 12:34:25 +02:00
8ef2f61f4d Reskinn dashbord + erstatt bunn-navigasjon med clubhouse-palett
Dashbordets egne JSX re-stylet til --clubhouse-*/--tee*/--cup*-tokens
(V0, egen parallell utforskning ved siden av Forest Green) -- delte
komponenter som RoundCard/TournamentCard urørt. Den gamle, lokale
BottomTabBar erstattet med components/teecup/bottom-nav.tsx (egen
V0-prompt, usePathname()-drevet aktiv-fane), koblet inn på alle syv
sider som viser den. To reelle bugs funnet og rettet under
scratch-verifisering: aktiv-fane-sammenligning som feilaktig strippet
#hash (ga to samtidig aktive faner), og manglende fane-gruppering for
my-friends/my-feed/my-notifications (løst med en matchPaths-mekanisme).

Se CHANGELOG.md punkt 39-40 for full verifiseringsdetalj.
2026-08-08 12:34:03 +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
c5455d0220 Fullfør domenemigrering teecup.teeoff.no -> teecup.golf på app-nivå
Caddy/DNS/SPF/DKIM/DMARC var allerede live på teecup.golf. Denne
committen kobler appen inn: docker-compose.yml sendte til nå ALDRI
TEECUP_PUBLIC_BASE_URL/TEECUP_VAPID_SUBJECT inn i teecup_api-
containeren (kjørende containere brukte derfor kode-fallbacken, gammelt
domene, for magic-link-URL-er til tross for at nettsiden allerede ble
servert fra teecup.golf). layout.tsx sin metadataBase og config.py sine
to hardkodede fallback-standarder rettet til samme domene. E-post-
fra-adresse (TEECUP_FROM_EMAIL/SMTP_USER, ny postkasse teecup@teecup.golf)
oppdatert direkte i .env (ikke committet, gitignored).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-05 13:35:19 +02:00
158699fb36 Rett utdatert CLAUDE.md-notat om fire uferdige turneringsformater
Københavner, High-low-high og Try-all (Chapman) er bygget og live;
Robbins ble droppet av bruker. Notatet pekte fortsatt til det gamle,
firedelte utvalget som grunn til å lese HCP-PDF-ene -- generalisert til
å gjelde enhver fremtidig ny turneringsform i stedet.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-05 13:35:04 +02:00
ebd60da746 Fiks: "Fullfør runde" i header-modalen svelget feil stille og lukket seg uansett utfall
Modalen ("Administrer runde", tilgjengelig fra alle tre rundefanene) hadde en
egen, uavhengig "Fullfør runde"-vei som aldri sjekket setup_complete og
lukket dialogen umiddelbart uten å vente på fetch-svaret -- så en ufullstendig
formatoppsett (f.eks. Københavner med for få spillere) så ut til å fullføres,
men gjorde det aldri, uten noen feilmelding. Backend-valideringen var korrekt
fra før; kun frontend fulgte aldri opp svaret.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-04 19:48:17 +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
828b508c53 Dokumenter Augusta-stil resultattavle i CHANGELOG/FEATURE_BACKLOG
Fullfører dokumentasjonen for den nye slagspill-resultattavlen (POS/
PLAYER/TODAY/THRU/TOTAL/R1-Rn), rullet ut 2026-08-04: V0-integrering
(zip 29), Golfscore-språk-fiksen for rundekolonnenes eksakt-par-tilfelle,
og den reelle til-par-rangeringsbugen funnet og rettet under
scratch-verifisering.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-04 04:51:09 +02:00
50653303f4 Alt er scratch-verifisert grundig — API og ekte nettleser, både på 390px mobil og en 1920px "storskjerm". Før jeg deployer:
Hva som skjer:

Ingen migrasjon (kun nye felt i et eksisterende API-svar, ingen skjemaendring).
docker compose up -d --build teecup_api teecup_frontend mot ekte teecup_db.
Hva som er verifisert:

Ny Augusta-stil resultattavle (POS/PLAYER/TODAY/THRU/TOTAL/R1-Rn) for brutto-, netto- og stableford-turneringer — København/BBB/Flagg beholder dagens visning uendret.
Lederen(e) fastspent øverst i gull, uavgjort håndteres riktig (bekreftet: to spillere delte ledelsen med -5 hver, viste begge som "T1").
Rull-automatisk-knapp fungerer (av/på bekreftet).
Storskjerm skalerer opp fint uten skrolling; mobil får riktig frossen POS/PLAYER-kolonne.
Rettet appens eget "E → ren tekst, ingen ramme"-regel inn i den nye komponenten (V0 hadde ikke helt fått det med seg for selve runde-cellene) — bekreftet visuelt.
Fant og rettet en reell rangeringsbug under verifiseringen: i en flerrunde-turnering der spillere har spilt ulikt antall hull, kan man IKKE rangere på rått slagtall (færre hull spilt ga misvisende lavt tall) — måtte rangere på til-par i stedet. Uten denne fiksen ville en spiller som knapt hadde startet kunnet vises som leder.
2026-08-04 04:47:27 +02:00
38168b2871 Dokumenter konkurranseklasser (ADR-041) i CHANGELOG/FEATURE_BACKLOG
Fullfører dokumentasjonen for klasse-funksjonen (migrasjon 053, rullet
ut 2026-08-04): ny ADR-041 med de fire load-bærende beslutningene
(fritt navngitte klasser, delt tabell mellom turneringstyper,
standardutslag som frontend-bekvemmelighet, egen resultatliste kun i
individuelle turneringer), pluss fulle bygge-/verifiseringsoppføringer
i CHANGELOG.md og FEATURE_BACKLOG.md.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-04 03:49:41 +02:00
7bda1bf789 Alt er bygget og grundig scratch-verifisert — både API-nivå og ekte nettleser-klikk, på begge turneringstyper. Før jeg ruller ut mot ekte teecup_db, her er planen:
Hva som skjer:

Kjør migrasjon 053_tournament_classes.sql mot ekte teecup_db — ny tournament_class-tabell + nullable class_id-kolonne på team_roster og tournament_participant (rent additivt, ingen eksisterende data røres).
docker compose up -d --build teecup_api teecup_frontend — begge containere bygges og redeployes.
Hva som er verifisert:

Klasser kan opprettes/slettes for begge turneringstyper, med valgfritt standardutslag (kaskaderende bane→utslag-valg)
I lagturneringer: klasse foreslår riktig utslag automatisk når en spiller legges til en kamp (bekreftet: Kari→44, Ola→56), ingen endring i selve kampresultatet
I individuelle turneringer: samme utslag-forslag ved runde-oppsett, PLUSS leaderboardet deler seg nå i egne seksjoner per klasse med riktig rangering innad i hver (bekreftet: Damer viste Kari #1/Siv #2, Herrer viste Ola #1 — matcher håndregnet slagsum)
Sletter man en klasse, mister spillerne bare merkelappen (ikke fjernet fra laget/turneringen)
Ingen klasser opprettet = identisk visning som før (bakoverkompatibelt)
98/98 enhetstester og 12/12 isolasjonstester uendret, ekte typesjekket produksjonsbuild
2026-08-04 03:44:16 +02:00
83caddf193 Noter plan for internasjonale baner (golfapi.io) i backlog/ADR-019
Ren dokumentasjonsrunde, ingen kode - fanger retningen fra brukerens
eksterne research (Gemini) om hvordan TeeCup kan støtte baner utenfor
Norge når/hvis produktet kommersialiseres. Golfapi.io valgt som
leverandør, anbefalt tilnærming er live API + egen caching (samme
import-ved-eksplisitt-valg-prinsipp som ADR-019 allerede etablerte for
teeoff), ikke det dyre CSV-databasekjøpet. Ingen ADR skrevet ennå -
bevisst utsatt til dette faktisk skal bygges.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-03 19:15:13 +02:00