Commit 0089fe31 by luoqi

fix(摄入): 「调合/调颌」挪到含词表末尾 —— 排在 periodontic 之前会抢别人的记录

0366b572 加这条规则时只挡了 restorative(补牙散文含「调合」),放在了 periodontic
之前 —— 漏掉了牙周/预防/外科。「调合/调颌」是咬合微调,几乎任何术式的收尾都可能
带一句,它**单独出现**时才代表修复动作;和别的操作词同句时,那个操作词才是本次治疗。

2026-08-28 测试服 reparse 实测:新写入的 179 条调合/调颌事实里 18 条(10%)判错
  「牙周刮治+调合」「根面平整+调合+牙周内上药」「洁治,47调合」→ 应 periodontic(16)
  「涂氟,45调合」→ 应 preventive(1);拔牙类 → 应 surgical(1)

两个方向都坏:
  ① 牙周治疗不再解 perio_no_srp 缺口 = 多召牙周;
  ② prosthodontic 在结构 resolver 里,反而去解那些牙位的缺牙缺口 = 少召缺牙(不报错)。

修法:挪到本表倒数第二行(只在人群词 pediatric 之前)。原始个案照样接得住 ——
「调合,抛光」「调合抛光」里的「抛光」不在任何含词表,只有「调合」命中,仍判
prosthodontic(陈惠英@16 / 陶美玉@22)。

tests/keyword-case-and-terms.spec.ts 锁住两侧:实测误判串必须归回原类目,
原始个案必须仍是 prosthodontic。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
parent 76bbc63e
...@@ -47,15 +47,6 @@ keyword_mapping: ...@@ -47,15 +47,6 @@ keyword_mapping:
- { value: preventive, any: [窝沟封闭, 封闭剂, 点隙封闭] } - { value: preventive, any: [窝沟封闭, 封闭剂, 点隙封闭] }
# 材料弱词:放 preventive 后 —— "玻璃离子窝沟封闭" 已被上面 preventive 收;裸"树脂/玻璃离子"→ restorative # 材料弱词:放 preventive 后 —— "玻璃离子窝沟封闭" 已被上面 preventive 收;裸"树脂/玻璃离子"→ restorative
- { value: restorative, any: [树脂, 玻璃离子] } - { value: restorative, any: [树脂, 玻璃离子] }
# 调合/调颌(2026-08-28 陈惠英 TS0K028757 牙34;35;36;37):种植戴牙一年按约复查,当次治疗
# 写「调合,抛光」,牙位与缺牙诊断完全一致。宿主精确表早已判定「调合」「调颌」= prosthodontic
# (treatment_actual.yaml),但只在精确表里 —— 医生把两个词写在一起,精确匹配不上、含词表也没有,
# 整条丢弃 → 那次复查在系统里没有任何治疗 → 判「缺失牙未启动修复」误召。DW 实测 238 条。
# ⛔ **必须排在 restorative 之后**:「去腐净,Z250充填,调合抛光」这类补牙散文含「调合」,
# 放到上面的 prosthodontic 行会把上千条充填记录改判成修复(两者都在结构 resolver 里,
# 召回判定不变,但治疗史和标签会错)。放这里让「充填/树脂」先赢。
# ⛔ 「调磨」不收 —— 见文末 ⛔ 块(姑息调整,不代表问题已解决);调合=咬合调整,是宿主已判定的修复动作。
- { value: prosthodontic, any: [调合, 调颌] }
# 牙周去裸"洁牙"(避开自由文本"清洁牙面"误命中);洁牙/全口洁牙等精确词由上方 enum_mapping 兜 # 牙周去裸"洁牙"(避开自由文本"清洁牙面"误命中);洁牙/全口洁牙等精确词由上方 enum_mapping 兜
# SRP = scaling & root planing(龈下刮治+根面平整)的国际通用缩写,正是 perio_no_srp 子场景 # SRP = scaling & root planing(龈下刮治+根面平整)的国际通用缩写,正是 perio_no_srp 子场景
# 要认的那个治疗。DW 实测 SRP 648 + 局部SRP 40 + SRP+冲洗上药 76,此前全部落 _default 被丢 —— # 要认的那个治疗。DW 实测 SRP 648 + 局部SRP 40 + SRP+冲洗上药 76,此前全部落 _default 被丢 ——
...@@ -76,6 +67,23 @@ keyword_mapping: ...@@ -76,6 +67,23 @@ keyword_mapping:
# 「拆除缝线」699 条(665 带牙位)漏了 —— 同一临床动作。收「缝线」一并覆盖变体。 # 「拆除缝线」699 条(665 带牙位)漏了 —— 同一临床动作。收「缝线」一并覆盖变体。
# 碰撞已验:「拆除」不含「拔除/切除」,不会被本行前面的词误命中。 # 碰撞已验:「拆除」不含「拔除/切除」,不会被本行前面的词误命中。
- { value: surgical, any: [拔除, 拔牙, 切开, 翻瓣, 切除, 系带, 脓肿, 囊肿, 植骨, 缝线] } - { value: surgical, any: [拔除, 拔牙, 切开, 翻瓣, 切除, 系带, 脓肿, 囊肿, 植骨, 缝线] }
# 调合/调颌(2026-08-28 陈惠英 TS0K028757 牙34;35;36;37):种植戴牙一年按约复查,当次治疗
# 写「调合,抛光」,牙位与缺牙诊断完全一致。宿主精确表早已判定「调合」「调颌」= prosthodontic
# (treatment_actual.yaml),但只在精确表里 —— 医生把两个词写在一起,精确匹配不上、含词表也没有,
# 整条丢弃 → 那次复查在系统里没有任何治疗 → 判「缺失牙未启动修复」误召。DW 实测 238 条。
#
# ⛔ **必须排在所有其他治疗类目之后**(本表倒数第二行,只在人群词 pediatric 之前)。
# 「调合/调颌」是**咬合微调**,几乎任何术式的收尾都可能带一句,它单独出现时才代表修复动作;
# 和别的操作词同句时,那个操作词才是本次治疗。放前面就会把别人的记录整片抢过来:
# 2026-08-28 测试服实测(初版只挡了 restorative,排在 periodontic 之前)——
# 新写入的 179 条调合/调颌事实里 18 条(10%)判错:
# 「牙周刮治+调合」「根面平整+调合+牙周内上药」「洁治,47调合」→ 应 periodontic(16 条)
# 「涂氟,45调合」→ 应 preventive(1 条);拔牙类 → 应 surgical(1 条)
# 两个方向都坏:①牙周治疗不再解 perio_no_srp 缺口 = 多召牙周;
# ②prosthodontic 在结构 resolver 里,反而去解那些牙位的缺牙缺口 = 少召缺牙(不报错)。
# 排在末尾后仍能接住原始个案:「调合,抛光」「调合抛光」里的「抛光」不在任何含词表,
# 只有「调合」命中 → 照样 prosthodontic(陈惠英@16 / 陶美玉@22 已实测)。
- { value: prosthodontic, any: [调合, 调颌] }
- { value: pediatric, any: [乳牙, 儿童, 年轻恒牙] } - { value: pediatric, any: [乳牙, 儿童, 年轻恒牙] }
# ⛔ 不收进本表(冲洗 / 换药 / 上药 / 调磨 / 试戴)—— 但**不再丢弃**: # ⛔ 不收进本表(冲洗 / 换药 / 上药 / 调磨 / 试戴)—— 但**不再丢弃**:
......
...@@ -197,6 +197,30 @@ describe('调合 / 调颌 → prosthodontic(2026-08-28 陈惠英 TS0K028757)', ( ...@@ -197,6 +197,30 @@ describe('调合 / 调颌 → prosthodontic(2026-08-28 陈惠英 TS0K028757)', (
expect(cat('正畸调合')).toBe('orthodontic'); expect(cat('正畸调合')).toBe('orthodontic');
}); });
// 🔴 2026-08-28 测试服 reparse 实测到的回归 —— 初版只挡了 restorative,规则排在 periodontic
// 之前,新写的 179 条调合/调颌事实里 18 条(10%)被抢:牙周 16 / 预防 1 / 外科 1。
// 两个方向都坏:①牙周治疗不再解 perio_no_srp 缺口 = 多召牙周;
// ②prosthodontic 在结构 resolver 里,反而去解那些牙位的缺牙缺口 = 少召缺牙(不报错)。
// 修法:把该规则挪到本表倒数第二行(只在人群词 pediatric 之前)。
it('🔴 ⛔ 也必须排在 periodontic / preventive / surgical 之后 —— 别人的记录不能被抢', () => {
// 下面全是测试服实测被错判成 prosthodontic 的真实串
expect(cat('牙周刮治+调合')).toBe('periodontic');
expect(cat('根面平整+调合+牙周内上药')).toBe('periodontic');
expect(cat('洁治,47调合')).toBe('periodontic');
expect(cat('牙周刮治+调合,酌情牙周手术')).toBe('periodontic');
expect(cat('复查,洁牙,调颌')).toBe('periodontic');
expect(cat('涂氟,45调合')).toBe('preventive');
});
it('⭐ 挪到末尾后,原始个案照样接得住(「抛光」不在任何含词表,只有「调合」命中)', () => {
// 陈惠英@16 / 陶美玉@22 —— 这两条是加这条规则的初衷,不能因为挪位置而失效
expect(cat('调合,抛光')).toBe('prosthodontic');
expect(cat('调合抛光')).toBe('prosthodontic');
expect(cat('局部调颌')).toBe('prosthodontic');
expect(cat('切端调合')).toBe('prosthodontic');
expect(cat('基托缓冲')).toBe('prosthodontic'); // 义齿维护族,走上面那行
});
it('⛔ 「调磨」仍然不收(姑息调整,见词表文末 ⛔ 块)', () => { it('⛔ 「调磨」仍然不收(姑息调整,见词表文末 ⛔ 块)', () => {
expect(cat('调磨')).toBeUndefined(); expect(cat('调磨')).toBeUndefined();
}); });
......
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