"""Track when a filing gap stops pausing setups Revision ID: 034 Revises: 033 Create Date: 2026-08-21 00:00:00.000000 An escalated gap stops pausing setups while the issuer's own fundamentals are still recent (``GAP_GATE_RECENT_FILING_DAYS``). That reprieve is not permanent: the stored filings age out, or a newer gap appears, and the pause returns — silently, because ``filing_gap_aged`` only escalates gaps whose ``escalated_at`` is NULL and so never fires twice for the same gap. ``exempted_at`` is the state marker that makes the transition observable. It is set (quietly) while the issuer is exempt and cleared when the exemption lapses, which is when ``filing_gap_repaused`` fires — once per lapse, re-arming if the issuer's data recovers and ages out again. Nullable, and carrying no meaning of its own beyond that state: an existing gap starts NULL and is stamped on the next import that finds it exempt. """ from typing import Sequence, Union from alembic import op import sqlalchemy as sa revision: str = "034" down_revision: Union[str, None] = "033" branch_labels: Union[str, Sequence[str], None] = None depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: op.add_column( "sec_filing_gaps", sa.Column("exempted_at", sa.DateTime(timezone=True), nullable=True), ) def downgrade() -> None: op.drop_column("sec_filing_gaps", "exempted_at")