-- ============================================================
-- Migration 004: Constraints y triggers de privacidad
--
-- 1. Trigger: rechazar respondent_id no nulo en encuestas anónimas
--    → Regla no negociable #2 de CLAUDE.md (barrera técnica)
--
-- 2. Trigger: inmutabilidad de consent_records
--    → ADR-003: sin UPDATE/DELETE, evidencia permanente del consentimiento
--
-- 3. Trigger: inmutabilidad de consent_versions
--    → Textos de consentimiento históricos son inmutables
-- ============================================================

-- ============================================================
-- 1. Trigger: respondent_id prohibido en encuestas anónimas
-- ============================================================
CREATE OR REPLACE FUNCTION public.enforce_anonymous_no_respondent_id()
RETURNS trigger
LANGUAGE plpgsql
SET search_path = public
AS $$
DECLARE
    v_is_anonymous boolean;
BEGIN
    -- Leer la propiedad de la encuesta referida
    SELECT is_anonymous INTO v_is_anonymous
    FROM public.surveys
    WHERE id = NEW.survey_id;

    IF v_is_anonymous AND NEW.respondent_id IS NOT NULL THEN
        RAISE EXCEPTION
            'Privacy violation: respondent_id must be NULL in anonymous surveys (survey_id: %). '
            'See CLAUDE.md rule #2.',
            NEW.survey_id
            USING ERRCODE = 'check_violation';
    END IF;

    RETURN NEW;
END;
$$;

CREATE TRIGGER trg_responses_anonymous_no_respondent_id
    BEFORE INSERT OR UPDATE ON public.responses
    FOR EACH ROW EXECUTE FUNCTION public.enforce_anonymous_no_respondent_id();

-- ============================================================
-- 2. Trigger: inmutabilidad de consent_records (ADR-003)
-- El consentimiento es evidencia, no UI. Nunca se modifica.
-- ============================================================
CREATE OR REPLACE FUNCTION public.deny_consent_records_mutation()
RETURNS trigger
LANGUAGE plpgsql
AS $$
BEGIN
    RAISE EXCEPTION
        'consent_records is immutable: % is not permitted. '
        'Each response consent is permanent evidence (ADR-003).',
        TG_OP
        USING ERRCODE = 'insufficient_privilege';
END;
$$;

CREATE TRIGGER trg_consent_records_immutable
    BEFORE UPDATE OR DELETE ON public.consent_records
    FOR EACH ROW EXECUTE FUNCTION public.deny_consent_records_mutation();

-- ============================================================
-- 3. Trigger: inmutabilidad de consent_versions
-- Los textos históricos no se alteran. Cambiar el wording del
-- consentimiento crea una nueva versión, nunca edita la existente.
-- ============================================================
CREATE OR REPLACE FUNCTION public.deny_consent_versions_mutation()
RETURNS trigger
LANGUAGE plpgsql
AS $$
BEGIN
    RAISE EXCEPTION
        'consent_versions is immutable: % is not permitted. '
        'Create a new version instead of modifying an existing one.',
        TG_OP
        USING ERRCODE = 'insufficient_privilege';
END;
$$;

CREATE TRIGGER trg_consent_versions_immutable
    BEFORE UPDATE OR DELETE ON public.consent_versions
    FOR EACH ROW EXECUTE FUNCTION public.deny_consent_versions_mutation();
