feat: acquire immutable sanctions snapshots
This commit is contained in:
+192
@@ -0,0 +1,192 @@
|
||||
"""Add immutable sanctions source snapshots.
|
||||
|
||||
Revision ID: f7c8d9e0a1b2
|
||||
Revises: e6b7c8d9f0a1
|
||||
Create Date: 2026-07-29
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
revision = "f7c8d9e0a1b2"
|
||||
down_revision = "e6b7c8d9f0a1"
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
op.create_table(
|
||||
"connector_sanctions_acquisition_runs",
|
||||
sa.Column("id", sa.String(length=36), nullable=False),
|
||||
sa.Column("tenant_id", sa.String(length=36), nullable=False),
|
||||
sa.Column("provider_id", sa.String(length=100), nullable=False),
|
||||
sa.Column("source_id", sa.String(length=200), nullable=False),
|
||||
sa.Column("status", sa.String(length=40), nullable=False),
|
||||
sa.Column("attempt_count", sa.Integer(), nullable=False),
|
||||
sa.Column("request_evidence", sa.JSON(), nullable=False),
|
||||
sa.Column("response_evidence", sa.JSON(), nullable=False),
|
||||
sa.Column(
|
||||
"started_at",
|
||||
sa.DateTime(timezone=True),
|
||||
nullable=False,
|
||||
),
|
||||
sa.Column(
|
||||
"finished_at",
|
||||
sa.DateTime(timezone=True),
|
||||
nullable=True,
|
||||
),
|
||||
sa.Column("snapshot_id", sa.String(length=36), nullable=True),
|
||||
sa.Column("error", sa.Text(), nullable=True),
|
||||
sa.Column("created_by", sa.String(length=255), nullable=True),
|
||||
sa.Column(
|
||||
"created_at",
|
||||
sa.DateTime(timezone=True),
|
||||
nullable=False,
|
||||
),
|
||||
sa.Column(
|
||||
"updated_at",
|
||||
sa.DateTime(timezone=True),
|
||||
nullable=False,
|
||||
),
|
||||
sa.PrimaryKeyConstraint(
|
||||
"id",
|
||||
name=op.f("pk_connector_sanctions_acquisition_runs"),
|
||||
),
|
||||
)
|
||||
for column in (
|
||||
"tenant_id",
|
||||
"provider_id",
|
||||
"source_id",
|
||||
"status",
|
||||
"started_at",
|
||||
"snapshot_id",
|
||||
"created_by",
|
||||
):
|
||||
op.create_index(
|
||||
op.f(
|
||||
"ix_connector_sanctions_acquisition_runs_"
|
||||
f"{column}"
|
||||
),
|
||||
"connector_sanctions_acquisition_runs",
|
||||
[column],
|
||||
)
|
||||
op.create_index(
|
||||
"ix_connector_sanctions_run_health",
|
||||
"connector_sanctions_acquisition_runs",
|
||||
["tenant_id", "provider_id", "status", "started_at"],
|
||||
)
|
||||
|
||||
op.create_table(
|
||||
"connector_sanctions_snapshots",
|
||||
sa.Column("id", sa.String(length=36), nullable=False),
|
||||
sa.Column("tenant_id", sa.String(length=36), nullable=False),
|
||||
sa.Column("provider_id", sa.String(length=100), nullable=False),
|
||||
sa.Column("publisher", sa.String(length=300), nullable=False),
|
||||
sa.Column("jurisdiction", sa.String(length=100), nullable=False),
|
||||
sa.Column("list_type", sa.String(length=100), nullable=False),
|
||||
sa.Column("source_id", sa.String(length=200), nullable=False),
|
||||
sa.Column(
|
||||
"source_version",
|
||||
sa.String(length=255),
|
||||
nullable=False,
|
||||
),
|
||||
sa.Column(
|
||||
"publication_at",
|
||||
sa.DateTime(timezone=True),
|
||||
nullable=True,
|
||||
),
|
||||
sa.Column(
|
||||
"effective_at",
|
||||
sa.DateTime(timezone=True),
|
||||
nullable=True,
|
||||
),
|
||||
sa.Column(
|
||||
"acquired_at",
|
||||
sa.DateTime(timezone=True),
|
||||
nullable=False,
|
||||
),
|
||||
sa.Column("source_url", sa.String(length=1500), nullable=True),
|
||||
sa.Column(
|
||||
"content_type",
|
||||
sa.String(length=200),
|
||||
nullable=False,
|
||||
),
|
||||
sa.Column("byte_count", sa.Integer(), nullable=False),
|
||||
sa.Column("sha256", sa.String(length=64), nullable=False),
|
||||
sa.Column("signature_evidence", sa.JSON(), nullable=False),
|
||||
sa.Column(
|
||||
"parser_version",
|
||||
sa.String(length=100),
|
||||
nullable=False,
|
||||
),
|
||||
sa.Column("licence_notes", sa.Text(), nullable=True),
|
||||
sa.Column("trust_notes", sa.Text(), nullable=True),
|
||||
sa.Column(
|
||||
"connector_run_id",
|
||||
sa.String(length=36),
|
||||
nullable=False,
|
||||
),
|
||||
sa.Column("transport_evidence", sa.JSON(), nullable=False),
|
||||
sa.Column("raw_content", sa.LargeBinary(), nullable=False),
|
||||
sa.Column(
|
||||
"created_at",
|
||||
sa.DateTime(timezone=True),
|
||||
nullable=False,
|
||||
),
|
||||
sa.Column(
|
||||
"updated_at",
|
||||
sa.DateTime(timezone=True),
|
||||
nullable=False,
|
||||
),
|
||||
sa.ForeignKeyConstraint(
|
||||
["connector_run_id"],
|
||||
["connector_sanctions_acquisition_runs.id"],
|
||||
name=op.f(
|
||||
"fk_connector_sanctions_snapshots_connector_run_id_"
|
||||
"connector_sanctions_acquisition_runs"
|
||||
),
|
||||
ondelete="RESTRICT",
|
||||
),
|
||||
sa.PrimaryKeyConstraint(
|
||||
"id",
|
||||
name=op.f("pk_connector_sanctions_snapshots"),
|
||||
),
|
||||
sa.UniqueConstraint(
|
||||
"connector_run_id",
|
||||
name="uq_connector_sanctions_snapshot_run",
|
||||
),
|
||||
)
|
||||
for column in (
|
||||
"tenant_id",
|
||||
"provider_id",
|
||||
"jurisdiction",
|
||||
"list_type",
|
||||
"source_id",
|
||||
"source_version",
|
||||
"acquired_at",
|
||||
"sha256",
|
||||
"connector_run_id",
|
||||
):
|
||||
op.create_index(
|
||||
op.f(f"ix_connector_sanctions_snapshots_{column}"),
|
||||
"connector_sanctions_snapshots",
|
||||
[column],
|
||||
)
|
||||
op.create_index(
|
||||
"ix_connector_sanctions_snapshot_source",
|
||||
"connector_sanctions_snapshots",
|
||||
["tenant_id", "provider_id", "acquired_at"],
|
||||
)
|
||||
op.create_index(
|
||||
"ix_connector_sanctions_snapshot_version",
|
||||
"connector_sanctions_snapshots",
|
||||
["provider_id", "source_id", "source_version"],
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
op.drop_table("connector_sanctions_snapshots")
|
||||
op.drop_table("connector_sanctions_acquisition_runs")
|
||||
Reference in New Issue
Block a user