Commit graph

253 commits

Author SHA1 Message Date
648293e1f8 Reduser strømforbruk for avstandsindikatoren
Brukerrapport om høyt batteriforbruk. To justeringer i
hole-target-distance.tsx: maximumAge 1000ms -> 4000ms (umerkelig ved
gangfart, sjeldnere GPS-fix), og watchPosition pauses helt når
fanen/appen ikke er synlig (document.visibilitychange), gjenopptas
automatisk. enableHighAccuracy uendret -- lav nøyaktighet ville gjort
front/midt/bak-tallene meningsløse.

Verifisert i nettleser: clearWatch bekreftet kalt ved backgrounding,
watchPosition bekreftet kalt på nytt ved retur, ingen konsollfeil.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-13 15:01:59 +02:00
ac11da7b87 Flytt avstandsindikatoren til hovedvisningen, full bredde
Brukeren viste et skjermbilde fra ekte produksjon: indikatoren satt i
scoreførings-veiviseren (feil øyeblikk -- åpnes ETTER hullet er
spilt), skulle vært i hoved-hull-visningen (PlayerHoleCards, rett
under hull-navigatoren) med mer bredde enn kompaktvarianten.

HoleTargetDistance sin egen rad-wrapper fjernet -- kalleren styrer nå
plassering/bredde. Verifisert på nytt i scratch (lys+mørk, ingen
konsollfeil) og rullet ut.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-13 10:48:09 +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
12504343ec Dokumenter utrulling av lineær regresjon + trend-på-alle-variabler
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-12 11:19:56 +02:00
ad1cbf7113 Dokumenter lineær regresjon + trend-på-alle-variabler i CHANGELOG.md
All checks were successful
Backend-tester / test (push) Successful in 20s
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-12 11:18:01 +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
a7896122cb Dokumenter utrulling av statistikk-omstruktureringen
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-12 09:15:39 +02:00
859dded655 Dokumenter statistikk-omstruktureringen i CHANGELOG.md
All checks were successful
Backend-tester / test (push) Successful in 23s
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-12 09:13:44 +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
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