Files
ss-tools/backend/alembic/versions/l6m7n8o9p1q2_maintenance_event_auto_end.py
busya 093f7f600f fix(maintenance): harden banner lifecycle and guarded migrations
- Guard maintenance Alembic operations for create_all-only tables on clean DBs
- Add guarded verification_runs.fanout_plan_id backfill migration
- Improve maintenance banner rendering, chart management, orchestration, and API routes
- Expand assistant maintenance tool and edge-case coverage

Tests: cd backend && source .venv/bin/activate && python -m pytest -q tests/test_maintenance_api.py tests/test_maintenance_service.py tests/api/test_assistant_tool_maintenance.py tests/api/test_maintenance_routes_edge.py (77 passed)
2026-08-09 08:22:16 +03:00

49 lines
1.9 KiB
Python

# #region Alembic.MaintenanceEventAutoEnd [C:3] [TYPE Module] [SEMANTICS alembic,maintenance,auto-end,column]
# @ingroup Alembic
# @BRIEF Add maintenance_events.auto_end flag (opt-in automatic ending at end_time).
# @LAYER Database
# @RELATION DEPENDS_ON -> [Models.Maintenance.MaintenanceModels]
# @INVARIANT auto_end defaults to false — end_time stays informational unless the caller opts in.
# @RATIONALE end_time alone is used for idempotency and banner text; an explicit flag lets the
# scheduler end maintenance automatically only when the caller asks for it.
# @REJECTED Auto-ending on end_time presence alone was rejected — ETL tools may pass a window
# purely informational and would be surprised by an automatic end.
"""add auto_end flag to maintenance_events
Revision ID: l6m7n8o9p1q2
Revises: k5l6m7n8o9p0
Create Date: 2026-08-04 15:55:00.000000
"""
from collections.abc import Sequence
import sqlalchemy as sa
from sqlalchemy import inspect
from alembic import op
# revision identifiers, used by Alembic.
revision: str = "l6m7n8o9p1q2"
down_revision: str | Sequence[str] | None = "k5l6m7n8o9p0"
branch_labels: str | Sequence[str] | None = None
depends_on: str | Sequence[str] | None = None
def upgrade() -> None:
"""Add auto_end column with server default false (existing rows become informational)."""
# maintenance_events is a create_all()-only table on a fresh install; guard so a clean-DB
# upgrade is a no-op and ORM schema initialization creates it with the final shape.
if inspect(op.get_bind()).has_table("maintenance_events"):
op.add_column(
"maintenance_events",
sa.Column("auto_end", sa.Boolean(), nullable=False, server_default=sa.false()),
)
def downgrade() -> None:
"""Drop the auto_end column."""
if inspect(op.get_bind()).has_table("maintenance_events"):
op.drop_column("maintenance_events", "auto_end")
# #endregion Alembic.MaintenanceEventAutoEnd