Files
ss-tools/backend/alembic/versions/z5a6b7c8d9e0_add_scenario_execution_tables.py

75 lines
3.7 KiB
Python

# #region Alembic.ScenarioExecutionTables [C:3] [TYPE Module] [SEMANTICS alembic,scenario,execution,artifact,approval,resume]
# @ingroup Alembic
# @BRIEF Add 044 execution artifacts, PROD approval gates, run idempotency/resume columns.
# @LAYER Database
"""add generic-owner scenario execution artifacts, PROD approval gates, run idempotency/resume columns (044 T014f/T017/T018/T019)"""
from collections.abc import Sequence
import sqlalchemy as sa
from alembic import op
revision: str = "z5a6b7c8d9e0"
down_revision: str | Sequence[str] | None = "y4z5a6b7c8d9"
branch_labels: str | Sequence[str] | None = None
depends_on: str | Sequence[str] | None = None
def upgrade() -> None:
op.create_table(
"scenario_artifacts",
sa.Column("id", sa.String(36), nullable=False),
sa.Column("owner_type", sa.String(32), nullable=False),
sa.Column("owner_id", sa.String(36), nullable=False),
sa.Column("kind", sa.String(32), nullable=False),
sa.Column("name", sa.String(255), nullable=False),
sa.Column("content_ref", sa.String(256), nullable=False),
sa.Column("sha256", sa.String(64), nullable=False),
sa.Column("retention_class", sa.String(32), nullable=False),
sa.Column("created_at", sa.DateTime(), nullable=False),
sa.PrimaryKeyConstraint("id"),
)
op.create_index("ix_scenario_artifacts_owner", "scenario_artifacts", ["owner_type", "owner_id"])
op.create_index(
"ix_scenario_artifacts_owner_kind", "scenario_artifacts", ["owner_type", "owner_id", "kind"]
)
op.create_table(
"action_approval_gates",
sa.Column("id", sa.String(36), nullable=False),
sa.Column("owner_type", sa.String(32), nullable=False),
sa.Column("owner_id", sa.String(36), nullable=False),
sa.Column("operation", sa.String(64), nullable=False),
sa.Column("required_permission", sa.String(64), nullable=False),
sa.Column("request_hash", sa.String(64), nullable=False),
sa.Column("status", sa.String(16), nullable=False),
sa.Column("decision", sa.String(16), nullable=True),
sa.Column("actor_id", sa.String(128), nullable=True),
sa.Column("comment", sa.String(2000), nullable=True),
sa.Column("expires_at", sa.DateTime(), nullable=True),
sa.Column("created_at", sa.DateTime(), nullable=False),
sa.Column("decided_at", sa.DateTime(), nullable=True),
sa.PrimaryKeyConstraint("id"),
)
op.create_index("ix_action_approval_gates_owner", "action_approval_gates", ["owner_type", "owner_id"])
op.create_index("ix_action_approval_gates_status", "action_approval_gates", ["status"])
# Idempotency request fingerprint and infrastructure-pause resume token on existing run rows.
op.add_column("scenario_runs", sa.Column("request_hash", sa.String(64), nullable=True))
op.add_column("scenario_runs", sa.Column("resume_token", sa.String(128), nullable=True))
op.create_index("ix_scenario_runs_request_hash", "scenario_runs", ["request_hash"])
def downgrade() -> None:
op.drop_index("ix_scenario_runs_request_hash", table_name="scenario_runs")
op.drop_column("scenario_runs", "resume_token")
op.drop_column("scenario_runs", "request_hash")
op.drop_index("ix_action_approval_gates_status", table_name="action_approval_gates")
op.drop_index("ix_action_approval_gates_owner", table_name="action_approval_gates")
op.drop_table("action_approval_gates")
op.drop_index("ix_scenario_artifacts_owner_kind", table_name="scenario_artifacts")
op.drop_index("ix_scenario_artifacts_owner", table_name="scenario_artifacts")
op.drop_table("scenario_artifacts")
# #endregion Alembic.ScenarioExecutionTables