1. Migrasjon — kjør 013_messaging.sql mot ekte teecup_db (ny message-tabell, RLS, ingen endring av eksisterende data). 2. Backend + frontend — docker compose up -d --build teecup_api teecup_frontend. 3. Caddy — legger til /ws/*-ruten i /opt/teeoff/deploy/Caddyfile (allerede skrevet og syntaks-validert). Som i alle tidligere runder som har rørt denne filen: en graceful reload plukker historisk IKKE opp endringen (stale bind-mount-inode), så det trengs en full docker restart teeoff_caddy — det gir noen sekunders nedetid for teeoff.no også, ikke bare teecup.teeoff.no. Etter alt dette: sjekke /health + /dashboard → 200, en reell WebSocket-tilkobling fungerer over wss://teecup.teeoff.no/ws/..., og teeoff.no er tilbake på 200.
50 lines
2.4 KiB
SQL
50 lines
2.4 KiB
SQL
-- 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;
|