CHANGELOG: logg for cut-kaskade, sorterbare kolonner, Ny runde-fiksene og Score-fane-rettelsene
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
e940e932c1
commit
a3f306c388
1 changed files with 252 additions and 0 deletions
252
CHANGELOG.md
252
CHANGELOG.md
|
|
@ -13667,3 +13667,255 @@ Neste steg:
|
|||
Ren frontend. `docker compose build teecup_frontend && up -d`, rene
|
||||
logger. Ekstra oppmerksomhet på akkurat denne (automatisk
|
||||
hull-fremgang etter siste spiller) anbefalt i faktisk bruk.
|
||||
|
||||
144. **Cut-overlevere kaskaderes automatisk til alle senere runder,
|
||||
2026-08-20 (ADR-095).** Bruker: "I eksempelturneringen vår opererer
|
||||
vi med cut etter runde 1. På et vis burde de som har klart cut'en
|
||||
autoselekteres på runde 2?" Undersøkt (read-only, Explore-agent) før
|
||||
bygging: `tournament_round_participant`-rader opprettes kun på
|
||||
forespørsel, aldri på forhånd for alle runder -- ingen eksisterende
|
||||
mekanisme for dette.
|
||||
|
||||
To designbeslutninger bekreftet av bruker etter at jeg foreslo en
|
||||
snevrere variant: (1) kaskade til ALLE runder etter cut, ikke bare
|
||||
den neste -- "Har du klart cut'en spiller du alle påfølgende
|
||||
runder." (2) fjern kuttede spilleres rundedeltakelse i senere runder
|
||||
(ikke bare la stå blokkert) -- "Jo, fjern de. Dette får vi heller
|
||||
reversere om det viser seg å være en dårlig beslutning," etter at
|
||||
jeg opplyste at sletting kaskaderer til `tournament_round_hole`
|
||||
(migrasjon 040, `ON DELETE CASCADE`).
|
||||
|
||||
Ny `_sync_post_cut_round_participation`-funksjon
|
||||
(`app/routers/individual_tournaments.py`), kalt fra `apply_cut` i
|
||||
samme transaksjon: for hver runde etter cut -- overlevere som
|
||||
mangler en rad får én auto-INSERT-et (tee kopiert fra cut-runden,
|
||||
handicap regnet ut med samme funksjon `add_round_participant`
|
||||
bruker); kuttede spilleres eksisterende rad SLETTES, MEN kun hvis
|
||||
den ikke allerede har registrert score (beskytter ekte data mot
|
||||
kaskade-sletting). Idempotent, som resten av `apply_cut`.
|
||||
`CutResult` fikk nytt felt `added_to_later_rounds`, vist i "Anvend
|
||||
cut"-bekreftelsen. `SetupTab` nullstiller nå hele
|
||||
`roundParticipantsByRound` etter "Anvend cut" (flere runder kan
|
||||
endres samtidig) i stedet for å refreshe kun én.
|
||||
|
||||
**Testet, ikke bare gjennomgått:** 5 nye tester lagt til
|
||||
`tests/test_cut.py`, kjørt mot en isolert scratch-database
|
||||
(`./scripts/run_backend_tests.sh`) -- auto-tillegg med riktig
|
||||
kopiert tee, fjerning av kuttede spilleres rad, IKKE-fjerning når
|
||||
scorer finnes (+ bekreftet at 403-sperren fortsatt fungerer der),
|
||||
kaskade til runde 3 uten runde 2 i mellom. Én eksisterende test
|
||||
fikk sin forventning riktig oppdatert fra 403 til 404 (raden
|
||||
slettes nå, blokkeres ikke lenger). Alle 156 backend-tester grønne.
|
||||
|
||||
**Rullet ut 2026-08-20** -- bruker bekreftet ("Suprt! Da kjører vi
|
||||
på!"), etter en presiseringsrunde om hva "fjernes" faktisk betyr
|
||||
(deselekteres fra runden, IKKE fjernet fra deltakerlisten eller
|
||||
spillerpoolen). `docker compose build teecup_api teecup_frontend &&
|
||||
up -d`, begge containere friske, rene logger. Ingen migrasjon
|
||||
nødvendig.
|
||||
|
||||
145. **Sorterbare kolonner i Spillere-tabellen (turneringsoppsett),
|
||||
2026-08-20.** V0-prompt (`v0-prompt-players-table-sort.md`, sortering
|
||||
ALENE -- en tidligere prompt som også inkluderte en bulk-
|
||||
utslagssted-flyt ble uttrykkelig trukket av bruker: "Jeg glemmer at
|
||||
sjekkboksene er for HVEM SOM SKAL SPILLE RUNDEN. Ikke gjør hva jeg
|
||||
ba deg om (med unntak av sorteringsmuligheten)"). V0-mønsteret
|
||||
(klikk header -> stigende -> synkende -> opprinnelig rekkefølge,
|
||||
`aria-sort`, pil-indikator kun på aktiv kolonne, ekte fokuserbar
|
||||
knapp) integrert i den ekte `tournament-players-table.tsx` for de syv
|
||||
ikke-runde-kolonnene (Spiller/Hcp/Klasse/Statistikknivå/Status/
|
||||
Kjønn/Alder) -- runde-kolonnene og handlingskolonnen forblir
|
||||
usorterbare, urørt.
|
||||
|
||||
Klasse-sortering slår opp klassenavn via `classId` (`classNameById`,
|
||||
utledet fra `classes`-proppen); statistikknivå/status sorteres etter
|
||||
en meningsfull rangering (mengde sporing / alvorlighet), ikke
|
||||
alfabetisk. Null-verdier sorteres alltid sist, uansett retning.
|
||||
|
||||
**Verifisert i scratch mot den EKTE komponenten** (ikke V0-mocken):
|
||||
egen `tmp-preview`-rute som monterer `TournamentPlayersTable` direkte
|
||||
med realistisk mock-data, `evaluate_script`-sjekker av faktisk
|
||||
radrekkefølge OG `aria-sort`-verdi gjennom alle tre klikk-sykluser
|
||||
(stigende/synkende/opprinnelig) for både numerisk (Hcp) og
|
||||
oppslags-basert (Klasse) sortering -- begge korrekte, inkludert
|
||||
null-sist-oppførsel. `tsc --noEmit` rent. Scratch-ruten slettet
|
||||
etterpå, bekreftet med `git status --short`.
|
||||
|
||||
**Rullet ut 2026-08-20** -- samlet med #144. Ren frontend, samme
|
||||
`docker compose build teecup_frontend && up -d`, rene logger.
|
||||
|
||||
146. **Flytende "Registrer score" forsvant helt ved mange hindringer,
|
||||
2026-08-20.** Bruker viste skjermbilde: knappen manglet når hullet
|
||||
hadde mange registrerte hindringer -- selv om banekartet ALDRI ble
|
||||
utvidet.
|
||||
|
||||
Rot-årsak: den flytende knappens synlighet var styrt av `mapExpanded`
|
||||
alene (#140-#142). Feil premiss -- ADR-083 gjorde at
|
||||
"compact"-visningen (kartet IKKE utvidet) OGSÅ viser hele
|
||||
hindringslisten, ikke bare nærmeste. På et hull med mange hindringer
|
||||
(7 i brukerens tilfelle) blir denne listen alene høy nok til å dytte
|
||||
den vanlige side-flyt-knappen utenfor synlig område -- akkurat den
|
||||
situasjonen den flytende knappen skulle dekke, men trigget aldri
|
||||
fordi `mapExpanded` fortsatt var `false`.
|
||||
|
||||
Rettet ved å bytte ut det indirekte signalet (`mapExpanded`) med et
|
||||
direkte: er selve side-flyt-knappen faktisk synlig akkurat nå. Ny
|
||||
`inFlowButtonRef` + `inFlowButtonVisible`-tilstand, målt med samme
|
||||
`getBoundingClientRect()` + scroll/resize-lytter-mønster som
|
||||
`playerListReached` (ikke IntersectionObserver, se begrunnelse i
|
||||
kodekommentaren fra #141). Side-flyt-knappen fjernet fra sin
|
||||
`{!mapExpanded && ...}`-betingelse -- ligger nå ALLTID i normal flyt,
|
||||
uansett kart-tilstand. Den flytende knappen vises når
|
||||
`!inFlowButtonVisible && !playerListReached` (før: `mapExpanded &&
|
||||
!playerListReached`).
|
||||
|
||||
**Verifisert i scratch, ikke bare gjennomgått:** egen
|
||||
`tmp-preview`-rute som monterer den EKTE `RoundDetail` (kun
|
||||
`roundId`-prop, ingen egen mock-versjon), med `window.fetch`-mock for
|
||||
runde/deltakere/hull-data og et hindringssett som gjenskaper
|
||||
brukerens skjermdump nøyaktig (7 hindringer, samme typer/avstander).
|
||||
`evaluate_script`-målt gjennom fire scenarioer: (1) mange hindringer,
|
||||
kart ALDRI utvidet -- flytende knapp korrekt synlig
|
||||
(`aria-hidden="false"`) siden side-flyt-knappen satt bak headeren;
|
||||
(2) scroll til side-flyt-knappen faktisk er fri av headeren -- flytende
|
||||
knapp korrekt skjult; (3) hull UTEN hindringer -- flytende knapp
|
||||
forblir skjult hele veien, ingen regresjon; (4) kart utvidet (det
|
||||
opprinnelige brukstilfellet) -- samme korrekte oppførsel som før,
|
||||
pluss `playerListReached`-skjuling ved scroll til spillerlisten
|
||||
fortsatt intakt. `tsc --noEmit` rent. Scratch-ruten slettet etterpå,
|
||||
bekreftet med `git status --short`.
|
||||
|
||||
**Rullet ut 2026-08-20** -- bruker bekreftet ("Bygg og deploy").
|
||||
`docker compose build teecup_frontend && up -d`, container frisk,
|
||||
rene logger. Ingen migrasjon, ren frontend.
|
||||
|
||||
147. **Tre ting i "Ny runde"-veiviseren, 2026-08-20 (bruker, skjermdump av
|
||||
Spillere-steget).**
|
||||
|
||||
1. **"Administrer runde"-overleggsmenyen lukket seg ikke selv etter
|
||||
"Spillere og runde" ble trykket** -- måtte lukkes manuelt for å se
|
||||
siden under. Rot-årsak: `<Link href={manageHref}>` i
|
||||
`ManageRoundDialog` (round-header.tsx) navigerer ofte KUN til en
|
||||
søkeparameter-endring (`?tab=manage`) på samme rute -- ingen
|
||||
remount, så dialogens lokale `manageOpen`-state (eid av
|
||||
`RoundHeader`) forble uendret. Rettet med `onClick={onClose}` på
|
||||
selve lenken, i tillegg til navigasjonen.
|
||||
|
||||
2. **Kunne ikke overstyre HCP for en nylig lagt til, kontokoblet
|
||||
medspiller i selve veiviseren** -- feltet viste kun en read-only
|
||||
"X · hentes fra profilen"-tekst. Fungerte allerede via "Runde og
|
||||
runde" (PATCH .../participants/{id}) senere i runden, men ikke fra
|
||||
start. To lag:
|
||||
- **Backend** (`add_participant`, app/routers/rounds.py): POST-
|
||||
endepunktet ignorerte `body.handicap_index` HELT for en
|
||||
`user_id`-koblet deltaker (brukte alltid profilens verdi
|
||||
direkte) -- ulikt PATCH-endepunktet (`update_participant`), som
|
||||
allerede æret en eksplisitt overstyring for enhver deltaker,
|
||||
ikke bare gjester (bekreftet i kode: `guest_only_fields`-sperren
|
||||
ekskluderer bevisst `handicap_index`). Rettet til `body.
|
||||
handicap_index if body.handicap_index is not None else target
|
||||
["handicap_index"]`, i tråd med ADR-038 sin allerede dokumenterte
|
||||
"MANUELT satt ... med mindre eksplisitt overstyrt"-modell.
|
||||
- **Frontend** (`step3-players.tsx`): HCP-feltet for en
|
||||
kontokoblet, ikke-eier-spiller gjort redigerbart (samme `Field`/
|
||||
`TextInput`-mønster som allerede brukt for gjester i samme fil),
|
||||
forhåndsutfylt med profilverdien, urørt betyr fortsatt "bruk
|
||||
profilen". `wizard-context.tsx` sin `submit()` sender nå
|
||||
`handicap_index: p.hcp ?? null` også for kontokoblede
|
||||
deltakere (uendret verdi er en trygg no-op, siden backend
|
||||
faller tilbake til profilen når feltet er urørt).
|
||||
- Ny backend-test `test_add_participant_hcp_override.py` (2 tester
|
||||
-- overstyring æres, OG regresjonsvern: uendret oppførsel når
|
||||
ingen overstyring gis), kjørt mot scratch-database
|
||||
(`./scripts/run_backend_tests.sh`), alle 158 tester grønne.
|
||||
|
||||
3. **Standard statistikknivå for en NY medspiller var "Alt", skal
|
||||
være "Kun slag"** -- `defaultStat`-proppen til `AddPlayerPanel`
|
||||
speilet feilaktig `state.statLevel` (scoreførerens EGET valgte
|
||||
nivå fra "Spilleform"-steget), ikke et fast "Kun slag"-utgangs-
|
||||
punkt for ANDRE spillere. Bekreftet ved kodegjennomgang: en
|
||||
tilstøtende kommentar i wizard-context.tsx (fra en tidligere,
|
||||
urelatert rettelse 2026-08-15) dokumenterer eksplisitt at
|
||||
`defaultStat` alltid var MENT som "default for NYE medspillere",
|
||||
atskilt fra eierens eget felt -- speilingen var en glipp, ikke et
|
||||
bevisst valg. Rettet til en fast `"score"` i `step3-players.tsx`.
|
||||
Organisatoren kan fortsatt sette et høyere nivå manuelt per
|
||||
medspiller.
|
||||
|
||||
**Verifisert i scratch, ikke bare gjennomgått, for alle tre:**
|
||||
(1) egen `tmp-preview`-rute som monterer den EKTE `RoundHeader`,
|
||||
bekreftet via `evaluate_script` at dialogen (`[role="dialog"]`) er
|
||||
borte fra DOM-en umiddelbart etter klikk+navigasjon, ingen manuell
|
||||
lukking nødvendig. (2)+(3) egen `tmp-preview`-rute som monterer den
|
||||
EKTE `WizardProvider` + `Step3Players` (med `window.fetch`-mock for
|
||||
`/auth/me` og `/people/search`), drevet gjennom hele den ekte søk-og-
|
||||
legg-til-flyten (søkte "Morten", la til kontoen, ekspanderte kortet)
|
||||
-- bekreftet HCP-feltet er en ekte, redigerbar `<input>` forhånds-
|
||||
utfylt med 11.1, aksepterer et desimaltall (satt direkte via
|
||||
`dispatchEvent` for å utelukke en `fill`-verktøy-særegenhet som først
|
||||
strippet punktumet), OG at "Kun slag" er forhåndsvalgt for den nylig
|
||||
lagte-til spilleren. `tsc --noEmit` rent gjennom hele. Begge
|
||||
scratch-rutene slettet etterpå, bekreftet med `git status --short`.
|
||||
|
||||
**Rullet ut 2026-08-20** -- bruker bekreftet ("Ja takk").
|
||||
`docker compose build teecup_api teecup_frontend && up -d`, begge
|
||||
containere friske, rene logger. Ingen migrasjon.
|
||||
|
||||
148. **Hindringslisten sortert feil vei + kartretning ved slagmåling nå
|
||||
styrt av ekte utslag→green-geometri, 2026-08-21.** Bruker, med
|
||||
skjermdump: holdes telefonen loddrett for avstandsmåling, bør det
|
||||
som er lengst unna (greenen) stå øverst i lista og det nærmeste
|
||||
(utslaget) nederst, med hindringene sortert i SAMME rekkefølge
|
||||
imellom -- listen viste tidligere motsatt (nærmeste hindring øverst,
|
||||
rett attmed greenen). Presisert: der en hindring har både forkant og
|
||||
bakkant vist, er det BAKKANTEN (fjerneste kant) som skal styre
|
||||
sorteringen.
|
||||
|
||||
To sorteringssteder i `hole-target-distance.tsx` rettet fra stigende
|
||||
til synkende (lengst unna FØRST): `groupDiagramHazards()` sin
|
||||
`entities.sort(...)` (den parrede forkant/bakkant-visningen, brukt av
|
||||
`HoleDiagram` -- nøkkel endret fra alltid `below` til `above ?? below`,
|
||||
altså bakkanten når en finnes), og den enklere flate listen (`hazards
|
||||
.sort(...)`, brukt når banen mangler tee-koordinater -- ingen
|
||||
forkant/bakkant-parring der, kun ett tall per punkt).
|
||||
|
||||
**Samme runde, andre delen av brukerønsket:** på baner med BÅDE
|
||||
utslags- OG green-koordinater kjent, skal selve satellittkartet i
|
||||
slagmåleren ("Mål et slag") vises med greenen opp/utslaget ned, ikke
|
||||
nord opp. `initialBearing`-mekanismen fantes allerede (bygget
|
||||
2026-08-10, roterte kartet etter spillerens EGEN forrige slag-
|
||||
retning på hullet, `bearingDegrees(forrige slag start, slutt)`) --
|
||||
denne er nå supplert med en NY, mer pålitelig kilde: `ShotMeasurement
|
||||
Entry` (fellet-komponenten brukt fra alle tre stedene i filen
|
||||
slagmåling kan åpnes fra: kompakt spillerkort, delt-ball-sidebadge,
|
||||
og full-skjerm-veiviserens "Retning"-steg) henter nå selv hullets
|
||||
`target-points`, regner ut `bearingDegrees(midtpunkt(utslag front/
|
||||
bakkant), green senter)`, og lar DENNE vinne over forrige-slag-
|
||||
gjetningen når den finnes -- ekte banegeometri er mer pålitelig enn
|
||||
en tilfeldig sleng/hook på forrige slag. Egen, liten fetch per
|
||||
spillerkort (i stedet for å prop-drille et tall gjennom RoundDetail/
|
||||
PlayerHoleCards/ScoringWizard for å dele HoleTargetDistance sin
|
||||
allerede-eksisterende henting) -- en akseptert kostnad for at ALLE
|
||||
tre inngangene til kartet får riktig retning samtidig, ikke bare én.
|
||||
|
||||
**Verifisert i scratch, presist, ikke bare gjennomgått:** egen
|
||||
`tmp-preview`-rute som monterer den EKTE `RoundDetail`, med
|
||||
`window.fetch`-mock for `target-points` (utslag+green forskjøvet til
|
||||
en bevisst IKKE-kardinal (ikke nord/øst/sør/vest) retning, for å
|
||||
fange opp en feil som ved et uhell falt tilbake til "ingen
|
||||
rotasjon"). Ekte `NEXT_PUBLIC_MAPBOX_TOKEN` lest fra `.env` inn i
|
||||
scratch-serverens miljø (aldri skrevet i klartekst noe sted).
|
||||
`mapboxgl.Map`-konstruktøren instrumentert (kun i scratch, aldri i
|
||||
kildekoden) til å fange opp `bearing`-verdien den faktisk mottok.
|
||||
Gikk gjennom hele den ekte flyten (ekspander spillerkort -> "Mål et
|
||||
slag" -> "Velg punkt på kart") og bekreftet numerisk: forventet
|
||||
`19.02°` (regnet uavhengig, samme formel, i selve scratch-siden) mot
|
||||
faktisk mottatt `19.016306...°` -- match. Selve korttavlerenderingen
|
||||
feilet med "Kunne ikke laste kartet" pga. manglende ekte nettverks-
|
||||
tilgang til Mapbox sine tile-servere i dette sandkasse-miljøet
|
||||
(urelatert til retting -- `bearing`-argumentet appliseres synkront
|
||||
ved konstruksjon, uavhengig av om selve kart-flisene faktisk laster).
|
||||
`tsc --noEmit` rent. Scratch-ruten slettet etterpå, bekreftet med
|
||||
`git status --short`.
|
||||
|
||||
**Ikke rullet ut ennå.**
|
||||
|
|
|
|||
Loading…
Reference in a new issue