ADR-081/CHANGELOG: rangefinder for offisielle baner rullet ut
Migrasjon 079 kjørt og teecup_api/teecup_frontend rullet ut 2026-08-17 etter bekreftelse fra bruker. Tjømes offisielle bane fylt med de 180 feltbefarte koordinatene fra forrige runde. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
93af7c5bef
commit
366582d3ef
2 changed files with 183 additions and 0 deletions
|
|
@ -7979,6 +7979,136 @@ etterpå.
|
|||
|
||||
---
|
||||
|
||||
## ADR-081: Rangefinder-koordinater for offisielle (TeeOff-koblede) baner (migrasjon 079) (2026-08-17)
|
||||
|
||||
Foranledning: forrige runde erstattet koordinatene på Erol sin
|
||||
PERSONLIGE Tjøme-bane (`personal_course`, GolfAPI-cache). Brukeren
|
||||
påpekte at dette ikke er banen org-turneringer faktisk spilles på --
|
||||
"Tjøme Gents" sin offisielle, TeeOff-koblede bane (`course.source=
|
||||
'official'`, `external_course_ref='tjome-golfklubb:140'`) er en helt
|
||||
separat rad, og har ALDRI hatt koordinatdata i det hele tatt. Brukeren
|
||||
ba om samme koordinater der også, OG at dette skal være en generell,
|
||||
gjenbrukbar mulighet for ALLE offisielle baner fremover -- ikke en
|
||||
engangsfiks til.
|
||||
|
||||
Rangefinder-funksjonalitet (avstand til green/hindringer, GPS-basert)
|
||||
fantes til nå KUN for GolfAPI-importerte personlige baner. Verken
|
||||
org-turneringer (individuell slagspill ELLER lag-matchplay) hadde noen
|
||||
rangefinder i det hele tatt -- og selv frittstående runder spilt på en
|
||||
EKTE teeoff-bane (`round.course_source='teeoff'`) fikk tom liste, samme
|
||||
underliggende hull (ingen koordinatkilde for teeoff-baner). Løsningen
|
||||
dekker derfor tre steder for prisen av én delt backend-brikke.
|
||||
|
||||
**Bekreftet med bruker (AskUserQuestion):** rangefinderen skulle wires
|
||||
inn i BEGGE org-turnering-scoringsflytene i samme runde (individuell
|
||||
slagspill OG lag-matchplay), ikke én med den andre som senere sak --
|
||||
til tross for at ingen aktiv runde fantes på den offisielle Tjøme-banen
|
||||
ennå (fremtidsrettet grunnlag, ikke en akutt "vis det nå"-fiks).
|
||||
|
||||
**Gjenbrukt, ikke oppfunnet på nytt:** `app/hole_history.py` hadde
|
||||
ALLEREDE nøyaktig den bane-bro-abstraksjonen dette trengte fra ADR-072:
|
||||
`CourseKey = tuple[Literal["teeoff"], str, str] | tuple[Literal[
|
||||
"golfapi"], str]`, med `resolve_personal_round_course_key()` og
|
||||
`resolve_tournament_round_course_key()`. Tredje søster `resolve_match_
|
||||
course_key()` (match->session->course, lag-matchplay) lagt til ved
|
||||
siden av de to andre, identisk mønster.
|
||||
|
||||
**Ny delt backend-modul `app/target_points.py`:** `get_target_points
|
||||
(conn, course_key, hole_number)` grener på `course_key[0]` -- `"teeoff"`
|
||||
slår opp den nye `teeoff_course_coordinate`, `"golfapi"` slår opp
|
||||
eksisterende `golfapi_course_coordinate` (uendret spørring). Ingen RLS
|
||||
på noen av kildetabellene (globale, delt på tvers av organisasjoner/
|
||||
brukere som tilfeldigvis bruker samme fysiske bane), så samme funksjon
|
||||
virker uansett om `conn` kommer fra `plain_connection()` eller
|
||||
`org_connection()`. Tre tynne kallesteder: `rounds.py` sitt eksisterende
|
||||
endepunkt REFAKTORERT til dette mønsteret (villet sideeffekt:
|
||||
frittstående runder på en ekte teeoff-bane får nå rangefinder for
|
||||
første gang), nytt endepunkt i `individual_tournaments.py`, nytt
|
||||
endepunkt i `scoring.py` (tilgangssjekk speiler `get_scorecard`: org-
|
||||
medlem ELLER deltaker i turneringen).
|
||||
|
||||
**Migrasjon 079, del 1 -- delte domener.** To runder på rad (067:
|
||||
rock/layup, 078: landmark) måtte hver for seg utvide DEN SAMME
|
||||
poi_type-CHECK-listen i `golfapi_course_coordinate`. Å innføre en ny
|
||||
tabell med en IDENTISK, dupliserende CHECK-liste ville gjort dette
|
||||
vedlikeholdsproblemet permanent. Løst med `CREATE DOMAIN course_poi_
|
||||
type`/`course_poi_location`/`course_poi_side` -- én kilde til sannhet,
|
||||
brukt av BEGGE tabeller. Eksisterende `golfapi_course_coordinate`-kolonner
|
||||
konvertert til domenene (additivt, ingen datatap).
|
||||
|
||||
**Migrasjon 079, del 2 -- `teeoff_course_coordinate`.** Samme
|
||||
kolonneform som `golfapi_course_coordinate`, men nøkkel er `course.
|
||||
external_course_ref` (tekst, IKKE en FK -- speiler at `external_course_
|
||||
ref` selv er en myk referanse, ingen global "teeoff_course"-tabell
|
||||
finnes å FK-e mot). GLOBAL (ikke org-scopet, ingen RLS) -- samme
|
||||
begrunnelse som `golfapi_course_coordinate`: flere organisasjoner kan
|
||||
importere samme fysiske bane fra teeoff hver sin `course`-rad,
|
||||
koordinatene skal deles, ikke registreres på nytt per organisasjon.
|
||||
|
||||
**Ny skrive-vei (`courses.py`): `PUT`/`GET .../courses/{id}/coordinates`.**
|
||||
400 hvis banen ikke er `source='official'`. Full erstatning i én
|
||||
transaksjon (samme "erstatt hele settet"-semantikk brukeren ba om for
|
||||
Tjøme). Autorisasjon: `get_authorized_org` -- samme bar som ALLE andre
|
||||
course-muterende endepunkter i denne filen (ingen strengere rolle-sjekk,
|
||||
matcher eksisterende presedens). Selve tolkningsarbeidet (fritekst-navn
|
||||
på feltbefarte punkter -> `poi_type`/`location`/`side_fairway`) er
|
||||
BEVISST IKKE automatisert -- krever dømmekraft (bekreftet konkret av
|
||||
denne rundens egen Tjøme-erfaring: "Voll"/"Bjella" kunne ikke vært
|
||||
gjettet av et script). Capabiliten som åpnes er lagrings-/gjenbrukslaget;
|
||||
selve kartleggingen gjøres fortsatt av bruker+Claude sammen per bane.
|
||||
|
||||
**Frontend:** `HoleTargetDistance` (allerede en fritt gjenbrukbar,
|
||||
selvstendig komponent -- egen fetch+GPS, selvskjulende ved tom data)
|
||||
generalisert fra `roundId`-prop til `baseUrl`-prop, slik at alle tre
|
||||
kallesteder (frittstående runde `/rounds/{id}`, individuell org-
|
||||
turnering `/orgs/{org}/tournaments/{t}/rounds/{r}`, lag-matchplay
|
||||
`/orgs/{org}/matches/{m}`) kan gjenbruke samme komponent uendret utover
|
||||
selve URL-en. Limt inn persistent (uansett steg) i `HoleStatsSheet`
|
||||
(individuell slagspill) og som en ny betinget blokk i `session-
|
||||
scorecard.tsx` sin hull-`<section>` (lag-matchplay, samme
|
||||
plasseringsmønster som `NassauPanel`).
|
||||
|
||||
**Verifisert:**
|
||||
1. `tests/test_target_points.py`, 11 nye tester -- `get_target_points()`
|
||||
begge grener, `resolve_match_course_key()` alle tre utfall, alle tre
|
||||
GET-endepunktene + skrive-veien (inkl. 400 på ikke-offisiell bane,
|
||||
full erstatning, tilgangskontroll). Full backend-suite: 106/106
|
||||
bestått. `tsc --noEmit` rent + 45/45 vitest.
|
||||
2. Scratch-database (alle migrasjoner 001-079 anvendt) + scratch
|
||||
`teecup_api` + lokal `next dev`: én org med offisiell bane, koordinater
|
||||
satt via det nye PUT-endepunktet over ekte HTTP (verifisert tilbake
|
||||
via GET), én individuell turnering-runde og én match-play-økt på
|
||||
samme bane. Rangefinder bekreftet korrekt koblet i BEGGE UI-ene
|
||||
(nettverksspor viste riktig `target-points`-kall med riktige 6 punkter
|
||||
for hull 4, tom liste for hull 5 -- komponenten viste følgelig "venter
|
||||
på GPS"-tilstanden på hull 4 og INGEN rad i det hele tatt på hull 5,
|
||||
nøyaktig den designede selvskjulende oppførselen). Lys+mørk bekreftet
|
||||
begge steder. Regresjonssjekk: en frittstående GolfAPI-personlig-bane-
|
||||
runde satt opp i samme scratch-miljø, bekreftet identisk oppførsel
|
||||
som før refaktoreringen (data på hull med koordinater, ingen rad på
|
||||
hull uten). Scratch-stacken fullstendig revet ned (Docker-container,
|
||||
database+rolle, MinIO-bucket, `next dev`) -- ekte `teecup_db` urørt
|
||||
gjennom hele verifiseringen.
|
||||
3. Migrasjon 079 vist og bekreftet av bruker før kjøring mot ekte
|
||||
`teecup_db` (additiv -- tre domener + én ny tabell, eksisterende
|
||||
`golfapi_course_coordinate`-data verifisert uendret etterpå, 399
|
||||
rader).
|
||||
|
||||
**Rullet ut 2026-08-17** -- bruker bekreftet ("Git commit og rull ut").
|
||||
Migrasjon 079 kjørt mot ekte `teecup_db`, deretter `docker compose
|
||||
build teecup_api teecup_frontend && up -d`. Rene containerlogger,
|
||||
`https://teecup.golf/logg-inn` bekreftet 200 OK. Deretter fylt Tjømes
|
||||
offisielle bane ("Tjøme Golfklubb – Hovedbanen", org "Tjøme Gents") med
|
||||
de samme 180 feltbefarte koordinatene som ble bekreftet mot den
|
||||
personlige banen i forrige runde (samme mapping-beslutninger gjenbrukt
|
||||
direkte, ikke re-avklart) -- kjørt via et engangsskript i `teecup_api`-
|
||||
containeren mot det NYE endepunktets underliggende tabell (samme
|
||||
DELETE+INSERT-logikk som `PUT`-endepunktet selv bruker), bekreftet
|
||||
180/180 rader med korrekt `poi_type`-fordeling direkte mot databasen
|
||||
etterpå.
|
||||
|
||||
---
|
||||
|
||||
## Utviklingsplan (rekkefølge)
|
||||
|
||||
1. ✅ Land tenant-modell → **Organisasjon** (ADR-001/002/003)
|
||||
|
|
|
|||
53
CHANGELOG.md
53
CHANGELOG.md
|
|
@ -11870,3 +11870,56 @@ Neste steg:
|
|||
direkte mot databasen etterpå: riktig `poi_type`-fordeling, `landmark`-
|
||||
punktene og de tre hull-4-bunkerne til stede med korrekte
|
||||
koordinater. Ingen kodeendring -- ingen container-restart nødvendig.
|
||||
|
||||
98. **Rangefinder-koordinater for offisielle (TeeOff-koblede) baner
|
||||
(ADR-081, migrasjon 079) — 2026-08-17.** Bruker påpekte at forrige
|
||||
rundes Tjøme-koordinater havnet på Erol sin PERSONLIGE GolfAPI-bane,
|
||||
ikke den offisielle TeeOff-koblede banen "Tjøme Gents" faktisk
|
||||
bruker til org-turneringer -- og ba om at koordinatene også legges
|
||||
inn der, OG at dette blir en generell mulighet for alle offisielle
|
||||
baner fremover.
|
||||
|
||||
Rangefinder fantes til nå kun for GolfAPI-importerte personlige
|
||||
baner -- verken org-turneringer (individuell slagspill/lag-matchplay)
|
||||
eller frittstående runder på en EKTE teeoff-bane hadde noen
|
||||
koordinatkilde. Bekreftet med bruker (AskUserQuestion): begge
|
||||
org-turnering-scoringsflytene wires inn i samme runde, ikke faset.
|
||||
|
||||
Migrasjon 079: delte domener (`course_poi_type`/`location`/`side`)
|
||||
for å stoppe et allerede observert vedlikeholdsproblem (067 og 078
|
||||
måtte begge utvide samme dupliserte CHECK-liste), ny global tabell
|
||||
`teeoff_course_coordinate` (nøkkel `course.external_course_ref`, samme
|
||||
"delt cache, ikke per-org"-begrunnelse som `golfapi_course_
|
||||
coordinate`). Ny delt modul `app/target_points.py` +
|
||||
`resolve_match_course_key()` (tredje søster til de to eksisterende
|
||||
bane-bro-funksjonene i `hole_history.py`, ADR-072) -- alle tre
|
||||
kallesteder (frittstående runder, individuell org-turnering,
|
||||
lag-matchplay) bruker nå samme `CourseKey`-abstraksjon. `rounds.py`
|
||||
sitt eksisterende endepunkt refaktorert til samme mønster (villet
|
||||
sideeffekt: frittstående runder på en ekte teeoff-bane får nå også
|
||||
rangefinder). Ny skrive-vei `PUT`/`GET .../courses/{id}/coordinates`
|
||||
i `courses.py` -- generell, gjenbrukbar, ikke en engangsfiks.
|
||||
`HoleTargetDistance` generalisert (`roundId` -> `baseUrl`-prop) og
|
||||
wiret inn i `HoleStatsSheet` (individuell slagspill) og `session-
|
||||
scorecard.tsx` (lag-matchplay, samme mønster som `NassauPanel`).
|
||||
|
||||
**Verifisert:** `tests/test_target_points.py`, 11 nye tester (106/106
|
||||
backend totalt). `tsc --noEmit` rent + 45/45 vitest. Scratch-database
|
||||
+ scratch `teecup_api` + lokal `next dev`: koordinater satt via det
|
||||
nye PUT-endepunktet over ekte HTTP, rangefinder bekreftet korrekt i
|
||||
BEGGE org-turnering-UI-ene (riktig data på hull med koordinater,
|
||||
ingen synlig rad på hull uten -- nettverksspor bekreftet nøyaktig
|
||||
hvilke punkter som ble hentet). Lys+mørk bekreftet begge steder.
|
||||
Regresjonssjekk: eksisterende GolfAPI-personlig-bane-rangefinder
|
||||
satt opp i samme scratch-miljø, bekreftet uendret oppførsel etter
|
||||
refaktoreringen. Scratch-stacken fullstendig revet ned.
|
||||
|
||||
**Rullet ut 2026-08-17** -- bruker bekreftet ("Git commit og rull
|
||||
ut"). Migrasjon 079 kjørt mot ekte `teecup_db` (eksisterende
|
||||
`golfapi_course_coordinate`-data verifisert uendret, 399 rader),
|
||||
deretter `docker compose build teecup_api teecup_frontend && up -d`.
|
||||
Rene containerlogger, `https://teecup.golf/logg-inn` 200 OK. Tjømes
|
||||
offisielle bane fylt med de samme 180 koordinatene fra forrige runde
|
||||
(samme mapping gjenbrukt, ikke re-avklart) via et engangsskript i
|
||||
`teecup_api`-containeren mot det nye endepunktets tabell -- bekreftet
|
||||
180/180 rader med korrekt `poi_type`-fordeling.
|
||||
|
|
|
|||
Loading…
Reference in a new issue