"""Seed the default-handover reconcile scheduled job. Seeds ``hr.offboarding_handover_reconcile`` (daily 02:40 UTC — deliberately BEFORE the terminal delete sweeps at 03:00 / 03:10, so a handover person backfilled this morning unblocks the same morning's delete instead of waiting a full day). Why the job exists: ``start_process`` prefills ``offboarding_processes.default_handover_person_id`` from the leaver's HRIS manager exactly once, at creation. When the manager link has not resolved yet at that moment (``backfill_manager_links`` re-links late-arriving managers on a later sync), the prefill lands NULL and nothing ever revisits it — production carried 12 completed and 2 in-flight processes with no handover person, and ``hice@pingcap.com``'s Google account was hard-deleted in exactly that state. Config: ``{"batch_limit": 500}``. No schema change (fills an existing column). Revision ID: 467 Revises: 466 """ import uuid import sqlalchemy as sa from alembic import op revision = "467" down_revision = "466" branch_labels = None depends_on = None JOB = "hr.offboarding_handover_reconcile" 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 (:id, :name, :display_name, :description, :name, 'cron', NULL, '40 2 * * *', 'UTC', 1, :config, 0, 0, NOW(), NOW()) """ ), { "id": str(uuid.uuid4()), "name": JOB, "display_name": "离职默认交接人回填", "description": ( "每日 02:40 UTC 重扫仍然有意义的离职流程(未完成的,以及" "虽已完成但终删尚未落地的),用「上级 → 上级链 → 平台兜底人」" "解析链回填空的默认交接人;解析不出来的给 IT 发一次性汇总" "告警(每个流程只发一次)。只填空值,不覆盖 IT 设好的人。" "排在终删任务(03:00 / 03:10)之前,当天回填当天生效。" ), "config": '{"batch_limit": 500}', }, ) def downgrade() -> None: bind = op.get_bind() bind.execute(sa.text("DELETE FROM scheduled_jobs WHERE name = :n"), {"n": JOB})