"""identity_sync_targets.alert_enabled — per-target failure-alert on/off switch. Revision ID: 309 Revises: 308 Create Date: 2026-06-19 Adds a NOT NULL boolean (server_default true) master switch for each target's run-failure alerting. When false the notifier sends nothing — not even to the configured ``alert_recipient_ids``. Existing rows default to ``true`` so a target that already has recipients keeps alerting; a target with no recipients stays silent regardless (the IT-admin fallback was removed in the same change — see DECISIONS.md 2026-06-19, "不要默认通知管理员"). Idempotent + re-runnable. """ from __future__ import annotations import sqlalchemy as sa from alembic import op revision = "309" down_revision = "308" branch_labels = None depends_on = None _TABLE = "identity_sync_targets" _COLUMN = "alert_enabled" def _has_column(bind, table: str, column: str) -> bool: insp = sa.inspect(bind) return any(c["name"] == column for c in insp.get_columns(table)) def upgrade() -> None: bind = op.get_bind() if not _has_column(bind, _TABLE, _COLUMN): op.add_column( _TABLE, sa.Column( _COLUMN, sa.Boolean(), nullable=False, server_default=sa.text("1"), ), ) def downgrade() -> None: bind = op.get_bind() if _has_column(bind, _TABLE, _COLUMN): op.drop_column(_TABLE, _COLUMN)