mirror of
https://github.com/rennf93/roboco.git
synced 2026-08-03 07:23:24 +02:00
65 lines
2.0 KiB
Python
65 lines
2.0 KiB
Python
"""Add notifications.reescalation_count/_delivered_count + last_reescalated_at.
|
|||
|
|
|
||
|
|
`sweep_expired_notifications` used to re-escalate EVERY ack-required
|
||
|
|
notification past `expires_at` on every ~1min sweep tick, forever — a static
|
||
|
|
pile of stale notifications produced a fresh blocker_escalation row (+
|
||
|
|
Telegram DM) per row per tick. These three columns back a per-notification
|
||
|
|
exponential backoff (first re-escalation at expiry, then doubling from
|
||
|
|
`notification_reescalation_base_seconds`, capped at 24h, hard-stopped past
|
||
|
|
`notification_max_reescalations`): `reescalation_count` is the attempt
|
||
|
|
counter (claimed via compare-and-set even when delivery then fails),
|
||
|
|
`reescalation_delivered_count` is how many of those attempts actually
|
||
|
|
reached a recipient, `last_reescalated_at` anchors the backoff interval.
|
||
|
|
Additive and default-`0`/`NULL`: existing rows read as `count=0`, preserving
|
||
|
|
today's first-fire semantics.
|
||
|
|
|
||
|
|
Revision ID: 079_notification_backoff
|
||
|
|
Revises: 078_project_codegen_command
|
||
|
|
Create Date: 2026-07-22
|
||
|
|
"""
|
||
|
|
|
||
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
import sqlalchemy as sa
|
||
|
|
from alembic import op
|
||
|
|
|
||
|
|
revision = "079_notification_backoff"
|
||
|
|
down_revision = "078_project_codegen_command"
|
||
|
|
branch_labels: dict[str, str] | None = None
|
||
|
|
depends_on: dict[str, str] | None = None
|
||
|
|
|
||
|
|
|
||
|
|
def upgrade() -> None:
|
||
|
|
op.add_column(
|
||
|
|
"notifications",
|
||
|
|
sa.Column(
|
||
|
|
"reescalation_count",
|
||
|
|
sa.Integer(),
|
||
|
|
nullable=False,
|
||
|
|
server_default="0",
|
||
|
|
),
|
||
|
|
)
|
||
|
|
op.add_column(
|
||
|
|
"notifications",
|
||
|
|
sa.Column(
|
||
|
|
"reescalation_delivered_count",
|
||
|
|
sa.Integer(),
|
||
|
|
nullable=False,
|
||
|
|
server_default="0",
|
||
|
|
),
|
||
|
|
)
|
||
|
|
op.add_column(
|
||
|
|
"notifications",
|
||
|
|
sa.Column(
|
||
|
|
"last_reescalated_at",
|
||
|
|
sa.DateTime(timezone=True),
|
||
|
|
nullable=True,
|
||
|
|
),
|
||
|
|
)
|
||
|
|
|
||
|
|
|
||
|
|
def downgrade() -> None:
|
||
|
|
op.drop_column("notifications", "last_reescalated_at")
|
||
|
|
op.drop_column("notifications", "reescalation_delivered_count")
|
||
|
|
op.drop_column("notifications", "reescalation_count")
|