-- Kommunikasjon (ADR-025): lag-intern chat («det hemmelige rommet») og -- offentlig runde-feed («Banter Board»), delt tabell med en scope- -- diskriminator -- de to bruksmåtene deler samme meldingsform (tekst + -- valgfritt bilde), men har svært ulik synlighet/autorisasjon, håndhevet i -- app-laget (app/team_authz.py sin user_is_rostered_on_team for chat, og -- registration.py sitt gjenbrukte visibility-mønster for feeden). -- -- Lag-chat er BEVISST ekte privat -- ingen org-eier/admin-unntak her, ulikt -- ALLE andre autorisasjonssjekker i appen (matches.py/scoring.py sin -- kaptein-/deltaker-sjekk har alltid en org-admin-fallback). «Det hemmelige -- rommet» mister poenget sitt hvis organisatoren kan lese det. CREATE TYPE message_scope AS ENUM ('team', 'tournament_feed'); CREATE TABLE message ( id uuid PRIMARY KEY DEFAULT gen_random_uuid(), organization_id uuid NOT NULL REFERENCES organization(id) ON DELETE CASCADE, scope message_scope NOT NULL, tournament_id uuid NOT NULL REFERENCES tournament(id) ON DELETE CASCADE, team_id uuid REFERENCES team(id) ON DELETE CASCADE, author_user_id uuid NOT NULL REFERENCES app_user(id), -- Frosset ved skrivetidspunkt (samme "snapshot, ikke live join"-prinsipp -- som handicap_index_snapshot, ADR-007) -- en spiller som senere endrer -- visningsnavn, eller mister koblingen til player-raden sin, skal ikke -- endre historiske meldingers avsendernavn. author_display_name text NOT NULL, body text, image_key text, created_at timestamptz NOT NULL DEFAULT now(), CHECK ( (scope = 'team' AND team_id IS NOT NULL) OR (scope = 'tournament_feed' AND team_id IS NULL) ), CHECK (body IS NOT NULL OR image_key IS NOT NULL) ); CREATE INDEX message_team_idx ON message (team_id, created_at) WHERE scope = 'team'; CREATE INDEX message_feed_idx ON message (tournament_id, created_at) WHERE scope = 'tournament_feed'; ALTER TABLE message ENABLE ROW LEVEL SECURITY; ALTER TABLE message FORCE ROW LEVEL SECURITY; CREATE POLICY org_isolation ON message USING (organization_id = app_current_org()) WITH CHECK (organization_id = app_current_org()); -- Ingen UPDATE-grant -- meldinger redigeres ikke, kun slettes (moderering/ -- egen sletting), se app/routers/messaging.py. GRANT SELECT, INSERT, DELETE ON message TO teecup_app;