Commit 4d48fb4c by luoqi

fix(recall): 外院已治疗匹配收紧 — 只看 result + 紧邻治疗词 + 排意图(修干扰)

原规则 result||follow_content + "外院"+任意治疗词太宽,两类干扰:
- follow_content 含营销标签"种植潜客/洁牙/正畸"→ 与 result 的"外院"误拼命中
  (种植潜客=潜在客户没做,反该召);
- "建议/打算/考虑…外院"(意图未去)被当成已治疗。

收紧(全库验证):
- 只 match patient_return_visits.result(弃 follow_content);
- POS=治疗词紧邻外院:外院(治疗|种植|矫正|矫治|修复|根管)|在外院|外院已|已外院;
- NEG=排意图:(建议|打算|考虑|可能|拟)[^,;。]{0,6}外院。
POS∧¬NEG 命中 851 患者(原 1812 含大量噪音);被剔除的全是"打算/考虑外院"假阳。

验证:李姝妤仍正确排除,21 人理由 41 不变(无回退无新误杀);recompute exit=0。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
parent 5e9744c6
import { Prisma } from '@prisma/client';
import {
EXTERNAL_TREATMENT_VISIT_PATTERNS,
EXTERNAL_TREATMENT_VISIT_POS_RE,
EXTERNAL_TREATMENT_VISIT_NEG_RE,
NO_RESTORATION_GAP_EXAM_PATTERNS,
TREATMENT_REFUSAL_SUBTYPE_PATTERNS,
RESTORATION_INELIGIBLE_DX_NAMES,
......@@ -130,15 +131,14 @@ export function buildGapCore(input: GapCoreInput): GapCorePieces {
const afterDxFragRtx = afterDxFor('rtx');
const noRestorMsgRe = NO_RESTORATION_GAP_EXAM_PATTERNS.join('|');
const refusalRe = TREATMENT_REFUSAL_SUBTYPE_PATTERNS.join('|');
const externalTreatRe = EXTERNAL_TREATMENT_VISIT_PATTERNS.join('|');
/// 外院已治疗(回访记录)患者级排除:命中"外院"+治疗词 且 回访日 ≥ 本次诊断 → 排除。
/// 患者级(不看牙位/类目);时间方向同治疗排除(新诊断更晚 → 不排)。只读 patient_return_visits,
/// 外院已治疗(回访记录 result)患者级排除:POS 紧邻命中 ∧ 非 NEG 意图 ∧ 回访日 ≥ 本次诊断 → 排除。
/// 患者级(不看牙位/类目);时间方向同治疗排除(新诊断更晚 → 不排)。只读 patient_return_visits.result,
/// 不影响已治疗事实。一线反馈②(李姝妤 回访"已在外院矫正中")。
const externalTreatmentGate = Prisma.sql`AND NOT EXISTS (
SELECT 1 FROM patient_return_visits rv
WHERE rv.patient_id = p.id
AND (COALESCE(rv.result, '') || ' ' || COALESCE(rv.follow_content, '')) LIKE '%外院%'
AND (COALESCE(rv.result, '') || ' ' || COALESCE(rv.follow_content, '')) ~ ${Prisma.sql`${externalTreatRe}`}
AND rv.result ~ ${Prisma.sql`${EXTERNAL_TREATMENT_VISIT_POS_RE}`}
AND rv.result !~ ${Prisma.sql`${EXTERNAL_TREATMENT_VISIT_NEG_RE}`}
AND rv.task_date >= COALESCE(sig.occurred_at, sig.planned_for)::date
)`;
/// 拒绝记录时间方向:planned 记录 occurred_at 为空 → 用 COALESCE(occurred_at, planned_for)
......
......@@ -37,4 +37,4 @@
- 21 人本地基线 diff:三修复共修 6 例误召(①47、⑪26;27、④31;41、⑯36、⑤26 收缩、⑥36;46),其余理由零变动、无误杀。
- **修复 4(患者无意愿)**:treatment_record subtype 含"无意愿/不愿/拒绝"(余奕铭⑧:planned"正畸取资料,患者无意愿")→ 患者拒绝该 category,对**本次诊断**排除(类目级,靠时间方向;新诊断更晚→重新可召,非永久非时效)。词典 TREATMENT_REFUSAL_SUBTYPE_PATTERNS;gap 全口分支加 NOT EXISTS、按牙分支加 resolved 拒绝。全库 1225 患者命中。验证:余奕铭正畸/牙周消失,其余 6 正畸+1 牙周召回保留(零误杀)。
- **修复 5(宿主 ICD 错标纠偏)**:K00=牙发育/萌出障碍(含先天缺牙),但宿主把后天缺失的"牙齿缺少"也标 K00(全库 1044 例)→ 误召"萌出异常"(关平⑭ 牙25)。diagnosis parser 加 reconcileDiagnosisCode:code=K00 且 name 含缺(牙/失/少)且无"先天"→ K08;先天缺牙/萌出/多生牙等 K00 不动。需 reparse 存量。
- **修复 6(外院已治疗)**:回访记录(patient_return_visits 展示表)命中"外院"+治疗词(治疗/种植/矫正/修复/根管…)→ 患者级排除该诊断召回,回访日须 ≥ 诊断日(同治疗排除时间方向,新诊断更晚→重新可召)。算法只读回访表、不写已治疗事实。词典 EXTERNAL_TREATMENT_VISIT_PATTERNS;"外院"+治疗词共现排除"外院洁牙/检查"噪音。验证:李姝妤正畸消失(42→41,零误杀)。全库回访含外院 1812 患者。
- **修复 6(外院已治疗)**:回访记录(patient_return_visits 展示表)命中"外院"+治疗词(治疗/种植/矫正/修复/根管…)→ 患者级排除该诊断召回,回访日须 ≥ 诊断日(同治疗排除时间方向,新诊断更晚→重新可召)。算法只读回访表、不写已治疗事实。**只 match result 字段**(follow_content 是"种植潜客/洁牙"等营销标签,拼进来会误命中);POS=治疗词紧邻外院(外院治疗/在外院/已外院),NEG=排"建议/打算/考虑…外院"(意图未去)。验证:李姝妤正畸消失(42→41,零误杀);全库 POS∧¬NEG 命中 851 患者。
......@@ -284,18 +284,15 @@ export const RESTORATION_INELIGIBLE_DX_NAMES = ['废用牙', '无功能牙'] as
/// 拥挤语境(全库 844 段「间隙不足」仅 246 段共现缺牙,均为真·缺牙无空间)。
/// 回访记录里"外院已治疗"信号(李姝妤②:回访结果"已在外院矫正中")。
/// 患者去外院做了治疗 → 患者级排除该诊断召回(回访日须晚于诊断,同治疗排除的时间方向;
/// 新诊断更晚 → 重新可召)。需"外院"+治疗词共现,排除"外院洁牙/外院检查"等低值噪音。
/// 信号在 patient_return_visits(展示表),算法只读不写,不影响已治疗事实。
export const EXTERNAL_TREATMENT_VISIT_PATTERNS = [
'治疗',
'种植',
'矫正',
'矫治',
'修复',
'根管',
'已治',
'做了',
] as const;
/// 新诊断更晚 → 重新可召)。信号在 patient_return_visits.result(展示表),算法只读不写,
/// 不影响已治疗事实。**只 match result 字段**(follow_content 是营销标签/任务主题如
/// "种植潜客/洁牙",拼进来会误命中)。
///
/// POS:治疗词【紧邻】外院(外院治疗/外院种植/在外院/已外院)—— 表"已在/已去外院做了";
/// NEG:排除"建议/打算/考虑/可能/拟…外院"(意图未去,反而该召)。
/// 数据验证(2026-06 全库):POS∧¬NEG 命中 851 患者,被 NEG 剔除的全是"打算/考虑外院"假阳。
export const EXTERNAL_TREATMENT_VISIT_POS_RE = '外院(治疗|种植|矫正|矫治|修复|根管)|在外院|外院已|已外院';
export const EXTERNAL_TREATMENT_VISIT_NEG_RE = '(建议|打算|考虑|可能|拟)[^,;。]{0,6}外院';
/// 宿主 std_code 错标纠偏:K00=牙发育/萌出障碍(含先天缺牙),但宿主常把【后天缺失】的
/// "牙齿缺少/缺失/缺牙"也错标成 K00(全库 1044 例)→ 冒出"萌出异常"误召(关平 BJ0U007377 牙25:
......
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