-- =============================================================
-- DWH ROLES AUDIT
-- Target Database: tracksolid_dwh
-- Purpose: Assert that the n8n DWH pipeline's role contract holds:
--          - dwh_owner exists (writes bronze + dwh_control)
--          - grafana_ro exists (reads bronze + silver + gold + dwh_control)
--          - grafana_ro has CONNECT on the database
--          - grafana_ro has USAGE on every schema it needs
-- Applies after: 260423_dwh_ddl_v1.sql, 261001_dwh_control.sql
-- Idempotent: pure assertion, no CREATE ROLE or GRANT statements.
--
-- Why this file exists: 260423 creates both roles and grants bronze/silver/gold;
-- 261001 grants dwh_control. This file is a single checkpoint that verifies
-- those prior migrations were applied in the right order, and fails loudly
-- if anything is missing before the pipeline goes live.
--
-- Password rotation and sslmode=require enforcement are out-of-band:
-- rotate via ALTER ROLE ... PASSWORD ... in a psql superuser session,
-- enforce SSL via the n8n credential (sslmode=require) — not SQL-level.
-- =============================================================

BEGIN;

DO $$
DECLARE
    missing TEXT := '';
    r RECORD;
BEGIN
    -- 1. Roles exist
    IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'dwh_owner') THEN
        missing := missing || E'\n  - role dwh_owner missing (expected from 260423)';
    END IF;
    IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'grafana_ro') THEN
        missing := missing || E'\n  - role grafana_ro missing (expected from 260423)';
    END IF;

    -- 2. grafana_ro CONNECT on this database
    IF NOT has_database_privilege('grafana_ro', current_database(), 'CONNECT') THEN
        missing := missing
                || format(E'\n  - grafana_ro lacks CONNECT on database %s',
                          current_database());
    END IF;

    -- 3. grafana_ro USAGE on every schema the pipeline / dashboards touch
    FOR r IN
        SELECT unnest(ARRAY['bronze','silver','gold','dwh_control']) AS schema_name
    LOOP
        IF NOT EXISTS (SELECT 1 FROM pg_namespace WHERE nspname = r.schema_name) THEN
            missing := missing
                    || format(E'\n  - schema %s missing (expected from 260423/261001)',
                              r.schema_name);
        ELSIF NOT has_schema_privilege('grafana_ro', r.schema_name, 'USAGE') THEN
            missing := missing
                    || format(E'\n  - grafana_ro lacks USAGE on schema %s',
                              r.schema_name);
        END IF;
    END LOOP;

    IF length(missing) > 0 THEN
        RAISE EXCEPTION E'DWH roles audit FAILED:%s', missing;
    END IF;

    RAISE NOTICE 'DWH roles audit OK: dwh_owner + grafana_ro present with expected grants.';
END$$;

COMMIT;
