-- 「到期改档」调度锚点。
--
-- 水位闸只在事实变了时放行重算,但有一类变化不伴随任何事实变动 —— 时间自己走了:
-- 急迫等级跨 30/90 天线、生命周期跨 180/540/730、RFM 的 R 跨 540/730/1095/1460、
-- 年龄跨段、种植年龄禁忌满 19 岁解除、滑动窗口把最老记录挤出去。
-- 这类患者旧实现里永远不会被重算。靠"每天全量扫"等于把闸拆了,所以存确切到期时刻,
-- 夜扫只捞 next_boundary_at <= now() 的那一小撮(每天几百到几千,不是 40 万)。
ALTER TABLE "personas" ADD COLUMN "next_boundary_at" TIMESTAMPTZ(3);

-- 夜扫分支的支撑索引。personas 约 50 万行,建索引很快,无需 CONCURRENTLY 预建。
CREATE INDEX IF NOT EXISTS "personas_superseded_at_next_boundary_at_idx"
  ON "personas"("superseded_at", "next_boundary_at");

-- ⚠️ 存量行 next_boundary_at 为 NULL,而 NULL 的语义是"不再改档"—— **不会自愈**:
-- 水位闸认为这些版本新鲜,永远不会重算,也就永远算不出边界。必须部署后强制跑一次:
--   pnpm recompute-persona:prod -- --host=jvs-dw --concurrency=8 --force
-- 与 fact_watermark 的回填是同一次运行。写侧节流保证这次全量跑基本不产新版本
-- (本地 13,268 患者实测:success=0 / refreshed=885 / unchanged=12,383)。
