"""Shape fingerprints + the mechanical proposer's columns (#2792, milestone 294)

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

Two additions to the ledger. `signature` / `body_sha` fingerprint each shape
(definition line + a whitespace/comment-insensitive hash of its block) so the
proposer can match on content and a later drift recheck can notice change,
without the ledger ever storing code. The proposal columns carry the
proposer's standing suggestion for an unclassified row — instance-of-#N with
a basis and score, or a derive-first group key — and `proposed_sha`
remembers the content it was judged at so a refresh re-examines only what
changed. Mechanical and recomputable: a restore that lacks them loses
nothing the next refresh does not rebuild.
"""
import sqlalchemy as sa
from alembic import op

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


def upgrade() -> None:
    op.add_column("code_shapes", sa.Column("signature", sa.Text(), nullable=False, server_default=""))
    op.add_column("code_shapes", sa.Column("body_sha", sa.Text(), nullable=False, server_default=""))
    op.add_column(
        "code_shapes",
        sa.Column(
            "proposed_snippet_id",
            sa.BigInteger(),
            sa.ForeignKey("notes.id", ondelete="SET NULL"),
            nullable=True,
        ),
    )
    op.add_column("code_shapes", sa.Column("proposal_basis", sa.Text(), nullable=True))
    op.add_column("code_shapes", sa.Column("proposal_score", sa.Float(), nullable=True))
    op.add_column("code_shapes", sa.Column("proposal_group", sa.Text(), nullable=True))
    op.add_column("code_shapes", sa.Column("proposed_at", sa.DateTime(timezone=True), nullable=True))
    op.add_column("code_shapes", sa.Column("proposed_sha", sa.Text(), nullable=False, server_default=""))
    op.create_index(
        "ix_code_shapes_proposed", "code_shapes", ["project_id", "proposed_snippet_id"]
    )


def downgrade() -> None:
    op.drop_index("ix_code_shapes_proposed", table_name="code_shapes")
    for col in (
        "proposed_sha", "proposed_at", "proposal_group", "proposal_score",
        "proposal_basis", "proposed_snippet_id", "body_sha", "signature",
    ):
        op.drop_column("code_shapes", col)
