43 lines
1.6 KiB
Python
43 lines
1.6 KiB
Python
"""Durable EXIF projections per asset and stage (US07-03).
|
|
|
|
Revision ID: 0015_exif_projections
|
|
Revises: 0014_restore_plans
|
|
Create Date: 2026-08-16
|
|
|
|
The concept's ``exif_projections`` table, added at the point it earns its keep: a
|
|
checkpoint that finds a field it does not own changed must be able to say so after
|
|
a restart. ``state`` is verified | divergent | failed, and only ``verified`` counts
|
|
as a completed metadata stage.
|
|
"""
|
|
|
|
import sqlalchemy as sa
|
|
from alembic import op
|
|
|
|
revision = "0015_exif_projections"
|
|
down_revision = "0014_restore_plans"
|
|
branch_labels = None
|
|
depends_on = None
|
|
|
|
|
|
def upgrade() -> None:
|
|
op.create_table(
|
|
"exif_projections",
|
|
sa.Column("asset_id", sa.String(), sa.ForeignKey("assets.id"), primary_key=True),
|
|
sa.Column("stage", sa.String(), primary_key=True), # safety | analysis
|
|
sa.Column("id", sa.String(), nullable=False),
|
|
sa.Column("projection_version", sa.Integer(), nullable=False, server_default="0"),
|
|
# What the stage asked for: {"add": [...], "remove": [...]}.
|
|
sa.Column("desired_json", sa.String(), nullable=True),
|
|
# Fields outside the stage's ownership that did not survive the write.
|
|
sa.Column("divergent_fields", sa.String(), nullable=True),
|
|
sa.Column("result_file_sha256", sa.String(), nullable=True),
|
|
sa.Column("state", sa.String(), nullable=False),
|
|
sa.Column("error_code", sa.String(), nullable=True),
|
|
sa.Column("verified_at", sa.DateTime(timezone=True), nullable=True),
|
|
sa.Column("updated_at", sa.DateTime(timezone=True), nullable=True),
|
|
)
|
|
|
|
|
|
def downgrade() -> None:
|
|
op.drop_table("exif_projections")
|