Ny tournament_round_shot-tabell (org-scopet RLS, FK-et til tournament_round_participant + hole_number siden tournament_round_hole kanskje ikke finnes ennå). ShotMeasurementSheet/MapPointPicker gjenbrukt uendret; ShotMeasurementEntry generalisert fra en lokal round-detail.tsx- funksjon til en delt, URL-parameterisert komponent. Deling går til den rundespesifikke kommentartråden (ADR-102) i stedet for Banter Board. Autorisasjon speiler update_hole (self/org-admin), strengere enn ADR-102s kommentar-nivå. Migrasjon 091 IKKE kjørt mot ekte teecup_db ennå -- venter på brukerbekreftelse før utrulling. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
75 lines
4.2 KiB
SQL
75 lines
4.2 KiB
SQL
-- =====================================================================
|
|
-- TeeCup — Slag-for-slag GPS-avstandsmåling for org-turneringer,
|
|
-- migrasjon 091 (ADR-103). Speiler 060_round_shot.sql/
|
|
-- 061_round_shot_end_method.sql (ADR-048, frittstående runder)
|
|
-- strukturelt, men org-scopet (RLS) og med en annen eierskaps-nøkkel.
|
|
--
|
|
-- Eierskap: FK direkte til (organization_id, tournament_round_
|
|
-- participant_id) + hole_number -- IKKE tournament_round_hole_id.
|
|
-- `tournament_round_hole` opprettes (ulikt frittstående round_hole,
|
|
-- som pre-oppretter alle 18 ved rundestart) FØRST ved første
|
|
-- score-innsending (update_hole sin INSERT ... ON CONFLICT,
|
|
-- individual_tournaments.py) -- en spiller skal kunne måle et slag
|
|
-- FØR de fullfører hullets score, så en FK mot en hull-rad som kanskje
|
|
-- ikke finnes ennå ville vært feil. Samme LEFT JOIN-tolerante mønster
|
|
-- som get_tournament_round_hole_target_points/list_round_participant_
|
|
-- holes allerede bruker for nøyaktig dette problemet.
|
|
--
|
|
-- Turneringsmodellen har ALDRI en side/lag-XOR (kun individuelt) --
|
|
-- ingen tilsvarende round_side-gren trengs her, ulikt round_shot.
|
|
--
|
|
-- Koordinater: samme rene double precision lat/lng-par som round_shot
|
|
-- (ADR-048 Beslutning D) -- ingen PostGIS.
|
|
-- =====================================================================
|
|
\set ON_ERROR_STOP on
|
|
|
|
CREATE TABLE tournament_round_shot (
|
|
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
organization_id uuid NOT NULL,
|
|
tournament_round_participant_id uuid NOT NULL,
|
|
hole_number smallint NOT NULL CHECK (hole_number BETWEEN 1 AND 18),
|
|
|
|
-- Hvem som MÅLTE slaget -- ikke nødvendigvis samme som deltakeren selv,
|
|
-- samme "en lenket medspiller/org-admin kan føre" som update_hole.
|
|
recorded_by_user_id uuid NOT NULL REFERENCES app_user(id),
|
|
|
|
-- Eksplisitt, hull-tolerant rekkefølge (IKKE ORDER BY captured_at) --
|
|
-- samme begrunnelse som round_shot.shot_number.
|
|
shot_number integer NOT NULL CHECK (shot_number > 0),
|
|
|
|
club text NOT NULL CHECK (char_length(club) <= 50),
|
|
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_method text NOT NULL CHECK (end_method IN ('gps', 'map_tap')) DEFAULT 'gps',
|
|
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 den rundespesifikke kommentartråden (ADR-102) -- lenke,
|
|
-- ikke bare et bool-flagg, samme prinsipp som round_shot.
|
|
shared_tournament_round_message_id uuid REFERENCES tournament_round_message(id) ON DELETE SET NULL,
|
|
|
|
captured_at timestamptz NOT NULL DEFAULT now(),
|
|
|
|
FOREIGN KEY (organization_id, tournament_round_participant_id)
|
|
REFERENCES tournament_round_participant(organization_id, id) ON DELETE CASCADE,
|
|
UNIQUE (tournament_round_participant_id, hole_number, shot_number)
|
|
);
|
|
|
|
CREATE INDEX ON tournament_round_shot (organization_id, tournament_round_participant_id, hole_number, shot_number);
|
|
|
|
DO $$
|
|
BEGIN
|
|
ALTER TABLE tournament_round_shot ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE tournament_round_shot FORCE ROW LEVEL SECURITY;
|
|
CREATE POLICY org_isolation ON tournament_round_shot
|
|
USING (organization_id = current_setting('app.current_org', true)::uuid)
|
|
WITH CHECK (organization_id = current_setting('app.current_org', true)::uuid);
|
|
END $$;
|
|
|
|
-- Samme "slett og opprett på nytt, aldri rediger"-prinsipp som round_shot
|
|
-- -- ett smalt UPDATE-unntak for delings-lenken.
|
|
GRANT SELECT, INSERT, DELETE ON tournament_round_shot TO teecup_app;
|
|
GRANT UPDATE (shared_tournament_round_message_id) ON tournament_round_shot TO teecup_app;
|