Commit 3f979faa by luoqi

Revert "fix(recall): 复述诊断不重新拉弓 — 排除谓词放宽黄金窗回看 + 一线反馈核验文档"

This reverts commit cb5e4bc1.
parent 98b4e409
......@@ -110,17 +110,9 @@ export function buildGapCore(input: GapCoreInput): GapCorePieces {
AND dd.type IN ('diagnosis_record', 'recommendation_record')
AND dd.content->>'code' = ANY(${allCodes}::text[])
)`;
// ⭐ 复述诊断不重新拉弓(2026-06-11 一线反馈① 李然 BA38586 牙47):
// 1/25 种植(actual/implant/47)→ 2/7 拆线复诊,EMR 惯性把"牙齿缺少 47"再写一遍(复述,
// 非新发现)→ 最新诊断晚于治疗 13 天 → 时间方向判"未启动" → 误召(92 分)。
// 修:治疗只要落在「诊断 − 黄金窗(rule.windowDays)」之后,视为同一治疗 episode,
// 复述不 re-arm;真复发(末次治疗距再诊断超黄金窗,如修复体多年后失败)仍正常召回。
// 已知取舍:治疗后黄金窗内的"真二次新发"会被压到下一次诊断才召 — 临床上该场景
// 通常当场处理,误召打扰的代价更高。
const episodeLookback = Prisma.sql`make_interval(days => ${rule.windowDays})`;
const afterDxFrag = rule.excludeIfEverTreated
? Prisma.sql`AND tx.occurred_at >= ${latestDxOfCode} - ${episodeLookback}`
: Prisma.sql`AND tx.occurred_at >= COALESCE(sig.occurred_at, sig.planned_for) - ${episodeLookback}`;
? Prisma.sql`AND tx.occurred_at >= ${latestDxOfCode}`
: Prisma.sql`AND tx.occurred_at >= COALESCE(sig.occurred_at, sig.planned_for)`;
const sigToothExpr = rule.wholeMouth
? Prisma.sql`NULL::text`
......@@ -128,8 +120,8 @@ export function buildGapCore(input: GapCoreInput): GapCorePieces {
const wholeMouthFlag = rule.wholeMouth ? Prisma.sql`TRUE` : Prisma.sql`FALSE`;
const afterDxFragRtx = rule.excludeIfEverTreated
? Prisma.sql`AND rtx.occurred_at >= ${latestDxOfCode} - ${episodeLookback}`
: Prisma.sql`AND rtx.occurred_at >= COALESCE(sig.occurred_at, sig.planned_for) - ${episodeLookback}`;
? Prisma.sql`AND rtx.occurred_at >= ${latestDxOfCode}`
: Prisma.sql`AND rtx.occurred_at >= COALESCE(sig.occurred_at, sig.planned_for)`;
// §E (d) 正畸减数位(仅 missing_tooth):该牙有外科拔除 + 患者有正畸语境 → 折进 resolved 减掉。
const orthoExtractBranch = cfgFlags.excludeOrthoExtractionSites
......
# 一线反馈核验记录(2026-06-11 批次,21 例)
> 背景:试点客服(user 576)认领 21 个召回任务后逐一外呼/核档,手写反馈异议。
> 本文档逐条核验:一线说的对不对 → 系统为什么这么判 → 根因定性 → 修复与验证。
> 病历号/姓名已与库内真值比对(21/21 确认,见当日会话记录)。
## 核验方法
1. 拉该患者 assigned plan 的 `plan_reasons`(scenario/牙位/天数/evidence factIds);
2. 拉证据 fact + 该患者相关牙位/类目的全部当前版 facts,还原时间线;
3. 与一线反馈对照,定性:误召(算法/数据问题)or 正确召回(一线信息差)or 数据源问题;
4. 误召 → 本地修复 + 新旧谓词对照验证 + 记录于此。
## 状态总览
| # | 病历号 | 姓名 | 反馈要点 | 核验结论 | 状态 |
|---|---|---|---|---|---|
| ① | BA38586 | 李然 | 47 已种植+拆线,不该召 | **误召 — 复述诊断 re-arm** | ✅ 已修复(见下) |
| ② | BJ0U005102 | 李姝妤 | 外院矫正,4.21 引(转)院 | 待核验 | ⬜ |
| ③ | BJ0A057103 | 秦溢泽 | 2026.1.27 取资料未回复 | 待核验 | ⬜ |
| ④ | BJ0U016979 | 祁小夏 | 36/41 缺,11.22 修复 | 待核验 | ⬜ |
| ⑤ | BJ0U017412 | 王敏 | 26.37.47;26 无间隙 | 待核验 | ⬜ |
| ⑥ | BJ0U017401 | 李强 | 46.36 间隙不足→建议正畸? | 待核验 | ⬜ |
| ⑦ | BJ0U015883 | 黄琳 | ✓(认可) | 待核验 | ⬜ |
| ⑧ | BJ0F022277 | 余奕铭 | "穿"→外院;"病历"→无意愿 | 待核验 | ⬜ |
| ⑨ | BJ0U016929 | 刘强 | ✓(认可) | 待核验 | ⬜ |
| ⑩ | BJ0U017487 | 李石明 | 37.47 缺失,活动义齿 25.12.23 | 待核验 | ⬜ |
| ⑪ | BJ0U017563 | 韩俊和 | 26.27;2.3 已种 2.12 戴牙/拆线 | 待核验 | ⬜ |
| ⑫ | BJ0U017233 | 刘哲昕 | ✓ 正畸 | 待核验 | ⬜ |
| ⑬ | BJ0U016815 | 王晨 | ✓ 动态,回访过,未停,2次 | 待核验 | ⬜ |
| ⑭ | BJ0U007377 | 关平 | 25 分(磨)牙萌出 ✗;2020.9.18 增平;外院矫正→完成后全面修复 | 待核验 | ⬜ |
| ⑮ | BJ0U017637 | 李鹏 | ✓ 15.27.47 缺失 | 待核验 | ⬜ |
| ⑯ | BJ0U016360 | 高美玲 | ✗ 36 缺失;EMR 固定桥修复,误:已修复 | 待核验 | ⬜ |
| ⑰ | BJ0U017344 | 陈秀玲 | ✗ 27;1.20 修复,活动义齿 | 待核验 | ⬜ |
| ⑱ | BJ0U017423 | 陈葳 | ✓ 46 缺失 | 待核验 | ⬜ |
| ⑲ | BJ0U017440 | 王延春 | ✓ 24.25 缺失 | 待核验 | ⬜ |
| ⑳ | BJ0E012466 | 宗明 | ✗ 15.25/36.44;正畸关闭了;①病历信息正确 ②无片子 | 待核验 | ⬜ |
| ㉑ | BJ0U010770 | 王颖 | ✓ 47;空间不足? | 待核验 | ⬜ |
---
## ① 李然 BA38586 — 47 缺失牙召回异议 ✅ 已修复
**一线反馈**:47 牙 2026.1.25 已种植、2.7 已拆线(治疗已启动),系统不该召回。
**库内时间线(47 牙)**:
```
2024-04-20 47 拔除(surgical actual)+ 种植 planned
2024-08-11 诊断「缺失 47」(K08)+ 种植 planned(患者爽约/改期,链中断)
2026-01-25 ✅ 简单种植术 actual · category=implant · 牙位47 · treat_stages=[implant_placement]
+ 同日 planned「种植冠修复 47」+ CBCT
2026-02-07 拆线(category=review,牙位47)
⚠️ 同日 EMR 把「牙齿缺少 47」(K08)作为就诊诊断惯性复述 ← 问题源头
2026-06-08 计划生成:「缺失牙未启动修复·牙位47 — 诊断 120 天前(=02-07),
未启动种植/修复/冠桥」priority 92 → 入池 → 被认领
```
**定性:误召**。种植事实**已正确入库**,数据无缺;错在排除规则的时间方向判断:
- 排除闸要求「同牙位同类治疗 ≥ 信号诊断日」(§D 设计,防"修复体多年后失败复发"漏召);
- 拆线复诊的 EMR 复述诊断(02-07)把"最新诊断"推到了种植(01-25)**之后** 13 天;
- 拆线本身 category=review,刻意不算治疗(事实保真) → 47 被判"未启动" → 误召。
**根因模式**:**EMR 复述诊断 re-arm** — 复诊/拆线/复查时医生把历史诊断作为本次就诊
诊断再录一遍(录入惯性,非新发现),在时间方向规则下"复活"了已启动治疗的 gap。
该模式必然普发(任何术后复诊都可能复述),非个例。
**修复**(`potential-treatment-gap.sql.ts`,commit 见 git):
排除谓词从 `治疗 ≥ 诊断日` 放宽为 `治疗 ≥ 诊断日 − 黄金窗(rule.windowDays)`:
- 复述(治疗后黄金窗内再录同码诊断,K08=180 天)→ 同一治疗 episode,不 re-arm ✅
- 真复发(末次治疗距再诊断超黄金窗,如修复体 3 年后失败再诊断)→ 照常召回 ✅
- 两个消费方(召回 + 潜在治疗画像)共用 gap 核心,口径同步修正;
- 已知取舍:治疗后黄金窗内的"真二次新发"延后到下一次诊断才召 — 该场景临床通常
当场处理,误召打扰的代价更高。
**验证**:
- 服务器只读对照(李然 47,sig=02-07 诊断):新谓词 resolved=**t**,旧谓词=**f**
- 本地全量 plan 重算:SQL 无错误(运行记录见会话)✅
- 部署后:全量 recompute-plans,预期此类"术后复述"误召批量消失;对比报告待出。
---
## ②-㉑ 待逐条核验
(按 ① 的格式逐条补充)
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