114 lines
5.4 KiB
Python
114 lines
5.4 KiB
Python
# #region Alembic.ScenarioAutomationTables [C:3] [TYPE Module] [SEMANTICS alembic,scenario,automation,schedule,trigger,notification]
|
|
# @ingroup Alembic
|
|
# @BRIEF Add 046 scenario schedules, trigger rules and notification events tables.
|
|
# @LAYER Database
|
|
"""add scenario automation tables (046 dashboard-scenario-automation)
|
|
|
|
Revision ID: a8b9c0d1e2f3
|
|
Revises: z7a8b9c0d1e2
|
|
Create Date: 2026-08-20
|
|
|
|
"""
|
|
from collections.abc import Sequence
|
|
|
|
import sqlalchemy as sa
|
|
|
|
from alembic import op
|
|
|
|
# revision identifiers, used by Alembic.
|
|
revision: str = "a8b9c0d1e2f3"
|
|
down_revision: str | Sequence[str] | None = "z7a8b9c0d1e2"
|
|
branch_labels: str | Sequence[str] | None = None
|
|
depends_on: str | Sequence[str] | None = None
|
|
|
|
|
|
def upgrade() -> None:
|
|
"""Create scenario_schedules, scenario_trigger_rules, scenario_automation_policies,
|
|
scenario_notification_events (046 automation persistence).
|
|
|
|
revision_id is nullable — required only when revision_policy=pinned; a `current`
|
|
schedule/rule resolves the atomically activated revision at dispatch time (042).
|
|
"""
|
|
# ── scenario_schedules ──
|
|
op.create_table(
|
|
"scenario_schedules",
|
|
sa.Column("id", sa.String(length=36), nullable=False),
|
|
sa.Column("scenario_id", sa.String(length=36), nullable=False),
|
|
sa.Column("revision_policy", sa.String(length=16), nullable=False),
|
|
sa.Column("revision_id", sa.String(length=36), nullable=True),
|
|
sa.Column("environment_id", sa.String(length=128), nullable=False),
|
|
sa.Column("cron_expr", sa.String(length=128), nullable=False),
|
|
sa.Column("timezone", sa.String(length=64), nullable=False),
|
|
sa.Column("missed_execution_policy", sa.String(length=16), nullable=False),
|
|
sa.Column("policy_id", sa.String(length=36), nullable=True),
|
|
sa.Column("enabled", sa.Boolean(), nullable=False),
|
|
sa.Column("max_instances", sa.Integer(), nullable=False),
|
|
sa.Column("misfire_grace_time", sa.Integer(), nullable=False),
|
|
sa.Column("created_by", sa.String(length=128), nullable=True),
|
|
sa.Column("created_at", sa.DateTime(), nullable=False),
|
|
sa.PrimaryKeyConstraint("id"),
|
|
)
|
|
op.create_index("ix_scenario_schedules_scenario_id", "scenario_schedules", ["scenario_id"])
|
|
|
|
# ── scenario_trigger_rules ──
|
|
op.create_table(
|
|
"scenario_trigger_rules",
|
|
sa.Column("id", sa.String(length=36), nullable=False),
|
|
sa.Column("trigger", sa.String(length=64), nullable=False),
|
|
sa.Column("scenario_id", sa.String(length=36), nullable=False),
|
|
sa.Column("revision_policy", sa.String(length=16), nullable=False),
|
|
sa.Column("revision_id", sa.String(length=36), nullable=True),
|
|
sa.Column("environment_id", sa.String(length=128), nullable=False),
|
|
sa.Column("policy_id", sa.String(length=36), nullable=True),
|
|
sa.Column("enabled", sa.Boolean(), nullable=False),
|
|
sa.Column("conditions", sa.JSON(), nullable=False),
|
|
sa.Column("created_at", sa.DateTime(), nullable=False),
|
|
sa.PrimaryKeyConstraint("id"),
|
|
)
|
|
op.create_index("ix_scenario_trigger_rules_trigger", "scenario_trigger_rules", ["trigger"])
|
|
|
|
# ── scenario_automation_policies ──
|
|
op.create_table(
|
|
"scenario_automation_policies",
|
|
sa.Column("id", sa.String(length=36), nullable=False),
|
|
sa.Column("name", sa.String(length=255), nullable=False),
|
|
sa.Column("enabled", sa.Boolean(), nullable=False),
|
|
sa.Column("workload_class", sa.String(length=32), nullable=False),
|
|
sa.Column("max_concurrent_per_env", sa.Integer(), nullable=False),
|
|
sa.Column("dedup_window_seconds", sa.Integer(), nullable=False),
|
|
sa.Column("overlap_rule", sa.String(length=16), nullable=False),
|
|
sa.Column("retention_days", sa.Integer(), nullable=False),
|
|
sa.Column("prod_gate_required", sa.Boolean(), nullable=False),
|
|
sa.Column("on_repeated_failure", sa.String(length=16), nullable=False),
|
|
sa.Column("created_at", sa.DateTime(), nullable=False),
|
|
sa.PrimaryKeyConstraint("id"),
|
|
)
|
|
|
|
# ── scenario_notification_events ──
|
|
op.create_table(
|
|
"scenario_notification_events",
|
|
sa.Column("id", sa.String(length=36), nullable=False),
|
|
sa.Column("event_type", sa.String(length=32), nullable=False),
|
|
sa.Column("scenario_id", sa.String(length=36), nullable=False),
|
|
sa.Column("run_id", sa.String(length=36), nullable=True),
|
|
sa.Column("severity", sa.String(length=16), nullable=False),
|
|
sa.Column("payload", sa.JSON(), nullable=False),
|
|
sa.Column("created_at", sa.DateTime(), nullable=False),
|
|
sa.PrimaryKeyConstraint("id"),
|
|
)
|
|
op.create_index(
|
|
"ix_scenario_notification_events_event_type", "scenario_notification_events", ["event_type"]
|
|
)
|
|
|
|
|
|
def downgrade() -> None:
|
|
"""Drop scenario automation tables in reverse dependency order."""
|
|
op.drop_index("ix_scenario_notification_events_event_type", table_name="scenario_notification_events")
|
|
op.drop_table("scenario_notification_events")
|
|
op.drop_table("scenario_automation_policies")
|
|
op.drop_index("ix_scenario_trigger_rules_trigger", table_name="scenario_trigger_rules")
|
|
op.drop_table("scenario_trigger_rules")
|
|
op.drop_index("ix_scenario_schedules_scenario_id", table_name="scenario_schedules")
|
|
op.drop_table("scenario_schedules")
|
|
# #endregion Alembic.ScenarioAutomationTables
|