-- 007_enable_rls.sql
-- Enable Row-Level Security for Findings Ledger tenant isolation (LEDGER-TEN-48-001-DEV)
-- Based on Evidence Locker pattern per CONTRACT-FINDINGS-LEDGER-RLS-011

BEGIN;

-- ============================================
-- 1. Create app schema and tenant function
-- ============================================

CREATE SCHEMA IF NOT EXISTS findings_ledger_app;

CREATE OR REPLACE FUNCTION findings_ledger_app.require_current_tenant()
RETURNS TEXT
LANGUAGE plpgsql
STABLE
AS $$
DECLARE
    tenant_text TEXT;
BEGIN
    tenant_text := current_setting('app.current_tenant', true);
    IF tenant_text IS NULL OR length(trim(tenant_text)) = 0 THEN
        RAISE EXCEPTION 'app.current_tenant is not set for the current session'
            USING ERRCODE = 'P0001';
    END IF;
    RETURN tenant_text;
END;
$$;

COMMENT ON FUNCTION findings_ledger_app.require_current_tenant() IS
    'Returns the current tenant ID from session variable, raises exception if not set';

-- ============================================
-- 2. Enable RLS on ledger_events
-- ============================================

ALTER TABLE ledger_events ENABLE ROW LEVEL SECURITY;
ALTER TABLE ledger_events FORCE ROW LEVEL SECURITY;

DROP POLICY IF EXISTS ledger_events_tenant_isolation ON ledger_events;
CREATE POLICY ledger_events_tenant_isolation
    ON ledger_events
    FOR ALL
    USING (tenant_id = findings_ledger_app.require_current_tenant())
    WITH CHECK (tenant_id = findings_ledger_app.require_current_tenant());

-- ============================================
-- 3. Enable RLS on ledger_merkle_roots
-- ============================================

ALTER TABLE ledger_merkle_roots ENABLE ROW LEVEL SECURITY;
ALTER TABLE ledger_merkle_roots FORCE ROW LEVEL SECURITY;

DROP POLICY IF EXISTS ledger_merkle_roots_tenant_isolation ON ledger_merkle_roots;
CREATE POLICY ledger_merkle_roots_tenant_isolation
    ON ledger_merkle_roots
    FOR ALL
    USING (tenant_id = findings_ledger_app.require_current_tenant())
    WITH CHECK (tenant_id = findings_ledger_app.require_current_tenant());

-- ============================================
-- 4. Enable RLS on findings_projection
-- ============================================

ALTER TABLE findings_projection ENABLE ROW LEVEL SECURITY;
ALTER TABLE findings_projection FORCE ROW LEVEL SECURITY;

DROP POLICY IF EXISTS findings_projection_tenant_isolation ON findings_projection;
CREATE POLICY findings_projection_tenant_isolation
    ON findings_projection
    FOR ALL
    USING (tenant_id = findings_ledger_app.require_current_tenant())
    WITH CHECK (tenant_id = findings_ledger_app.require_current_tenant());

-- ============================================
-- 5. Enable RLS on finding_history
-- ============================================

ALTER TABLE finding_history ENABLE ROW LEVEL SECURITY;
ALTER TABLE finding_history FORCE ROW LEVEL SECURITY;

DROP POLICY IF EXISTS finding_history_tenant_isolation ON finding_history;
CREATE POLICY finding_history_tenant_isolation
    ON finding_history
    FOR ALL
    USING (tenant_id = findings_ledger_app.require_current_tenant())
    WITH CHECK (tenant_id = findings_ledger_app.require_current_tenant());

-- ============================================
-- 6. Enable RLS on triage_actions
-- ============================================

ALTER TABLE triage_actions ENABLE ROW LEVEL SECURITY;
ALTER TABLE triage_actions FORCE ROW LEVEL SECURITY;

DROP POLICY IF EXISTS triage_actions_tenant_isolation ON triage_actions;
CREATE POLICY triage_actions_tenant_isolation
    ON triage_actions
    FOR ALL
    USING (tenant_id = findings_ledger_app.require_current_tenant())
    WITH CHECK (tenant_id = findings_ledger_app.require_current_tenant());

-- ============================================
-- 7. Enable RLS on ledger_attestations
-- ============================================

ALTER TABLE ledger_attestations ENABLE ROW LEVEL SECURITY;
ALTER TABLE ledger_attestations FORCE ROW LEVEL SECURITY;

DROP POLICY IF EXISTS ledger_attestations_tenant_isolation ON ledger_attestations;
CREATE POLICY ledger_attestations_tenant_isolation
    ON ledger_attestations
    FOR ALL
    USING (tenant_id = findings_ledger_app.require_current_tenant())
    WITH CHECK (tenant_id = findings_ledger_app.require_current_tenant());

-- ============================================
-- 8. Enable RLS on orchestrator_exports
-- ============================================

ALTER TABLE orchestrator_exports ENABLE ROW LEVEL SECURITY;
ALTER TABLE orchestrator_exports FORCE ROW LEVEL SECURITY;

DROP POLICY IF EXISTS orchestrator_exports_tenant_isolation ON orchestrator_exports;
CREATE POLICY orchestrator_exports_tenant_isolation
    ON orchestrator_exports
    FOR ALL
    USING (tenant_id = findings_ledger_app.require_current_tenant())
    WITH CHECK (tenant_id = findings_ledger_app.require_current_tenant());

-- ============================================
-- 9. Enable RLS on airgap_imports
-- ============================================

ALTER TABLE airgap_imports ENABLE ROW LEVEL SECURITY;
ALTER TABLE airgap_imports FORCE ROW LEVEL SECURITY;

DROP POLICY IF EXISTS airgap_imports_tenant_isolation ON airgap_imports;
CREATE POLICY airgap_imports_tenant_isolation
    ON airgap_imports
    FOR ALL
    USING (tenant_id = findings_ledger_app.require_current_tenant())
    WITH CHECK (tenant_id = findings_ledger_app.require_current_tenant());

-- ============================================
-- 10. Create admin bypass role
-- ============================================

DO $$
BEGIN
    IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'findings_ledger_admin') THEN
        CREATE ROLE findings_ledger_admin NOLOGIN BYPASSRLS;
    END IF;
END;
$$;

COMMENT ON ROLE findings_ledger_admin IS
    'Admin role that bypasses RLS for migrations and cross-tenant operations';

COMMIT;
