-- Migrasjon 020: Propager tilgang ved nye belongs_to-edges
--
-- Når en belongs_to-edge opprettes mellom barn og forelder, skal alle
-- som allerede har tilgang til forelderen også få tilgang til barnet.
-- recompute_access håndterer dette i steg 2 for access-granting edges,
-- men ikke for belongs_to-edges som opprettes etter at tilgang allerede er gitt.

CREATE OR REPLACE FUNCTION propagate_belongs_to_access(
    p_child_id UUID,
    p_parent_id UUID
) RETURNS void LANGUAGE plpgsql AS $$
BEGIN
    -- For alle som har tilgang til forelder: gi samme tilgang til barnet
    INSERT INTO node_access (subject_id, object_id, access, via_edge)
    SELECT na.subject_id, p_child_id, na.access, na.via_edge
    FROM node_access na
    WHERE na.object_id = p_parent_id
    ON CONFLICT (subject_id, object_id)
    DO UPDATE SET access = GREATEST(node_access.access, EXCLUDED.access),
                  via_edge = CASE
                      WHEN EXCLUDED.access > node_access.access THEN EXCLUDED.via_edge
                      ELSE node_access.via_edge
                  END;
END;
$$;

-- Retroaktivt: fiks eksisterende belongs_to-edges der tilgang mangler.
-- Finn barn som har belongs_to-edge til forelder, men der forelderens
-- tilgangssubjekter ikke har tilgang til barnet.
DO $$
DECLARE
    r RECORD;
BEGIN
    FOR r IN
        SELECT e.source_id AS child_id, e.target_id AS parent_id
        FROM edges e
        WHERE e.edge_type = 'belongs_to'
          AND EXISTS (
              SELECT 1 FROM node_access na
              WHERE na.object_id = e.target_id
                AND NOT EXISTS (
                    SELECT 1 FROM node_access na2
                    WHERE na2.subject_id = na.subject_id
                      AND na2.object_id = e.source_id
                )
          )
    LOOP
        PERFORM propagate_belongs_to_access(r.child_id, r.parent_id);
    END LOOP;
END;
$$;
