"""Restore plans and archive divergence (US06-04). Revision ID: 0014_restore_plans Revises: 0013_protected_thumbnails Create Date: 2026-08-16 Restore reuses the archive plan and journal tables: the crash-safe question is the same one in the opposite direction (copy, verify, publish, register), so the rows gain a ``direction`` instead of a parallel pair of tables. ``archive_divergent_at`` records the moment an archived copy was proven to hold bytes that are not the ones the database recorded — a restore must never silently accept a different file. """ import sqlalchemy as sa from alembic import op revision = "0014_restore_plans" down_revision = "0013_protected_thumbnails" branch_labels = None depends_on = None def upgrade() -> None: for table in ("archive_plans", "archive_operations"): op.add_column( table, sa.Column("direction", sa.String(), nullable=False, server_default="archive"), ) op.add_column( "assets", sa.Column("archive_divergent_at", sa.DateTime(timezone=True), nullable=True) ) def downgrade() -> None: op.drop_column("assets", "archive_divergent_at") for table in ("archive_plans", "archive_operations"): op.drop_column(table, "direction")