teecup/084_tournament_round_groups.sql
Erol Haagenrud 9a9fcc84c0 Utslagsgrupper for individuelle turneringer: hvem spiller med hvem (ADR-088)
Tradisjonelt utslag (samme starthull, staggerte klokkeslett med fast
intervall), manuell gruppesammensetning med et forslag å justere, fast
gruppestørrelse. Fire ekte bugs funnet og fikset før utrulling via egen
scratch-verifisering (FK-korrupsjon, str/datetime-mismatch, tidssone,
React state). Migrasjon 084 lagt til, men IKKE anvendt mot ekte
teecup_db ennå -- venter på bekreftelse.
2026-08-18 15:43:39 +02:00

71 lines
3.8 KiB
SQL

-- =====================================================================
-- TeeCup — migrasjon 084
-- Utslagsgrupper for individuelle turneringer: hvem spiller med hvem,
-- klokka når
-- =====================================================================
-- Bruker: "Jeg må jo kunne bulksjekke hvem som skal spille fra hvor, med
-- hvem, klokka når?" -- undersøkt FØR bygging: individuelle turneringer
-- hadde INGEN gruppe-/pairing-konsept i det hele tatt, kun ett delt
-- start_hole/scheduled_at/tee_interval_minutes for HELE runden
-- (tournament_round, migrasjon 040) -- ingen måte å si hvem som spiller
-- sammen, eller gi ulike grupper ulikt klokkeslett.
--
-- Design bekreftet med bruker 2026-08-18 (tre spørsmål):
-- - TRADISJONELT utslag: samme starthull for alle (tournament_round sitt
-- allerede eksisterende start_hole -- ingen endring der), staggerte
-- klokkeslett PER GRUPPE med fast intervall -- IKKE shotgun (ulike
-- hull samtidig).
-- - Gruppesammensetning er MANUELL, med et forslag å justere -- ikke
-- helt automatisk, ikke helt fra bunnen av.
-- - FAST gruppestørrelse (organisator velger tallet, f.eks. 4), ikke
-- fleksibelt antall per gruppe.
--
-- `tournament_round_group` speiler `session`/`match` sin allerede
-- etablerte klokkeslett-modell i matches.py (`_compute_tee_time`):
-- gruppens tee-tid er UTLEDET (tournament_round.scheduled_at +
-- (sequence-1)*tournament_round.tee_interval_minutes), med en valgfri
-- `tee_time_override` som vinner hvis satt (samme unntaks-mønster som
-- `match.tee_time_override` -- f.eks. én gruppe forsinket). INGEN nytt
-- starthull-felt her -- alle grupper i en runde bruker rundens EGNE
-- start_hole, per bekreftet "tradisjonelt"-valg.
--
-- `tournament_round_participant.tournament_round_group_id` er nullable
-- (ikke gruppert ennå = null, ingen regresjon for eksisterende runder/
-- deltakere). BEVISST INGEN `ON DELETE SET NULL` på FK-en, selv om det
-- først virket naturlig ("slett en gruppe -> deltakerne blir ugrupperte
-- igjen") -- funnet under egen scratch-testing: en SAMMENSATT FK
-- (organization_id, tournament_round_group_id) med ON DELETE SET NULL
-- setter BEGGE kolonnene til null ved kaskade, IKKE bare fremmednøkkel-
-- kolonnen -- det ville korrumpert organization_id (RLS sin tenant-
-- nøkkel, kan ALDRI være null) på deltaker-rader hver gang en gruppe
-- slettes. Appen (`save_round_groups`, individual_tournaments.py)
-- nullstiller derfor `tournament_round_group_id` EKSPLISITT i Python
-- FØR den sletter de gamle gruppe-radene -- samme "eksplisitt rekkefølge
-- fremfor å stole på kaskade-semantikk"-mønster som ADR-086 sin
-- turneringssletting allerede etablerte for en beslektet RESTRICT-FK-
-- diamant. Standard FK-oppførsel (RESTRICT) er dermed trygg: den
-- utløses aldri fra denne kodestien (kolonnen er allerede null før
-- selve DELETE-en kjører), og ville korrekt stoppet enhver FREMTIDIG
-- kodesti som glemte å nullstille først, i stedet for å stille
-- korrumpere data.
-- =====================================================================
\set ON_ERROR_STOP on
CREATE TABLE tournament_round_group (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
organization_id uuid NOT NULL,
tournament_round_id uuid NOT NULL,
sequence smallint NOT NULL,
tee_time_override timestamptz,
created_at timestamptz NOT NULL DEFAULT now(),
FOREIGN KEY (organization_id, tournament_round_id)
REFERENCES tournament_round(organization_id, id) ON DELETE CASCADE,
UNIQUE (organization_id, id),
UNIQUE (tournament_round_id, sequence)
);
ALTER TABLE tournament_round_participant
ADD COLUMN tournament_round_group_id uuid,
ADD FOREIGN KEY (organization_id, tournament_round_group_id)
REFERENCES tournament_round_group(organization_id, id);