-
fix(recall): 缺牙建议治疗按年龄排序 —— >70 岁活动义齿在前、种植并行 · 3ff9c827
现象(业务反馈):90 岁(吕学文)、78 岁(李石明)的缺牙召回,界面一律显示 「目标 · 种植」,话术也推种植。业务反弹"为什么给 90 岁老人推种植"。 根因:UI 取 signals.expectedCategories[0],而 K08 的 categories 首项恒为 implant。 整条链路(目标标签 / 理由文案 / goal / 话术)都没有年龄维度 —— 召回场景 SQL 与 priority-scorer 里一个年龄条件都没有。 ## 修法:改在诊断→治疗的源头,不在流程末端打特例 canonical-codes.ts 新增 recommendedCategoriesForAge(categories, age) 作建议侧单一源: 候选同时含 implant + prosthodontic 时,age > DENTURE_FIRST_AGE(70)→ prosthodontic 提前。 scenario / 前端 reason-line / 话术 prompt 全部调这一个 resolver,不各写年龄分支。 ## 业务方口径(对齐后修正) 初版做成了"高龄禁推种植",过重。业务反馈:**70-80 不是种植禁忌**,能否种植取决于 骨量骨质 / 全身状况 / 患者意愿,由医生评估。故改为: - 建议**只调顺序**:活动义齿在前,**种植并行保留**(不删) - 话术从"严禁推荐种植"改为"先讲活动义齿,种植可并行提及;不主推手术、 不承诺能不能种 —— 落到来院让医生按身体条件评估" - PAC 不替医生下禁忌结论 ## 三条设计红线(各有用例锁住) 1. 只排序不增删 —— 任何年龄下返回集合恒等于入参(种植不会被抹掉) 2. 不碰排除闸 —— DiagnosisTreatmentMap[].categories 仍是完整候选集 (否则高龄患者做过种植反而排除不掉 → 重复召回) 3. 不碰"要不要召回" —— 缺牙影响咀嚼营养,高龄同样该管 ## 改动 - canonical-codes:DENTURE_FIRST_AGE=70 + recommendedCategoriesForAge + treatmentCategoryNameZhFor - reason-signals:signals 加 focusCategory / patientAge(均 optional,旧 plan 回落原行为) - scenario:SQL 取年龄 → 走 resolver;高龄 goal 文案(义齿为主、种植并行) - 前端:目标标签用 focusCategory;理由行调同一 resolver 显示「活动义齿 / 种植」 - 话术:fact-block + stable prompt 加高龄沟通约束;三档 promptVersion bump 实测(本地 75 岁真实患者重算):focusCategory=prosthodontic · patientAge=75 · 理由「…未启动活动义齿 / 种植」。308 tests passed,service + web typecheck 干净。⚠ ️ 存量:plan 变化判定只比 (scenario, subKey),signals 变化不升版本 → 已有 plan 不会自动拿到新字段(前端回落原行为)。生产 775 个 80+ 缺牙患者 需回填或强制重算才生效,另行处理。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>luoqi committed