-- 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;
