Commit ae5bf916 by luoqi

fix(recall): 补"同牙位替代性定性治疗"排除闸 ⑤e(对齐治疗链 alt-close)

召回 SQL 排除口径比治疗链 markAlternativeClosed 窄:链会因同牙后续做了
implant/prosthodontic(种植/冠桥 = definitive 替代治疗)而替代闭环,召回 SQL 却只看
本类目 actual(⑤a)+ 同牙拔除(⑤c),漏了"做了冠/种植即定性"。

例 韩雷:K04@11 但 11 已戴冠(prosthodontic,无 endodontic actual 记录)→ 治疗链替代
闭环 → UI "可不召回",但召回 SQL 仍产 endo_no_rct@11 → 误建 plan → 患者进召回列表却
显示"可不召回",自相矛盾。

修:加 ⑤e —— 诊断后同牙位(交集)有 implant/prosthodontic 的 actual → 排除该诊断召回。
(surgical 拔除已由 ⑤c;K08 的 implant/prosthodontic 已在 ⑤a,此处冗余无害;仅对有牙位
信号生效,全口诊断 K05 不触发。)

验证:韩雷 → 0 plan(掉出召回列表);826790 → 仍正确召回 31;32;41;42;43(无 implant/
prosthodontic 覆盖,不误伤)。全量 89 测试通过,tsc 0。

注(后续):runAllForHost 只处理"有 hit 的 patient",不会 abandon"已不再命中"的存量
active/assigned plan(患者治好后旧 plan 仍滞留)。此为独立 gap,待补"无 hit 清理"+
assigned plan 复评策略。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
parent b0b9705a
......@@ -393,6 +393,30 @@ export class TreatmentInitiationRecallScenario implements PlanScenarioPlugin {
WHERE trim(c) = ANY(${complaintTexts}::text[])
)
)
AND NOT EXISTS ( -- ⑤e 排除:同牙位"替代性定性治疗"(种植/冠桥)
-- 镜像 chain-composer.markAlternativeClosed:同一颗牙诊断后做了 implant / prosthodontic
-- (种植 / 冠桥 = definitive 替代修复)→ 该牙已定性处理,原诊断(根管/充填/牙体损伤等)
-- 召回失去意义。例 韩雷:K04@11 但 11 已戴冠(prosthodontic)→ 治疗链替代闭环,
-- 旧召回 SQL 只看 endodontic actual 漏掉 → 误召;此闸补齐"召回 ↔ 治疗链"口径。
-- 拔除(surgical)已由 ⑤c 覆盖;K08 的 implant/prosthodontic 已在 ⑤a(同类目)— 此处冗余无害。
-- 仅对有具体牙位信号生效(全口诊断不走);要求 actual 有牙位 + 牙位交集 + 诊断之后。
SELECT 1 FROM patient_facts alt
WHERE alt.patient_id = p.id
AND alt.type = 'treatment_record'
AND alt.kind = 'actual'
AND alt.status IN ('active', 'fulfilled')
AND alt.content->>'category' IN ('implant', 'prosthodontic')
AND alt.occurred_at >= COALESCE(sig.occurred_at, sig.planned_for) -- 诊断之后
AND COALESCE(NULLIF(trim(sig.content->>'tooth_position'), ''), '') != '' -- 信号有牙位
AND COALESCE(NULLIF(trim(alt.content->>'tooth_position'), ''), '') != '' -- actual 有牙位
AND array_remove(
string_to_array(regexp_replace(sig.content->>'tooth_position', '[^0-9;]+', ';', 'g'), ';'),
''
) && array_remove(
string_to_array(regexp_replace(alt.content->>'tooth_position', '[^0-9;]+', ';', 'g'), ';'),
''
)
)
`;
// ⭐ 同 patient 同 sub_scenario 的多 sig 按 tooth-overlap 合并(union-find)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment