teecup/app/target_points.py
Erol Haagenrud 84f11e1a45 Hull-diagram v2: kategoriske venstre/senter/høyre-akser (ADR-084)
Erstatter ADR-083 sin kontinuerlige crossMeters-forskyvning, som ga for
liten synlig venstre/høyre-forskjell på ekte banedata (Tjøme hull 18).
Baner velges nå kategorisk via side_fairway; green/tee/spiller alltid
på senterakse. Ny hazard_group-kolonne (migrasjon 080, ikke rullet ut
mot ekte DB ennå) lar to punkter eksplisitt pares til én carry-hindring
(forkant+bakkant) uten å risikere å slå sammen to atskilte hindringer
på samme side.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-17 23:36:28 +02:00

61 lines
2.2 KiB
Python

"""
Rangefinder-koordinater (migrasjon 065/079) -- avstand til green/hindringer,
GPS-basert. Delt mellom rounds.py (frittstående runder), individual_
tournaments.py (org-turnering, individuell slagspill) og scoring.py
(org-turnering, lag-matchplay) -- alle tre løser sin egen kontekst om til
samme `CourseKey` (se hole_history.py, som denne modulen gjenbruker banen-
bro-abstraksjonen fra) og kaller `get_target_points()` her.
To kildetabeller, ingen RLS på noen av dem (globale, delt på tvers av
organisasjoner/brukere som tilfeldigvis bruker samme fysiske bane -- samme
begrunnelse som golfapi_course_coordinate alltid har hatt): `golfapi_
course_coordinate` (GolfAPI-importerte baner) og `teeoff_course_coordinate`
(ekte teeoff-baner, migrasjon 079). Fordi ingen av dem er RLS-beskyttet,
virker `get_target_points()` uendret uansett om `conn` kommer fra
`plain_connection()` eller `org_connection()`.
"""
from __future__ import annotations
from asyncpg import Connection
from pydantic import BaseModel
from .hole_history import CourseKey
class TargetPoint(BaseModel):
poi_type: str
location: str | None
side_fairway: str | None
latitude: float
longitude: float
hazard_group: str | None
async def get_target_points(conn: Connection, course_key: CourseKey | None, hole_number: int) -> list[TargetPoint]:
if course_key is None:
return []
kind = course_key[0]
if kind == "teeoff":
_, facility_slug, teeoff_course_id = course_key
rows = await conn.fetch(
"""
SELECT poi_type, location, side_fairway, latitude, longitude, hazard_group
FROM teeoff_course_coordinate
WHERE external_course_ref = $1 AND hole_number = $2
""",
f"{facility_slug}:{teeoff_course_id}",
hole_number,
)
else:
_, golfapi_course_id = course_key
rows = await conn.fetch(
"""
SELECT poi_type, location, side_fairway, latitude, longitude, hazard_group
FROM golfapi_course_coordinate
WHERE golfapi_course_id = $1 AND hole_number = $2
""",
golfapi_course_id,
hole_number,
)
return [TargetPoint(**dict(r)) for r in rows]