"""Project inception: the decision record + always-on rulebook exclusions (milestone 297)

Revision ID: 0085
Revises: 0084
Create Date: 2026-08-22

`projects.inception` is the WHY a project inherits what it does — NULL until
someone decides, at which point enter_project stops asking. The new
association `project_rulebook_exclusions` is the opt-out of a whole always-on
rulebook for one project (the sibling of the rule/topic suppressions).

Backfill: every project that exists when this runs is stamped
via="legacy" with its CURRENT standing (no exclusions, its subscriptions,
its design_system_id, no seed) — so the ask fires only for projects created
after the step shipped, and nothing a running install relies on changes.
"""
import sqlalchemy as sa
from alembic import op
from sqlalchemy.dialects import postgresql

revision = "0085"
down_revision = "0084"
branch_labels = None
depends_on = None


def upgrade() -> None:
    op.add_column(
        "projects",
        sa.Column("inception", postgresql.JSONB(), nullable=True),
    )
    op.create_table(
        "project_rulebook_exclusions",
        sa.Column(
            "project_id", sa.BigInteger(),
            sa.ForeignKey("projects.id", ondelete="CASCADE"),
            primary_key=True, nullable=False,
        ),
        sa.Column(
            "rulebook_id", sa.BigInteger(),
            sa.ForeignKey("rulebooks.id", ondelete="CASCADE"),
            primary_key=True, nullable=False,
        ),
        sa.Column(
            "created_at", sa.DateTime(timezone=True),
            server_default=sa.text("now()"), nullable=False,
        ),
    )
    # Legacy stamp: what each existing project inherits today, recorded as a
    # decision so the inception ask does not fire on a project that has been
    # running for months.
    op.execute(sa.text("""
        UPDATE projects p SET inception = jsonb_build_object(
            'via', 'legacy',
            'decided_at', to_jsonb(now()),
            'decided_by', NULL,
            'choices', jsonb_build_object(
                'exclude_always_on_rulebooks', '[]'::jsonb,
                'subscribe_rulebooks', COALESCE(
                    (SELECT jsonb_agg(s.rulebook_id ORDER BY s.rulebook_id)
                       FROM project_rulebook_subscriptions s
                      WHERE s.project_id = p.id),
                    '[]'::jsonb),
                'design_system_id', to_jsonb(p.design_system_id),
                'seed_systems', false
            )
        )
        WHERE p.inception IS NULL
    """))


def downgrade() -> None:
    op.drop_table("project_rulebook_exclusions")
    op.drop_column("projects", "inception")
