-- ============================================================================
-- V39 — PostgreSQL Row-Level Security : isolation multi-tenant
--
-- P1.2 ROADMAP_2026.md — Multi-tenancy RLS sur tables tenant-scoped
--
-- Variables de session :
--   app.current_org_id   : UUID de l'organisation active (set par RlsConnectionInitializer)
--   app.is_super_admin   : 'true' si SUPER_ADMIN (bypass RLS pour dashboards globaux)
--
-- Notes sécurité :
--   - Ne pas activer FORCE ROW LEVEL SECURITY ici — le user Flyway (owner) bypasse naturellement.
--   - En prod : créer user `unionflow_app` sans BYPASSRLS pour le pool Quarkus.
--   - Le user Flyway (`unionflow_admin` ou `postgres`) doit avoir BYPASSRLS ou être owner.
-- ============================================================================

-- ============================================================================
-- Helper : policy template pour tables avec organisation_id direct
-- ============================================================================

-- TABLE cotisations
ALTER TABLE cotisations ENABLE ROW LEVEL SECURITY;
DO $$ BEGIN
    IF NOT EXISTS (SELECT 1 FROM pg_policy WHERE polname = 'rls_tenant_cotisations') THEN
        CREATE POLICY rls_tenant_cotisations ON cotisations
            USING (
                organisation_id = current_setting('app.current_org_id', true)::uuid
                OR current_setting('app.is_super_admin', true) = 'true'
            );
    END IF;
END $$;

-- TABLE souscriptions_organisation
ALTER TABLE souscriptions_organisation ENABLE ROW LEVEL SECURITY;
DO $$ BEGIN
    IF NOT EXISTS (SELECT 1 FROM pg_policy WHERE polname = 'rls_tenant_souscriptions') THEN
        CREATE POLICY rls_tenant_souscriptions ON souscriptions_organisation
            USING (
                organisation_id = current_setting('app.current_org_id', true)::uuid
                OR current_setting('app.is_super_admin', true) = 'true'
            );
    END IF;
END $$;

-- TABLE evenements
ALTER TABLE evenements ENABLE ROW LEVEL SECURITY;
DO $$ BEGIN
    IF NOT EXISTS (SELECT 1 FROM pg_policy WHERE polname = 'rls_tenant_evenements') THEN
        CREATE POLICY rls_tenant_evenements ON evenements
            USING (
                organisation_id = current_setting('app.current_org_id', true)::uuid
                OR current_setting('app.is_super_admin', true) = 'true'
            );
    END IF;
END $$;

-- TABLE documents
ALTER TABLE documents ENABLE ROW LEVEL SECURITY;
DO $$ BEGIN
    IF NOT EXISTS (SELECT 1 FROM pg_policy WHERE polname = 'rls_tenant_documents') THEN
        CREATE POLICY rls_tenant_documents ON documents
            USING (
                organisation_id = current_setting('app.current_org_id', true)::uuid
                OR current_setting('app.is_super_admin', true) = 'true'
            );
    END IF;
END $$;

-- TABLE comptes_comptables
ALTER TABLE comptes_comptables ENABLE ROW LEVEL SECURITY;
DO $$ BEGIN
    IF NOT EXISTS (SELECT 1 FROM pg_policy WHERE polname = 'rls_tenant_comptes_comptables') THEN
        CREATE POLICY rls_tenant_comptes_comptables ON comptes_comptables
            USING (
                organisation_id = current_setting('app.current_org_id', true)::uuid
                OR current_setting('app.is_super_admin', true) = 'true'
            );
    END IF;
END $$;

-- TABLE journaux_comptables
ALTER TABLE journaux_comptables ENABLE ROW LEVEL SECURITY;
DO $$ BEGIN
    IF NOT EXISTS (SELECT 1 FROM pg_policy WHERE polname = 'rls_tenant_journaux_comptables') THEN
        CREATE POLICY rls_tenant_journaux_comptables ON journaux_comptables
            USING (
                organisation_id = current_setting('app.current_org_id', true)::uuid
                OR current_setting('app.is_super_admin', true) = 'true'
            );
    END IF;
END $$;

-- TABLE ecritures_comptables
ALTER TABLE ecritures_comptables ENABLE ROW LEVEL SECURITY;
DO $$ BEGIN
    IF NOT EXISTS (SELECT 1 FROM pg_policy WHERE polname = 'rls_tenant_ecritures_comptables') THEN
        CREATE POLICY rls_tenant_ecritures_comptables ON ecritures_comptables
            USING (
                organisation_id = current_setting('app.current_org_id', true)::uuid
                OR current_setting('app.is_super_admin', true) = 'true'
            );
    END IF;
END $$;

-- TABLE kyc_dossier (scoped via membres_organisations JOIN)
-- Note : kyc_dossier n'a pas d'organisation_id direct — scope via membre_id + membres_organisations
ALTER TABLE kyc_dossier ENABLE ROW LEVEL SECURITY;
DO $$ BEGIN
    IF NOT EXISTS (SELECT 1 FROM pg_policy WHERE polname = 'rls_tenant_kyc_dossier') THEN
        CREATE POLICY rls_tenant_kyc_dossier ON kyc_dossier
            USING (
                EXISTS (
                    SELECT 1 FROM membres_organisations mo
                    WHERE mo.membre_id = kyc_dossier.membre_id
                    AND mo.organisation_id = current_setting('app.current_org_id', true)::uuid
                    AND mo.actif = true
                )
                OR current_setting('app.is_super_admin', true) = 'true'
            );
    END IF;
END $$;

-- TABLE membres_organisations (scope par organisation)
ALTER TABLE membres_organisations ENABLE ROW LEVEL SECURITY;
DO $$ BEGIN
    IF NOT EXISTS (SELECT 1 FROM pg_policy WHERE polname = 'rls_tenant_membres_organisations') THEN
        CREATE POLICY rls_tenant_membres_organisations ON membres_organisations
            USING (
                organisation_id = current_setting('app.current_org_id', true)::uuid
                OR current_setting('app.is_super_admin', true) = 'true'
            );
    END IF;
END $$;

-- TABLE budgets
ALTER TABLE budgets ENABLE ROW LEVEL SECURITY;
DO $$ BEGIN
    IF NOT EXISTS (SELECT 1 FROM pg_policy WHERE polname = 'rls_tenant_budgets') THEN
        CREATE POLICY rls_tenant_budgets ON budgets
            USING (
                organisation_id = current_setting('app.current_org_id', true)::uuid
                OR current_setting('app.is_super_admin', true) = 'true'
            );
    END IF;
END $$;

-- TABLE tontines (si applicable)
DO $$ BEGIN
    IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'tontines')
    AND NOT EXISTS (SELECT 1 FROM pg_policy WHERE polname = 'rls_tenant_tontines') THEN
        EXECUTE 'ALTER TABLE tontines ENABLE ROW LEVEL SECURITY';
        EXECUTE '
            CREATE POLICY rls_tenant_tontines ON tontines
            USING (
                organisation_id = current_setting(''app.current_org_id'', true)::uuid
                OR current_setting(''app.is_super_admin'', true) = ''true''
            )';
    END IF;
END $$;

-- ============================================================================
-- Rôle PostgreSQL applicatif (prod only — commenté pour ne pas casser dev)
-- À exécuter manuellement en prod avec le bon mot de passe.
-- ============================================================================
-- CREATE ROLE unionflow_app LOGIN PASSWORD '<UNIONFLOW_APP_DB_PASSWORD>';
-- GRANT CONNECT ON DATABASE unionflow TO unionflow_app;
-- GRANT USAGE ON SCHEMA public TO unionflow_app;
-- GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO unionflow_app;
-- GRANT USAGE ON ALL SEQUENCES IN SCHEMA public TO unionflow_app;
-- -- unionflow_app N'A PAS BYPASSRLS — RLS s'applique toujours
--
-- CREATE ROLE unionflow_admin LOGIN PASSWORD '<UNIONFLOW_ADMIN_DB_PASSWORD>' BYPASSRLS;
-- GRANT ALL ON ALL TABLES IN SCHEMA public TO unionflow_admin;
-- GRANT ALL ON ALL SEQUENCES IN SCHEMA public TO unionflow_admin;
-- -- unionflow_admin utilisé par Flyway et SuperAdminCrossTenantService
