Commit cc36dc6c by luoqi

feat(recall): 宿主跟进闸 —— 宿主正在跟进的患者不进召回池

宿主自己已建复杂病例 / 工单、客服或咨询师在推进的患者,PAC 不再发起召回:
两边同时联系同一个人,患者体验差,也显得两个系统各说各话。

落点 patient_profiles.host_follow_up_active(canonical hostFollowUpActive),
与 do_not_contact / deceased 并列在召回②合规硬过滤,但性质不同:
  合规闸 = 法务/风险,永久,需人工解除
  跟进闸 = 协作分工,临时,宿主停手下次推主档即回池

【本次最关键的决定:三态而非两态】
  null  = 宿主未提供该信号(jvs-dw 未接入)→ 不启用该闸
  false = 宿主明确说"没在跟"
  true  = 正在跟 → 排除
由此三条纪律,全部有测试锁住:
  1. 列可空且**无 @default** —— 给默认值等于把存量 38 万患者一次性断言成某种状态,
     且将来分不出"没接入"和"接了但没跟"
  2. SQL 一律 `IS NOT TRUE`,**绝不能** `= false` —— 后者遇 NULL 恒 UNKNOWN,
     会把未接入宿主的患者全部静默挡在池外(不报错、不留痕,只表现为池子空了)
  3. upsert full 分支不能 `?? false`(那是替宿主表态);partial 分支未提供则不进 update 集合

改动:
  - canonical: hostFollowUpActive(可空无默认)+ 挂进 patient.booleanFields,自动吃 0/1
  - prisma: 副表加列 + 索引;migration 加可空列不重写表,存量行为不变
  - scenario SQL: 入池闸 + 注释框图同步
  - recall-debug: compliance 增补该项,否则排查时会显示"合规通过"却查不到人
  - 测试 host-follow-up-gate.spec.ts(18 项)

FRIDAY 侧对应 has_active_complex_case,assembler 映射待宿主确认列名与 is_del 语义后再接,
故本次**未接 FRIDAY 映射** —— 该闸对所有宿主当前均为 NULL,行为与上线前完全一致。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
parent e518cf6a
Pipeline #3499 failed in 0 seconds