Compare commits

...

2 commits

Author SHA1 Message Date
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
4 changed files with 116 additions and 3 deletions

View file

@ -9388,3 +9388,85 @@ Neste steg:
faktisk postet riktig tekst til `/rounds/{id}/messages`, slettet faktisk postet riktig tekst til `/rounds/{id}/messages`, slettet
7-jern-slaget og bekreftet det forsvant fra listen ("1 slag målt" 7-jern-slaget og bekreftet det forsvant fra listen ("1 slag målt"
etterpå). Scratch-miljøet ryddet opp fullstendig. etterpå). Scratch-miljøet ryddet opp fullstendig.
51. **PRODUKSJONSBUG: kart-steget viste "Kunne ikke laste kartet" for
alle -- CSS-arv-krasj med mapbox-gl.css — 2026-08-08, brukeroppfølging
("jeg ser ikke noe kart eller satellittfoto").** Bruker bekreftet
"alle tre" da spurt hvor de forventet kart/foto: (1) kart-valg under
måling, (2) forhåndsvisning i resultatsteget, (3) bilde i den delte
meldingen.
**(1) Rotårsak:** `mapbox-gl.css` (selve biblioteket sin stilark,
importert i `map-point-picker.tsx`) definerer `.mapboxgl-map {
position: relative }`. Mapbox GL JS legger `mapboxgl-map`-klassen til
PÅ kart-beholderen sin egen `<div>` ved initialisering -- denne
klassen kom SENERE i CSS-cascaden enn Tailwind sin `absolute`-klasse
(samme element), og vant dermed kappløpet, og overstyrte `position`
fra `absolute` til `relative`. Så snart `position` ikke lenger var
`absolute`, mistet Tailwind sin `inset-0`-klasse all effekt på
STØRRELSEN (den styrer kun posisjon for absolutt/fixed-plasserte
elementer) -- beholderen kollapset til `height: 0`, og selve
Mapbox-kartet (som TEKNISK sett lastet helt fint -- style/tiles/
events ga alle 200/204) ble usynlig, klippet vekk av en 0px-høy
forelder. Bekreftet direkte via `getBoundingClientRect()`-kjeden opp
DOM-treet: `containerRect.height: 0` til tross for at Mapbox sitt
eget `<canvas>`-element hadde en normal størrelse. Rettet ved å bytte
`absolute inset-0` til `h-full w-full` på beholder-diven -- løser
størrelsen via prosent-arv, upåvirket av hvilken `position`-verdi som
vinner cascade-kappløpet.
Denne konkrete feilen kunne IKKE vært fanget opp i noen av de
tidligere scratch-testene denne økten (femtende, sekstende), siden
Mapbox sitt eget offentlige token alltid ble avvist av URL-
restriksjonen mot `localhost`-scratch-opprinnelser der -- kartet
kom aldri langt nok til å faktisk RENDRE for at CSS-krasjen skulle
bli synlig. Verifisert denne runden ved å midlertidig overstyre
nettleserens `Referer`-header til `https://teecup.golf/` (CDP-nivå,
forbi selve nettleserens fetch()-header-restriksjon) for å simulere
det ekte, godkjente domenet i scratch -- avdekket samtidig at
scratch-testen selv hadde en snubletråd: en `grep`-basert token-
utpakking (`grep NEXT_PUBLIC_MAPBOX_TOKEN .env`, uten `^`-anker)
matchet FEILAKTIG også `.env` sin forklarende kommentarlinje over
selve variabelen (som også inneholder teksten "NEXT_PUBLIC_MAPBOX_
TOKEN"), og satte sammen kommentarteksten med selve tokenet til en
ugyldig verdi -- bekreftet at DENNE spesifikke feilen kun rammet
scratch-testverktøyet mitt, ikke selve produksjonsutrullingen
(`docker-compose.yml` sin `${NEXT_PUBLIC_MAPBOX_TOKEN}`-variabel-
substitusjon er upåvirket, bekreftet ved å grepe direkte i den ekte,
kjørende frontend-containerens bygde JS-bunt).
Underveis avdekket også en ekte SERVICE WORKER-cache-fallgruve verdt
å ha i bakhoden for senere feilsøking: en omstart av scratch-
frontend-containeren (SAMME port) beholdt en GAMMEL, cachet JS-bunt
i nettleseren til service workeren ble eksplisitt avregistrert og
cachen tømt -- PWA-installasjonen cacher altså aggressivt nok til å
overleve en full container-utrulling, noe som er relevant å huske
ved fremtidig feilsøking av "jeg ser fortsatt det gamle" -rapporter.
**(2) Bygget (ikke opprinnelig planlagt, brukerønske):** en client-
side forhåndsvisning i resultatsteget, FØR "Lagre slag" trykkes.
Bruker Mapbox Static Images API direkte som en `<img src>`, med det
OFFENTLIGE tokenet (trygt i nettleseren) -- ingen server-tur-retur
nødvendig kun for en forhåndsvisning, adskilt fra selve delingens
server-side-genererte bilde (som fortsatt inkluderer en linje mellom
punktene, ikke bare to nåler).
**(3) Allerede fungerende:** bekreftet tidligere denne økten
(scratch18, punkt 48) at selve delings-bildegenereringen fungerer
server-side med `TEECUP_MAPBOX_SECRET_TOKEN` -- brukerens opplevelse
av "ingen bilde" der skyldtes at selve DELINGEN aldri fullførte
(punkt 50s diagnose: "Del i feeden"-valget nullstilles hver gang
arket åpnes på nytt), ikke en feil i bildegenereringen selv.
`tsc --noEmit` rent. **Scratch-verifisert i ekte nettleser** (tjueførste
scratch-miljø denne økten, samme migrasjon-002-forsiktighet,
`teecup_db` bekreftet uendret) MED `Referer`-overstyring for å komme
forbi URL-restriksjonen: kartet viste nå ekte satellittbilder (Oslo
sentrum, default-koordinat), et simulert klikk på kartet plasserte en
markør korrekt og aktiverte "Bekreft punkt", og resultatsteget viste
en korrekt forhåndsvisning med A/B-markører og riktig avstand (130m).
Scratch-miljøet ryddet opp fullstendig.
**Rullet ut umiddelbart** (produksjonsbug som traff ALLE brukere som
prøvde kart-basert måling) -- kun frontend-image, `teecup_api`
bekreftet uendret.

View file

@ -78,8 +78,20 @@ export function MapPointPicker({ onConfirm }: { onConfirm: (lngLat: LngLat) => v
return ( return (
<div className="flex h-full flex-col"> <div className="flex h-full flex-col">
<div className="relative flex-1"> <div className="relative flex-1">
{/* Map canvas host — kept mounted for the map's whole lifetime. */} {/* Map canvas host kept mounted for the map's whole lifetime.
<div ref={containerRef} className="absolute inset-0" aria-label="Satellittkart" role="application" /> `h-full w-full`, IKKE `absolute inset-0`: mapbox-gl.css sin egen
`.mapboxgl-map { position: relative }`-regel overstyrer en
`absolute`-Tailwind-klasse her (samme klasse-navn, senere i
cascade siden mapbox-gl.css importeres i denne komponentfilen)
-- når posisjonen dermed blir `relative` i stedet for
`absolute`, mister `inset-0` all effekt størrelsen (den
styrer kun posisjon/størrelse for absolutt/fixed-plasserte
elementer), og beholderen kollapser til 0 høyde uansett hvilken
posisjonsverdi som vinner kappløpet. `h-full`/`w-full` løser
størrelsen via prosent-arv i stedet, som fungerer likt for
både `relative` og `absolute`. Reell bug funnet 2026-08-08,
se CHANGELOG.md. */}
<div ref={containerRef} className="absolute inset-0 h-full w-full" aria-label="Satellittkart" role="application" />
{!loaded && !error ? ( {!loaded && !error ? (
<div className="absolute inset-0 flex items-center justify-center bg-background"> <div className="absolute inset-0 flex items-center justify-center bg-background">

View file

@ -143,6 +143,17 @@ export function ShotMeasurementSheet({
const distance = const distance =
typeof distanceMeters === "number" ? distanceMeters : previewDistance(startPoint, endPoint) typeof distanceMeters === "number" ? distanceMeters : previewDistance(startPoint, endPoint)
// Forhåndsvisning av satellittutsnittet FØR lagring (brukerønske
// 2026-08-08, ikke opprinnelig planlagt -- selve DELINGEN genererer sitt
// eget, server-side bilde med samme markører+linje uavhengig av dette).
// Bygget client-side med det OFFENTLIGE tokenet (trygt i nettleseren,
// URL-restriktert) -- ingen server-tur-retur nødvendig kun for en
// forhåndsvisning.
const previewUrl =
startPoint && endPoint && process.env.NEXT_PUBLIC_MAPBOX_TOKEN
? `https://api.mapbox.com/styles/v1/mapbox/satellite-streets-v12/static/pin-s-a+ff5a1f(${startPoint.lng},${startPoint.lat}),pin-s-b+2f7a3f(${endPoint.lng},${endPoint.lat})/auto/500x300@2x?padding=50&access_token=${process.env.NEXT_PUBLIC_MAPBOX_TOKEN}`
: null
// Prefill the (editable) share text once the result step is reached. // Prefill the (editable) share text once the result step is reached.
useEffect(() => { useEffect(() => {
if (step === "result" && !shareEdited.current) { if (step === "result" && !shareEdited.current) {
@ -353,6 +364,14 @@ export function ShotMeasurementSheet({
{step === "result" ? ( {step === "result" ? (
<div className="mx-auto flex max-w-md flex-col gap-6 pt-2"> <div className="mx-auto flex max-w-md flex-col gap-6 pt-2">
{previewUrl ? (
// eslint-disable-next-line @next/next/no-img-element -- ekstern Mapbox-URL, ikke next/image-verdt
<img
src={previewUrl || "/placeholder.svg"}
alt="Satellittutsnitt av slaget, med start- og sluttpunkt markert"
className="w-full rounded-2xl border border-border object-cover"
/>
) : null}
<div className="flex flex-col items-center gap-1 rounded-2xl border border-border bg-card p-6"> <div className="flex flex-col items-center gap-1 rounded-2xl border border-border bg-card p-6">
<span className="text-sm font-semibold uppercase tracking-wide text-muted-foreground"> <span className="text-sm font-semibold uppercase tracking-wide text-muted-foreground">
Målt lengde Målt lengde

File diff suppressed because one or more lines are too long