"""send retries for 24 hours, and an account's sync health A send the mail server could not take (SMTP unreachable, a temporary 4xx) is no longer failed at once: the outbox row goes to ``retrying`` and is tried again with growing gaps until ``retry_until`` (24 hours after the first failure). ``attempts`` counts the tries, ``next_attempt_at`` is when the next one runs. An account whose server cannot be reached for a while carries ``sync_error`` (``unreachable``) and ``sync_error_since``; both clear on the next success. Revision ID: 0021 Revises: 0020 Create Date: 2026-10-06 """ from __future__ import annotations from collections.abc import Sequence from alembic import op revision: str = "0021" down_revision: str | None = "0020" branch_labels: str | Sequence[str] | None = None depends_on: str | Sequence[str] | None = None _COLUMNS = ( ("outbox", "attempts", "integer NOT NULL DEFAULT 0"), ("outbox", "next_attempt_at", "timestamptz"), ("outbox", "retry_until", "timestamptz"), ("accounts", "sync_error", "text"), ("accounts", "sync_error_since", "timestamptz"), ) def upgrade() -> None: for table, name, ddl in _COLUMNS: op.execute(f"ALTER TABLE {table} ADD COLUMN {name} {ddl}") def downgrade() -> None: for table, name, _ in reversed(_COLUMNS): op.execute(f"ALTER TABLE {table} DROP COLUMN IF EXISTS {name}")