Commit 19be1c41 by luoqi

fix(recall): 废用牙/无功能牙 不进 K08 种植召回(临床语义剔除)

host diagnosis enum_mapping 把"废用牙/无功能牙"也映射到 K08(标注"临床功能性缺失"),
于是它们走 missing_tooth 子场景被当缺牙、召回种植。但临床上废用牙是"牙还在、无咬合功能
(对颌缺失/过长)"→ 该拔除或观察,不是修复(种植/桥/义齿)对象。

案例:826790 的 missing_tooth@18;28;38;48(name_zh=废用牙)被召回且 91 分排第一 = 催患者
来种植废用智齿(误召);韩雷 38;48 同理。

修:scenario WHERE 加临床语义剔除 —— sig.content->>'name_zh' ∈ {废用牙,无功能牙} 不进召回。
host 原文 name_zh 在 diagnosis_record.content 留底,据此精确剔除,免改 yaml / 免 reparse。
这俩名只映射到 K08 → 仅 missing_tooth 受影响,其余子场景无副作用。

验证(本地 100):826790 91 分误召消失;K08 诊断里 废用牙8+无功能牙6=14 条误召剔除,
真缺失(缺失/缺失牙/牙列缺损)12 条仍正常召回。全量 89 测试通过,tsc 0。
(拔牙本身不做泛召回;真缺失修复召回不变 — 详见 docs 讨论。)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
parent ae5bf916
......@@ -63,6 +63,14 @@ import { toothSet } from '../../../sync/pipeline/parsers/tooth-position.util';
* 通用过滤(每个子场景 SQL 自己写,共用片段后续抽):
* active + 非 DNC + 非 deceased(phone 缺失暂不强制,DW 不提供)
*/
/// 临床语义剔除:这些 name_zh 被 host 映射到 K08(yaml 标注"临床功能性缺失"),但牙其实
/// 还在、只是无咬合功能(对颌缺失/过长)→ 临床该拔除或观察,**不是修复(种植/桥/义齿)对象**
/// → 不进 K08 种植召回。host 原文 name_zh 在 diagnosis_record.content 留底,据此精确剔除。
/// 案例:韩雷 38;48 / 826790 18;28;38;48 都是"废用牙"被误当缺牙召回种植(91 分误召)。
/// 注:这跟"真缺失"(缺失/牙列缺损 → 该修复)区分开;拔牙本身不做泛召回(详见 docs 讨论)。
const RESTORATION_INELIGIBLE_NAMES = ['废用牙', '无功能牙'];
@Injectable()
export class TreatmentInitiationRecallScenario implements PlanScenarioPlugin {
readonly key = PlanScenario.TREATMENT_INITIATION_RECALL;
......@@ -310,6 +318,9 @@ export class TreatmentInitiationRecallScenario implements PlanScenarioPlugin {
AND sig.content->>'code' = ANY(${allCodes}::text[]) -- ③ 信号 code 命中
AND COALESCE(sig.occurred_at, sig.planned_for) IS NOT NULL -- ④ 时间不为空
AND COALESCE(sig.occurred_at, sig.planned_for) <= ${this.daysAgo(scope.now, start)}::timestamptz -- ④ 过 cooldown
-- ④' 临床语义剔除:废用牙/无功能牙(host 映射到 K08,但牙还在无功能 → 该拔/观察,非修复对象)
-- 不进种植召回。仅这些 name_zh 受影响(它们只在 K08),其余子场景诊断不含此名 → 无副作用。
AND COALESCE(sig.content->>'name_zh', '') <> ALL(${RESTORATION_INELIGIBLE_NAMES}::text[])
AND NOT EXISTS ( -- ⑤a 排除:同类 actual 治疗(已开始做)
SELECT 1 FROM patient_facts tx
WHERE tx.patient_id = p.id
......
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