-- ===================================================================== -- TeeCup — Slag-for-slag GPS-avstandsmåling, migrasjon 060 (ADR-048). -- -- IKKE en gjenåpning av ADR-033s avvisning av fri slag-for-slag-logging -- som DATAMODELL for hull-statistikk. Dette er en separat, valgfri -- måle-funksjon: spilleren kan måle avstanden på ett eller flere -- enkeltslag med GPS, uavhengig av det faste hull-statistikk-skjemaet. -- `round_hole` sine faste felt (club_off_tee, putts, osv.) er UBERØRT. -- -- Eierskap: round_shot henger kun av round_hole.id -- IKKE direkte av -- round_participant_id/round_side_id. round_hole har allerede en XOR -- mellom disse to (round_hole_owner_xor, migrasjon 031), så round_shot -- arver eierskapet (individuell ELLER lagformat) transitivt uten å -- duplisere XOR-logikken selv. Dette dekker BEGGE hull-typer fra v1 -- (ADR-048 Beslutning C). -- -- Eier-mønster for øvrig: samme non-RLS plain_connection() + WHERE- -- filtrering som resten av frittstående-runde-subsystemet (ADR-033 -- Beslutning A). -- -- Koordinater: rene double precision lat/lng-par, IKKE PostGIS. Volum er -- maks noen titalls rader per runde, og eneste geometriske operasjon er -- punkt-til-punkt storsirkel-avstand (Haversine), regnet CLIENT-SIDE i -- JS -- PostGIS ville vært en ny, tung avhengighet uten reell gevinst -- her (ADR-048 Beslutning D). -- ===================================================================== \set ON_ERROR_STOP on CREATE TABLE round_shot ( id uuid PRIMARY KEY DEFAULT gen_random_uuid(), round_hole_id uuid NOT NULL REFERENCES round_hole(id) ON DELETE CASCADE, -- Hvem som MÅLTE slaget -- ikke nødvendigvis samme som round_hole sin -- eier, en medspiller kan føre for flighten (samme skrive-autorisasjons- -- modell som update_hole/side-PATCH allerede bruker). recorded_by_user_id uuid NOT NULL REFERENCES app_user(id), -- Eksplisitt, hull-tolerant rekkefølge (IKKE ORDER BY captured_at) -- -- lar et slag midt i sekvensen slettes uten omnummerering av resten, -- og unngår at GPS-tidsstempel-drift/bakgrunnsthrottling noensinne -- stille endrer rekkefølgen. shot_number integer NOT NULL CHECK (shot_number > 0), club text NOT NULL CHECK (char_length(club) <= 50), -- Øvre grense 500m er en fornuftssjekk mot GPS-glitch/feiltrykk, ikke -- en golf-regel (lengste realistiske driver ligger rundt 370m). distance_meters numeric(6,1) NOT NULL CHECK (distance_meters > 0 AND distance_meters < 500), start_method text NOT NULL CHECK (start_method IN ('gps', 'map_tap')), start_lat double precision NOT NULL CHECK (start_lat BETWEEN -90 AND 90), start_lng double precision NOT NULL CHECK (start_lng BETWEEN -180 AND 180), end_lat double precision NOT NULL CHECK (end_lat BETWEEN -90 AND 90), end_lng double precision NOT NULL CHECK (end_lng BETWEEN -180 AND 180), -- Deling til rundens kommentarfelt (ADR-044) -- lenke, ikke bare et -- bool-flagg, slik at "delt" alltid reflekterer om meldingen FAKTISK -- finnes (ON DELETE SET NULL: slettes meldingen separat i feeden, -- forblir slaget "målt, men ikke lenger delt", ikke ugyldig). shared_round_message_id uuid REFERENCES round_message(id) ON DELETE SET NULL, captured_at timestamptz NOT NULL DEFAULT now(), UNIQUE (round_hole_id, shot_number) ); CREATE INDEX round_shot_hole_idx ON round_shot (round_hole_id, shot_number); -- INGEN RLS -- samme plain_connection()-mønster som round_message/ -- round_hole (ADR-033 Beslutning A). Autorisasjon i app-laget. GRANT SELECT, INSERT, DELETE ON round_shot TO teecup_app; -- Ingen generell UPDATE-grant -- samme "slett og opprett på nytt, aldri -- rediger"-prinsipp som round_message (et feilmålt slag slettes og måles -- på nytt). ETT eksplisitt, smalt unntak: å knytte et allerede opprettet -- slag til en round_message som opprettes i et eget, påfølgende -- delings-steg (se app/routers/rounds.py, share_shot). GRANT UPDATE (shared_round_message_id) ON round_shot TO teecup_app;