"""Seed the ``feishu.approval_drift_reconciler`` scheduled job. Fast-path reconcile (every 15 minutes) for missed terminal Feishu approval webhooks: scans pending ``approval_requests`` older than 10 minutes, replays the missed callback when Feishu's side is already terminal. Companion to the daily ``feishu.approval_pending_reaper`` (which only scans rows pending ≥14 days and owns expiry). Context: Feishu webhook delivery is at-most-once; on top of that, a form-decoding crash (fixed in the same PR) made every asset-linked APPROVED callback 500 — rows sat 待处理 until an admin opened the detail drawer. This cron closes the drift window to ≤15 minutes. Revision ID: 378 Revises: 377 """ import sqlalchemy as sa from alembic import op revision = "378" down_revision = "377" branch_labels = None depends_on = None JOB = "feishu.approval_drift_reconciler" def upgrade() -> None: bind = op.get_bind() job_exists = bind.execute( sa.text("SELECT 1 FROM scheduled_jobs WHERE name = :n LIMIT 1"), {"n": JOB}, ).scalar() if not job_exists: bind.execute(sa.text( """ INSERT INTO scheduled_jobs (id, name, display_name, description, handler_key, trigger_type, interval_seconds, cron_expr, timezone, enabled, config, run_count, failure_count, created_at, updated_at) VALUES (UUID(), :n, :dn, :desc, :hk, 'interval', 900, NULL, 'UTC', 1, JSON_OBJECT(), 0, 0, NOW(), NOW()) """, ), { "n": JOB, "dn": "Feishu approval 漂移快速对账", "desc": ( "每 15 分钟扫描 pending 且提交超过 10 分钟的审批实例," "Feishu 侧已终态则 replay missed callback。" "补 webhook at-most-once 丢终态事件的窗口;" "过期回收仍归每日 approval_pending_reaper。" ), "hk": JOB, }) def downgrade() -> None: op.get_bind().execute( sa.text("DELETE FROM scheduled_jobs WHERE name = :n"), {"n": JOB}, )