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