Implementerer Fase M1 av SpacetimeDB-migrasjonen: - SQL-migrasjon 018: Triggers for notify_node_change, notify_edge_change og notify_access_change på nodes, edges og node_access-tabellene - Ny ws.rs-modul i maskinrommet med: - PG LISTEN bakgrunnsoppgave som lytter på tre kanaler - Broadcast-kanal for å videresende events til alle WS-klienter - WebSocket-endepunkt (/ws) med JWT-autentisering - Initiell snapshot (initial_sync) ved tilkobling - Tilgangskontrollfiltrering per klient via node_access-matrisen - Oppdatert AppState med WsBroadcast og /ws-rute Frontend dual-tilkobling (STDB + nytt WS) kommer i neste commit.
110 lines
3 KiB
PL/PgSQL
110 lines
3 KiB
PL/PgSQL
-- 018_pg_notify_triggers.sql
|
|
-- PG LISTEN/NOTIFY triggers for sanntid: nodes, edges og node_access.
|
|
--
|
|
-- Portvokteren (maskinrommet) lytter på disse kanalene og videresender
|
|
-- endringer via WebSocket til tilkoblede klienter.
|
|
-- Ref: docs/retninger/datalaget.md (Fase M1)
|
|
|
|
BEGIN;
|
|
|
|
-- =============================================================================
|
|
-- notify_node_change: Sender NOTIFY ved INSERT, UPDATE eller DELETE på nodes.
|
|
-- Payload er JSON med operasjon, node-ID og node_kind.
|
|
-- =============================================================================
|
|
|
|
CREATE OR REPLACE FUNCTION notify_node_change()
|
|
RETURNS trigger AS $$
|
|
DECLARE
|
|
payload json;
|
|
target_row nodes%ROWTYPE;
|
|
BEGIN
|
|
IF TG_OP = 'DELETE' THEN
|
|
target_row := OLD;
|
|
ELSE
|
|
target_row := NEW;
|
|
END IF;
|
|
|
|
payload := json_build_object(
|
|
'op', TG_OP,
|
|
'id', target_row.id,
|
|
'kind', target_row.node_kind
|
|
);
|
|
|
|
PERFORM pg_notify('node_changed', payload::text);
|
|
RETURN target_row;
|
|
END;
|
|
$$ LANGUAGE plpgsql;
|
|
|
|
CREATE TRIGGER nodes_notify
|
|
AFTER INSERT OR UPDATE OR DELETE ON nodes
|
|
FOR EACH ROW EXECUTE FUNCTION notify_node_change();
|
|
|
|
-- =============================================================================
|
|
-- notify_edge_change: Sender NOTIFY ved INSERT, UPDATE eller DELETE på edges.
|
|
-- Payload er JSON med operasjon, edge-ID, source, target og type.
|
|
-- =============================================================================
|
|
|
|
CREATE OR REPLACE FUNCTION notify_edge_change()
|
|
RETURNS trigger AS $$
|
|
DECLARE
|
|
payload json;
|
|
target_row edges%ROWTYPE;
|
|
BEGIN
|
|
IF TG_OP = 'DELETE' THEN
|
|
target_row := OLD;
|
|
ELSE
|
|
target_row := NEW;
|
|
END IF;
|
|
|
|
payload := json_build_object(
|
|
'op', TG_OP,
|
|
'id', target_row.id,
|
|
'source_id', target_row.source_id,
|
|
'target_id', target_row.target_id,
|
|
'edge_type', target_row.edge_type
|
|
);
|
|
|
|
PERFORM pg_notify('edge_changed', payload::text);
|
|
RETURN target_row;
|
|
END;
|
|
$$ LANGUAGE plpgsql;
|
|
|
|
CREATE TRIGGER edges_notify
|
|
AFTER INSERT OR UPDATE OR DELETE ON edges
|
|
FOR EACH ROW EXECUTE FUNCTION notify_edge_change();
|
|
|
|
-- =============================================================================
|
|
-- notify_access_change: Sender NOTIFY ved endringer i node_access.
|
|
-- Brukes av portvokteren for å oppdatere klientenes tilgangsmatrise.
|
|
-- =============================================================================
|
|
|
|
CREATE OR REPLACE FUNCTION notify_access_change()
|
|
RETURNS trigger AS $$
|
|
DECLARE
|
|
payload json;
|
|
BEGIN
|
|
IF TG_OP = 'DELETE' THEN
|
|
payload := json_build_object(
|
|
'op', TG_OP,
|
|
'subject_id', OLD.subject_id,
|
|
'object_id', OLD.object_id
|
|
);
|
|
ELSE
|
|
payload := json_build_object(
|
|
'op', TG_OP,
|
|
'subject_id', NEW.subject_id,
|
|
'object_id', NEW.object_id,
|
|
'access', NEW.access
|
|
);
|
|
END IF;
|
|
|
|
PERFORM pg_notify('access_changed', payload::text);
|
|
RETURN COALESCE(NEW, OLD);
|
|
END;
|
|
$$ LANGUAGE plpgsql;
|
|
|
|
CREATE TRIGGER node_access_notify
|
|
AFTER INSERT OR UPDATE OR DELETE ON node_access
|
|
FOR EACH ROW EXECUTE FUNCTION notify_access_change();
|
|
|
|
COMMIT;
|