"""Shape history, recheck, and the divergence flag (#2793, milestone 294)

Revision ID: 0081
Revises: 0080
Create Date: 2026-08-21

The payoff surface of the ledger. `classified_sha` remembers the fingerprint
a judgment was made at so a later body change under an instance/variant can
flag `recheck_at`; `diverges_from` is the button-B flag (a shape new since
the previous refresh, where one canon dominates its directory+kind, and not
proposed as that canon). `code_shape_events` is the what-was-used-when
record: every classification, vanish, reappearance, and drift as it
happened — history the row alone cannot keep once it moves on.
"""
import sqlalchemy as sa
from alembic import op

revision = "0081"
down_revision = "0080"
branch_labels = None
depends_on = None


def upgrade() -> None:
    op.add_column("code_shapes", sa.Column("classified_sha", sa.Text(), nullable=False, server_default=""))
    op.add_column("code_shapes", sa.Column("recheck_at", sa.DateTime(timezone=True), nullable=True))
    op.add_column(
        "code_shapes",
        sa.Column(
            "diverges_from",
            sa.BigInteger(),
            sa.ForeignKey("notes.id", ondelete="SET NULL"),
            nullable=True,
        ),
    )
    op.create_index("ix_code_shapes_diverges", "code_shapes", ["project_id", "diverges_from"])
    op.create_table(
        "code_shape_events",
        sa.Column("id", sa.Integer(), primary_key=True),
        sa.Column(
            "shape_id",
            sa.Integer(),
            sa.ForeignKey("code_shapes.id", ondelete="CASCADE"),
            nullable=False,
        ),
        sa.Column("project_id", sa.Integer(), nullable=False),
        sa.Column("path", sa.Text(), nullable=False),
        sa.Column("symbol", sa.Text(), nullable=False),
        sa.Column("kind", sa.Text(), nullable=False),
        sa.Column("event", sa.Text(), nullable=False),
        sa.Column("status", sa.Text(), nullable=True),
        sa.Column("snippet_id", sa.BigInteger(), nullable=True),
        sa.Column("classified_by", sa.Text(), nullable=True),
        sa.Column("reason", sa.Text(), nullable=True),
        sa.Column("commit", sa.Text(), nullable=False, server_default=""),
        sa.Column("at", sa.DateTime(timezone=True), nullable=False),
    )
    op.create_index("ix_code_shape_events_shape", "code_shape_events", ["shape_id", "at"])
    op.create_index(
        "ix_code_shape_events_project_path", "code_shape_events", ["project_id", "path"]
    )


def downgrade() -> None:
    op.drop_index("ix_code_shape_events_project_path", table_name="code_shape_events")
    op.drop_index("ix_code_shape_events_shape", table_name="code_shape_events")
    op.drop_table("code_shape_events")
    op.drop_index("ix_code_shapes_diverges", table_name="code_shapes")
    for col in ("diverges_from", "recheck_at", "classified_sha"):
        op.drop_column("code_shapes", col)
