"""Phase 3: Enforce NOT NULL on tenant/node columns + enable RLS.

Data isolation spec Section 2.2 Phase 3.
Run AFTER Phase 2 backfill is verified.

RLS policy: Every query must have app.tenant_id session variable set.
If not set, falls back to nil UUID (matches nothing = safe default).

Revision ID: 9a3b4c5d6e7f
Revises: 8a2b3c4d5e6f
Create Date: 2026-03-13 10:00:02.000000

"""
from typing import Sequence, Union

from alembic import op

# revision identifiers, used by Alembic.
revision: str = "9a3b4c5d6e7f"
down_revision: Union[str, None] = "8a2b3c4d5e6f"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None

TABLES = [
    "documents",
    "extracted_records",
    "domain_term_dictionary",
    "symbol_dictionaries",
]


def upgrade() -> None:
    # Alter columns to NOT NULL
    for table in TABLES:
        op.alter_column(table, "tenant_id", nullable=False)
        op.alter_column(table, "node_id", nullable=False)

    # Enable RLS and create tenant isolation policies
    for table in TABLES:
        op.execute(f"ALTER TABLE {table} ENABLE ROW LEVEL SECURITY")
        op.execute(f"ALTER TABLE {table} FORCE ROW LEVEL SECURITY")
        op.execute(
            f"""
            CREATE POLICY tenant_isolation_{table} ON {table}
            FOR ALL
            USING (
                tenant_id = COALESCE(
                    NULLIF(current_setting('app.tenant_id', true), '')::uuid,
                    '00000000-0000-0000-0000-000000000000'::uuid
                )
            )
            WITH CHECK (
                tenant_id = COALESCE(
                    NULLIF(current_setting('app.tenant_id', true), '')::uuid,
                    '00000000-0000-0000-0000-000000000000'::uuid
                )
            )
            """
        )


def downgrade() -> None:
    for table in TABLES:
        op.execute(f"DROP POLICY IF EXISTS tenant_isolation_{table} ON {table}")
        op.execute(f"ALTER TABLE {table} DISABLE ROW LEVEL SECURITY")
        op.alter_column(table, "tenant_id", nullable=True)
        op.alter_column(table, "node_id", nullable=True)
