-- 003_team_transitivity.sql
-- Team-transitivitet: når en bruker melder seg inn i et team (member_of-edge),
-- arver brukeren all tilgang teamet allerede har.
--
-- Tidligere håndterte recompute_access kun retningen "team får ny tilgang →
-- propager til eksisterende medlemmer". Nå håndteres også "ny bruker melder
-- seg inn i team → arv teamets eksisterende tilganger".
--
-- Ref: docs/retninger/bruker_ikke_workspace.md, docs/primitiver/edges.md

BEGIN;

CREATE OR REPLACE FUNCTION recompute_access(
    p_subject_id   UUID,
    p_root_node_id UUID,
    p_access       access_level,
    p_via_edge     UUID
) RETURNS void AS $$
BEGIN
    -- Steg 1: Direkte tilgang til roten
    INSERT INTO node_access (subject_id, object_id, access, via_edge)
    VALUES (p_subject_id, p_root_node_id, p_access, p_via_edge)
    ON CONFLICT (subject_id, object_id)
    DO UPDATE SET access = GREATEST(node_access.access, p_access);

    -- Steg 2: Transitiv: noder som tilhører roten (belongs_to)
    INSERT INTO node_access (subject_id, object_id, access, via_edge)
    SELECT p_subject_id, e.source_id, p_access, p_via_edge
    FROM edges e
    WHERE e.target_id = p_root_node_id
      AND e.edge_type = 'belongs_to'
    ON CONFLICT (subject_id, object_id)
    DO UPDATE SET access = GREATEST(node_access.access, p_access);

    -- Steg 3: Hvis subject er et team: propager til alle teammedlemmer
    INSERT INTO node_access (subject_id, object_id, access, via_edge)
    SELECT e.source_id, na.object_id, na.access, na.via_edge
    FROM node_access na
    JOIN edges e ON e.target_id = p_subject_id
      AND e.edge_type = 'member_of'
    WHERE na.subject_id = p_subject_id
    ON CONFLICT (subject_id, object_id)
    DO UPDATE SET access = GREATEST(node_access.access, EXCLUDED.access);

    -- Steg 4: Team-transitivitet — arv tilgang fra teamet.
    -- Når en bruker (p_subject_id) melder seg inn i et team (p_root_node_id),
    -- arver brukeren all tilgang teamet allerede har til andre noder.
    -- Sjekker om root_node har node_access-rader som subject (= er et team
    -- eller annen entitet med tilgang). Kopierer disse til p_subject_id.
    INSERT INTO node_access (subject_id, object_id, access, via_edge)
    SELECT p_subject_id, na.object_id, na.access, na.via_edge
    FROM node_access na
    WHERE na.subject_id = p_root_node_id
    ON CONFLICT (subject_id, object_id)
    DO UPDATE SET access = GREATEST(node_access.access, EXCLUDED.access);
END;
$$ LANGUAGE plpgsql;

COMMIT;
