teecup/070_flag_plant_individual_tournament.sql
Erol Haagenrud 25bdabe3ea Flaggturnering: GPS-flaggplanting (Del A) + kartoversikt (Del B)
Del A (ADR-066, migrasjon 069/070, allerede rullet ut mot teecup_db):
"Plant flagget" via GPS, med en interaktiv "Hullet du ut?"-bekreftelse
før posisjonen registreres, pluss full runde 2+-scoreføring for
spillere som fullfører 18 hull med slag igjen. Ny, isolert overflow-
tabell (rører ikke delt round_hole/tournament_round_hole). Bygget for
både frittstående runder og org-individuelle turneringer. UI-sheeten
er en Claude-skrevet V0-eksport (zip 11).

Del B (ADR-067, migrasjon 071, klar for utrulling): av/på-bryter
(standard AV) for en satellittkartoversikt over ALLE deltakeres
plantede flagg, lap 1 skilt fra lap 2+ med farge+tekstbadge. Frittstående
runder får full tilskuerstøtte (/watch/[id]); org-individuelle
turneringer er bevisst avgrenset til medlemmer/deltakere, siden ingen
offentlig spectator-side finnes for det turneringsformatet ennå.

Se ARCHITECTURE_DECISIONS.md (ADR-066/067) og CHANGELOG.md (punkt 82/83)
for full begrunnelse og verifiseringslogg.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-14 10:38:54 +02:00

64 lines
3.4 KiB
SQL

-- =====================================================================
-- TeeCup — Flaggturnering: GPS-flaggplanting + runde 2+, org-
-- individuelle turneringer (migrasjon 070). Speiler migrasjon 069
-- (frittstående runder) presist, samme begrunnelse for hvorfor
-- overflow-scoring er en egen tabell og ikke en lap-kolonne på
-- tournament_round_hole (delt av alle formater, mange eksisterende
-- spørringer antar ≤18 rader per deltaker).
--
-- Ulikt 069: disse tabellene ER org-scopet og RLS-beskyttet (samme
-- org_isolation-policy-mønster som resten av tournament_round-familien,
-- migrasjon 040).
-- =====================================================================
\set ON_ERROR_STOP on
CREATE TABLE tournament_round_participant_flag_plant (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
organization_id uuid NOT NULL,
tournament_round_participant_id uuid NOT NULL UNIQUE,
lap smallint NOT NULL DEFAULT 1 CHECK (lap >= 1),
hole_number smallint NOT NULL CHECK (hole_number BETWEEN 1 AND 18),
lat double precision NOT NULL CHECK (lat BETWEEN -90 AND 90),
lng double precision NOT NULL CHECK (lng BETWEEN -180 AND 180),
on_green boolean NOT NULL DEFAULT false,
distance_to_pin_cm integer CHECK (distance_to_pin_cm >= 0),
CHECK (on_green OR distance_to_pin_cm IS NULL),
planted_by_user_id uuid NOT NULL REFERENCES app_user(id),
planted_at timestamptz NOT NULL DEFAULT now(),
FOREIGN KEY (organization_id, tournament_round_participant_id)
REFERENCES tournament_round_participant(organization_id, id) ON DELETE CASCADE
);
CREATE TABLE tournament_round_hole_flag_overflow (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
organization_id uuid NOT NULL,
tournament_round_participant_id uuid NOT NULL,
lap smallint NOT NULL CHECK (lap >= 2),
hole_number smallint NOT NULL CHECK (hole_number BETWEEN 1 AND 18),
gross_strokes smallint CHECK (gross_strokes BETWEEN 1 AND 20),
played boolean NOT NULL DEFAULT false,
FOREIGN KEY (organization_id, tournament_round_participant_id)
REFERENCES tournament_round_participant(organization_id, id) ON DELETE CASCADE,
UNIQUE (tournament_round_participant_id, lap, hole_number)
);
CREATE INDEX ON tournament_round_participant_flag_plant (organization_id, tournament_round_participant_id);
CREATE INDEX ON tournament_round_hole_flag_overflow (organization_id, tournament_round_participant_id);
DO $$
DECLARE t text;
BEGIN
FOREACH t IN ARRAY ARRAY[
'tournament_round_participant_flag_plant',
'tournament_round_hole_flag_overflow'
]
LOOP
EXECUTE format('ALTER TABLE %I ENABLE ROW LEVEL SECURITY;', t);
EXECUTE format('ALTER TABLE %I FORCE ROW LEVEL SECURITY;', t);
EXECUTE format($p$
CREATE POLICY org_isolation ON %I
USING (organization_id = current_setting('app.current_org', true)::uuid)
WITH CHECK (organization_id = current_setting('app.current_org', true)::uuid);
$p$, t);
END LOOP;
END $$;