"""device_alert_events Adds an insert-only history log of device alert transitions (WARNING/CRITICAL/ FAILED only — CLEARED is not logged here). device_alerts remains the current- state table and is untouched; this is purely additive, used to answer "when was the most recent issue on this device" even after it has been resolved. Also adds an optional rssi column to heartbeats, for a signal-strength indicator once firmware starts reporting it on the heartbeat payload. Revision ID: d4e5f6a7b8c9 Revises: c3d4e5f6a7b8 Create Date: 2026-07-13 00:00:00.000000 """ from typing import Sequence, Union import sqlalchemy as sa from alembic import op revision: str = "d4e5f6a7b8c9" down_revision: Union[str, None] = "c3d4e5f6a7b8" branch_labels: Union[str, Sequence[str], None] = None depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: op.create_table( "device_alert_events", sa.Column("id", sa.BigInteger(), primary_key=True, autoincrement=True), sa.Column("device_serial", sa.String(128), nullable=False), sa.Column("subsystem", sa.String(128), nullable=False), sa.Column("state", sa.String(64), nullable=False), sa.Column("message", sa.Text(), nullable=True), sa.Column("occurred_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.func.now()), ) op.create_index( "idx_device_alert_events_serial_occurred", "device_alert_events", ["device_serial", sa.text("occurred_at DESC")], ) op.add_column("heartbeats", sa.Column("rssi", sa.Integer(), nullable=True)) def downgrade() -> None: op.drop_column("heartbeats", "rssi") op.drop_index("idx_device_alert_events_serial_occurred", table_name="device_alert_events") op.drop_table("device_alert_events")