- 07 Jun, 2026 6 commits
-
-
gender extractor:patient.gender 映射 M/男→男性、F/女→女性、其他→未知(照图,三值)。 注册表 spec + enum/label;来源可切(现 patient.gender,宿主给 client_gender 后切)。 本地 928:女 468 / 男 460,画像现役 5 特征(rfm/age_bracket/gender/dnc/entitlement)。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
luoqi committed -
- age_bracket extractor:从 patient.birthDate 算周岁 → 9 档(婴幼儿..老年),照图区间; 3/55 重叠按'下界含、归下一档'+ ≥55→老年消歧。snapshot 时间语义(历史读版本流)。 - 注册表 spec(标签卡)+ enum/label;数据来源可切(现 birthDate 自算,宿主给 client_age 后切)。 - birthDate 缺失/年龄越界(<0/>120 脏数据)→ 不打标签。 - 本地 928 验证:分布合理、边界消歧正确、覆盖率 100%。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
luoqi committed -
- treatment-initiation-recall.fetchPersonaContext:改读 rfm.data(valueTier/riskScore), rfm 缺失优雅回退旧字段。本地 1437/1437 plan 打分零变化 → 翻转行为等价。 - FeatureRegistry/persona.module:摘除 value/recall_risk/treatment_chain_status 三个 extractor (treatment_chain 降级为详情页 episode 视图,后续单做);现役 rfm/dnc/entitlement。 - rfm 决策树补全:develop 档 F=2 扩 F<3(近期单次新客→一般发展,不误落低活跃)。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
luoqi committed -
- rfm.feature 改为业务整理好的 RFM 定义:R/F 分段照图、M 按租户分位(p20/40/60/80)、 8 段决策树(重要价值..低活跃)。R/F/M = last_visit_time/visit_times/net_receipts_total(lifetime)。 - M 分位需群体计算:PersonaService 算+缓存租户分位阈值(30min TTL),注入 ctx.populationStats; 缺失降级绝对¥档。valueTier(绝对¥)/riskScore 保留 → 仍 100% 兼容旧 value/recall_risk。 - 新增 persona-feature-specs.ts:标签注册表(标签值/数据来源/数据字段/释义/算法/时间语义), 代码存、来源可切(现 PAC 自算,宿主 CDP 报表给出后切宿主值)。score 列弃用语义。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
luoqi committed -
- 新增 rfm feature(融合 R最近/F频次/M金额三时间语义):data 带 segment 八象限 + lifecycle 生命周期 + valueTier(0-4)/riskScore(0-3)。统一旧 value+recall_risk。 - additive 接入(暂不动 scorer/旧特征);本地 928 验证:分布临床合理,且 valueTier/riskScore 100% 复现旧 value.score/recall_risk.score → 后续翻转零风险。 - recompute-persona 加 --force:算法/特征变更后(数据没变)跳过水位幂等闸强制重算 (部署到服务器也需要,否则全 noop)。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
luoqi committed -
画像从'被动打分+话术标签'升级为有治理、有时间语义、可圈人群的特征体系: - 时间语义模型(snapshot/window/lifetime/trend,每特征声明;画像=压缩当前态,历史留fact层,版本流=point-in-time) - Feature Registry 单一收口(OneModel)+ CI 防漂移 - persona_features 加 typed value JSONB(支持 SQL 圈人群) - RFM 八象限(统一现有 value+risk:M→value,R+F→lifecycle/risk)+ 召回语义映射 - lifecycle_stage 生命周期分层;treatment_chain 移出画像→episode 视图 - Campaign 圈人群→批量召回;质量监控;分 5 PR 实施 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
luoqi committed
-
- 06 Jun, 2026 12 commits
-
-
- parseScriptMarkdownToSections 改通用 H2 解析:原只认稳健 4 固定标题(开场白/...), 深度/标准的自由标题反 parse 全落空 → plan_scripts 存了内容但刷新显示'尚未生成'。 现按任意 ## 标题切段(稳健固定标题映射已知 id,标准/深度自由标题用 s{n}+原标题),三档通用。 - KeyFactsCard 主治医生:影像AI(image_ai 触发诊断)不当主治医生显示,退回真实最高频医生 (排除影像AI/image_ai),真无人类医生 → '—'。话术侧 extractPrimaryDoctor 本就排除,一致。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>luoqi committed -
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
luoqi committed -
§E 三条剔除(已落地 scenario)之前会被扫描器虚报成 truly_unexplained;补 x_thirdmolar/ x_congenital/x_orthoextract 三 flag,FN 按首个命中归桶,truly_unexplained 才准。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
luoqi committed -
仅 missing_tooth 子场景加 3 条剔除: - excludeThirdMolar:智齿位 18/28/38/48 不召种植 - excludeOrthoExtractionSites:该牙有外科拔除 + 患者正畸语境(K07/正畸治疗)= 正畸减数位, 缝隙靠矫治关闭,不种植(折进 resolvedTeeth 按牙减,忽略时间方向:拔在 K08 诊断前也算) - excludeCongenitalName:name 含'先天'(先天缺失等)→ 正畸统筹开/关隙,不自动召修复 本地验证:智齿位 active 召回 2→0,3573063 '38;46'→'46'(精准保留真磨牙),无过度抑制(FP 仍1)。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
luoqi committed -
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
luoqi committed -
- treatment-initiation-recall:excludeIfEverTreated(K05牙周/K07正畸)从"曾做过即永久排除" 改为"治疗须晚于该病【最新诊断】才算已处理"。最新诊断在末次治疗之后(复发未治)→ 重新召回; 维护中患者(末次治疗≥最新诊断)继续排除,活跃患者仍由 cooldown/⑤b/⑤d/⑤f 兜住。 仅改两段时间方向 fragment + 加 latestDxOfCode 子查询。 本地 1000 患者验证:复发漏召 27→6(残留全是 cooldown内/已指派锁/⑤d 合法不召),牙位级 FP 无回归。 - 新增 sql/verify-recall.sql:只读召回正确性扫描器(FP 硬闸 + 牙位交叉表 + FN 逐层解释 + 全口复发 + K08正畸语境),每次摄入/改算法后跑做回归。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
luoqi committed -
- 数据:data/jvs-dw/users.json — 116 位在岗客服(回访表口径·近12月), 结构 = 未来 users/user_clinics 两表形状(externalId/name/tenant/roles/clinics) - 后端:mock-users.ts 加载器(cwd 解析+缓存);mockLogin 支持 userExternalId (选具体客服→sub=externalId/真实姓名/该客服诊所);新增 GET /auth/mock-users - 前端:快速登录改为「角色(权限)+ 选客服」合并式;名册拉不到时降级回通用网格 - 前端:列表页诊所筛选选项改用 user.clinicIds(RBAC 可见范围),名取 dictionary (原误用全 tenant 名表,与后端 scope.clinicIds 过滤对齐) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
luoqi committed -
- RegenBtn:[档位▾][模型▾][重新生成] —— 两下拉只选不触发,重新生成移右为唯一触发口。 - 原文视图:默认展开语义(只记主动折叠)→ 流式时新段(s0/s1…)也展开,不再折叠。 - loading 骨架分档:稳健 4 段固定标题 / 标准 4 段无标题 / 深度 1 段(段数不定)。 - AIStamp 精简(去图标+label,只留相对时间)。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
luoqi committed -
标准档:4 固定角色字段 → 自由 sections[](固定4段,复用 DeepDraft + 段渲染 + 段数组安全规则);format.md 去 tier 污染纯指令;流式(段数组 partial 边渲染)。 深度档:富输入 base++ — 历史联系(patient_return_visits 最近5条)+ persona 价值/流失风险, 经 buildDeepExtensions 进 plan/write/verify;plan 放开结构(去固定段式、允许其他牙开段); verify 加 quality 质量评分(1-5,非 gate,回填 judgeScore/judgeRubric 供 eval);format 去污染。 治疗计划:ScriptMedicalRecord.plannedTreatments(treatment_record planned)— 原只读常空的 emr.treatment_plan 导致话术缺治疗计划;stable/standard 渲染;standard 病历补全到全 SOAP。 tone 收拢:shared/tone.ts 单一源(枚举/describe/label);选择规则只留人群 SKILL(system), user prompt 只给信号(熟络度),模型判断。占位:去模板档去 {} 替换占位,只留【时间段】人工填。 资深审查修复: - P0 SSE 客户端断连无清理 → AbortController 串到底(controller→orchestrator→runner→ generateObject/streamObject abortSignal):断连即取消在途 LLM(深度3-4步不再白烧), abort 不兜底/不写 PlanScript。实测:深度 6s 掐断仅 +1 条 aborted、PlanScript 未脏。 - P1 深度质量分回填到最终 invocation(原挂被丢弃的草稿);深度非流式 cacheHit 真实累计 (原硬编码 false);extractPrimaryDoctor 注释更正;skill-registry 陈旧 env 名更正。 两端 tsc 通过;三档 dry-run + 流式 + 中断 均验证。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>luoqi committed -
workspace.json 等每次开 Obsidian 都变动,反复污染 git status。 untrack 整个 docs/.obsidian/(本地文件保留)。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
luoqi committed -
NEXT_PUBLIC_API_BASE_URL 是构建期 inline。若 docker compose build 漏带 --env-file apps/pac-web/.env,`${NEXT_PUBLIC_API_BASE_URL}` 插值成空串; env.ts 原用 `??` 只挡 undefined 挡不住空串 → `new URL(path,'')` 抛 "Failed to construct 'URL': Invalid base URL",登录页直接报错。 改:空/缺失时浏览器端退到同源(prod 反代下 API 与前端同域,天然正确), SSR 退本地默认。即便构建注入失配,生产也不再硬崩。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>luoqi committed -
system/user 提示词系统性打磨 + 单一源收口(三档共用): - PII 收口:称呼派生(callSalutation/pickGuardian/nameSpokenForm)从 orchestrator 归到 shared/pii.ts(与 deidentifyDoctor 同处,人名/称呼单一源);script-facts.ts 退化为纯确定性渲染(smartDateDisplay + fdiToFriendly/toothFriendly),删死函数 resolveSalutation/resolveAgeBranch/resolveAgeGroup。 - common.md:角色=要点提纲非照念;铁律收口(接地不编 first / 突出本次应治未治项 / 医生名义 / 钱与方案软化"可点名不报价落点复查" / ≤18 禁拍片 / 主动约 / 口语短句), 去反向示例词。 - population adult/child SKILL.md:瘦身去重,语气改"熟络度"(recency 为主+次数为辅, 交 LLM 判断,去掉"新老客"二分退化标签)。 - fact-block(标准/深度共用):开场锚定最近一次就诊(非诊断日);熟络度 relationSignal; recentTreatments 结构化"用自己的话自然带";renderMedicalRecord。 - fdiToFriendly 补乳牙象限+字母记法(1A-4E),修儿童龋齿"1D/1E"原样泄漏给患者。 - 开场 bug 修:从 triggerDate(诊断日,可能更早)改为最近一次就诊;"检查后"→"来过之后"。 - stable tier:prompt/schema/phrasing/stable.call/format.md 配套(目标 + 牙位占位 + 医嘱/建议/治疗计划 + ≤18 belt;预约不成功措辞软化);儿童模板第二部分改病种无关。 - deep tier calls / standard.call:版本对齐。 本地 tsc + build 通过;CLI dry-run 多档重生验证称呼/开场/牙位/熟络度均正确。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
luoqi committed
-
- 05 Jun, 2026 9 commits
-
-
- RegenBtn 加投入档下拉(与模型下拉并列):稳健/标准/深度,选档即用该档重新生成 - tier 走 /script:stream ?tier= query;ServerSection.id → string 支持深度档多段不定渲染 - 详情页暂隐藏实时教练入口(功能未上线;import + 挂载注释) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
luoqi committed -
目录重组:shared/(脊柱周边 + 病种名/安全单一源 + 厚事实块)+ tiers/{stable,standard,deep}/。 脊柱(AiCallRunner)恒定,策略可插(每档一套 prompt/schema/format,深度为 3 步 pipeline)。 - input_snapshot 全字段结构化:reasons[].toothPositions(FDI)/medicalRecord(SOAP 全字段,per-reason); recentTreatments/pendingTreatments/lastVisit 对象化;personaHighlights/guardian 补原始 key; 聚焦单一源 reasons[0](orchestrator 单一排序,prompt/fallback 不再各自 sort) - 标准档:去模板 4 段自由编排(标题由 LLM 起)+ 厚输入(病历/其他reason/近期治疗),病种只给名 - 深度档:3 步(规划→写多段→独立对抗校验)+ repair(≤1)+ 兜底;多段不定输出(ScriptSectionDto.id→string) - user prompt 补 {牙位}/本次目标(plan.goal)/医生医嘱·建议·治疗计划;≤18 禁拍片 belt - 儿童复查段修:对齐本次病种 + 用{复查时长},删写死"3个月常规涂氟检查" - 安全单一源 safety-rules.ts(禁词/承诺/加粗时间 + machineSafetyScan);composer tier-aware - runner generateObject 解析失败重试一次再兜底(flash 多段 JSON 偶发脆) - controller +tier query;实时教练后端上下文改读结构化字段 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>luoqi committed -
撤掉上一版的 {{}}/【】 token 方案(LLM 看不懂 + 跟 {xxx} 占位冲突),改成 **直接给"姓+敬称"的可用称呼**(去全名,非 token): - 称呼 徐女士 / 诊断医生 韩医生(deidentifyDoctor:韩维→韩,模板拼"韩医生")/ 客服 小王 → LLM 直接用、客服直接看;全名(徐雅静/韩维)不进 user prompt - 撤 pii.ts token/回填机制,orchestrator 去 detokenizeScript;base-system 去 token 占位声明 - 开场白顺序修正(打电话场景):先 称呼+确认对方 → 再 自报家门 → 医生交代 → 问近况 (原来自报家门在前,不符合电话礼仪) - call.ts fallback 医生同口径去名;promptVersion v13 - 验证:张震校 重生成 →「徐女士您好…我是…客服…韩医生特意交代…」顺序+去名正确 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>luoqi committed -
ScriptContext = 三档全集数据(tier-agnostic superset),各档后续组装 user prompt 各取所需; **不是审计快照**(关联走 agent_invocations.linked_patient_id 列)。 - nameMasked → salutation 正名(它是"通话称呼"非脱敏名);消费方 pii/call/header/realtime-coach 同步 - 加 name(真名)— 数据,补"患者名字都没有"的缺;但**不进 user prompt**(走 token 回填) - ID 类(externalId/id)不进(非审计,无需标识符) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
luoqi committed -
发给第三方 LLM 的 user_prompt 不再带真名;ScriptContext/input_snapshot(PAC 内部)不变。 - 新增 script-common/pii.ts:NAME_TOKEN(称呼/诊断医生/客服)+ realNames + detokenizeNames/Script · token 用「原样保留」约定 【】(同 【时间段1】),不能用 {{}}(会跟 {xxx}=要替换 占位冲突, 被 LLM 吐成单括号 → 露生 token) - prompt.ts:称呼/诊断医生/客服 emit token;监护人触达提示去全名(只留关系) - orchestrator:LLM 输出在渲染/写库前 detokenizeScript 回填真名(流式 partial + 终态都回填) - base-system.md:声明 【称呼】【诊断医生】【客服】 为系统回填占位,LLM 原样保留 - 验证:张震校 重生成 → prompt 无真名;输出"徐女士/韩维医生"正确回填;promptVersion v12 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>luoqi committed -
- 统一称呼单一源 callSalutation(年龄+性别+监护人):未成年→监护人("徐女士")/家长, 成人→先生/女士;header + 开场白 + fallback 共用,不再各算一遍 · 修 bug:头部 `患者:张先生`(nameSpokenForm 无儿童分支)→ 9岁现为"徐女士" - 监护人进 ScriptContext:orchestrator 查 patient_relations(妈妈>爸爸>祖辈,优先已建档) → guardian + 触达提示"打给家长、患者是孩子(称宝宝)",称呼真正打给监护人 - user prompt basics 去掉称呼(原"徐女士,男,9岁"矛盾)→ 只留性别+年龄 - {最后一次就诊医生} → {诊断医生}(prompt + base-system.md + 人群模板 + schema), 标签对齐实际喂的 triggerDoctor(触发诊断的医生) - promptVersion bump v11 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>luoqi committed -
- 新增 script-common/disease-knowledge.ts:病种知识的 tier-agnostic 单一访问源 · diseaseKnowledgeForSubKey(subKey):subKey → {label,risks,advantages,reviewDuration} · resolveDisease(reason):subKey 优先 + 文本兜底(prompt + fallback 共用唯一入口) · SUBKEY_MAP 显式声明每病种在两套字典的中文 key → 收掉"双跳 + exact/includes 混用"脆弱性 - 修 bug:jaw_cyst 的 keypoints 字典 key 是「囊肿」、duration 是「颌骨囊肿」, 原 exact 查表静默丢 risks/advantages → 现分列对齐,颌骨囊肿召回拿回风险/优势要点 - prompt.ts / call.ts(fallback)改用 resolveDisease,删散落的 missedFromReason+lookupKeyPoints+lookupReviewDuration 三连 - 为标准/深度档铺路:同一份病种知识,后续档直接 resolveDisease 拿规则自由组织 - promptVersion bump v10 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>luoqi committed -
召回口径(乳牙): - missing_tooth 排除乳牙(FDI 51-85 + 象限 1A-4E)→ 乳牙缺失不进种植/修复召回 - 乳牙龋齿目标只显「充填」(去嵌体);前后端 + reason 文本统一走 treatmentCategoryNameZhForTeeth(@pac/types 共享 helper) - recall-oracle 同步乳牙规则(独立内联,守对抗纪律) 摄入: - 影像诊断粒度对齐医生诊断:列内逐牙拆分 → 牙位 ; 拼接(一码一 fact) - 回访 treatment_items + treatment_items_two 合并为单字段「大类·子项」 (transforms 合并 + normalizeMergedItems 空值归 null) 详情页: - 监护人 TEST-ONLY:儿童/老人触达 fallback,手机号旁标注(身份 姓名), 去掉关键事实「联系人」行 - 主治医生改口径 A:触发诊断的医生(影像源→「影像AI」兜底) - 病历快读:影像 AI 诊断加「影像」角标 - 召回理由列表页 +N 加 hover 展示其余 reason(对齐详情页) AI 话术(稳健档铺路): - DraftPlanScriptInput → ScriptContext(tier-agnostic,留 alias) - 剔除治疗链字段(chain-composer 将废弃):treatmentChainSummary 删、 ongoingChains → recentTreatments(只读 treatment_record「做过什么」) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
luoqi committed -
- 删除 db-review / db-suggest-after-review / db-review-confirm(~3.5k 行 W1 评审 ping-pong,决议已并入 db-design-v2 §13 + schema.prisma,无独立价值) - 修 db-design-v2 / treatment_aftercare_recall 对已删稿的死链 - 新增 docs/algorithm/ai-script-generation.md:话术生成分档设计 (投入档=输入/输出/步数联动;脊柱=AiCallRunner、策略=AiCall; 知识 vs 模板分离;ScriptContext 聚焦切片不含治疗链;单一源收口清单) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
luoqi committed
-
- 04 Jun, 2026 4 commits
-
-
prod CH 23.8 拒绝「Multiple JOIN + ARRAY JOIN 同层」且不支持相关子查询。改成分层嵌套: s1(image⋈client⋈org,无 array join)→ s2(array join 读 s1)→ 外层。 cohort 注入(裸 IN)落到 po 子查询 GROUP BY 前 → po 按 batch scope + 外层 notEmpty(po.org) 过滤到 batch 患者(prod CH 实测等价正确)。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
luoqi committed -
prod ClickHouse 拒绝「Multiple JOIN + ARRAY JOIN 混用」+ org 子查询 GROUP BY 带偏 cohort 注入。 本地 CH 24.3 容忍故未暴露。暂注掉 image_finding_rows query + assembler 注册, 放行召回质量/联系人/回访 3 块;影像 AI 信号源作 follow-up(经 prod CH 重做 SQL)。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
luoqi committed -
召回质量(摄入层 yaml + 召回 scenario,host 无关引擎增强): - C.10 治疗痕迹覆盖扩(治疗后/术中/X后/粘结中 + 修复/备牙/取模/根尖/植骨/错颌 keyword) - treat_plan/dispose 定向合并(real_no_tooth 闸 path2:治疗无牙位→dispose 找回牙位) - 牙位归一:全角字母数字折叠(RCT→RCT)、裸象限数字过滤(笔误 16→1 幽灵召回清零) - keyword none 排除 + 切段含全角标点 + 若条件从句 strip - 治疗家族 resolver / 同牙取代 / oracle 对账(差分 0) 联系人(patient
↔ patient 自关联,替代 primaryContactType): - 新 PatientRelation 边表(referee → 关系人即 patient,姓名/电话现取零冗余) - 删 primaryContactType 全链路;详情页"联系人"行 影像 AI 信号源(image_analysis → diagnosis_record,code_source=image_ai): - 源 SQL pivot+炸牙位(病种→K码),独立 subject,去重靠召回 (subKey,tooth) 聚类 回访展示(独立表,5 试点): - 新 PatientReturnVisit 表(org∈5试点 + customer_id→patient),详情页"历史联系"滚动卡 裁决:referee/image/returnvisit 已接(天然试点 scope);complain/consult 全集团覆盖不全,不接。 本地 191/200/1000/2000 四样本对抗验证:幽灵召回 0、resolver 漏判 0。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>luoqi committed -
召回核心(scenario + canonical-codes): - 治疗家族 resolver(resolverCategoriesFor):11 张码白名单 → 结构家族一张表 + 牙周/正畸沿用。结构码(K00-04/08/09)= 任何局部结构治疗算已治(充填/根管/冠桥/ 种植/外科/美学/儿牙);刻意排除 牙周/正畸/预防/复查流程 → 不跨病误销。 修李梦维 1B 贴面误召;差分实测 18 例补判全合理、0 误销。 - ⑤c 拔除改 afterDx:拔除只终结诊断前/同时的病;诊断在拔除后=新信号(不压)。 - toothArrSql 乳牙归一:对齐 toothSet 只剥"空格+牙面字母",保留 Palmer 字母。 修旧实现把 1D/1E 塌成象限 1 的错标 + 整象限过度相减漏召(差分 26 患者)。 - expectedCats(窄,展示"未启动 X")与 resolverCats(宽,判已解决)拆开。 前端对账工具(差分验证): - recall-oracle.ts:召回算法独立第二实现(按单牙时序状态机),共享家族配置、 判定逻辑独立 → 与生产 SQL 差分比对,分歧即 bug 捕获点。 - tooth-timeline:顶部对账面板(✓一致/
⚠ 仅生产/⚠ 仅oracle)+ 每泳道召回徽标。 - 去掉治疗链判断(plan-detail-app reasonAltClosed 过滤)——治疗链弃用第一步, 召回显示统一收口到「召回算法 + 牙位事实」。 本地差分全量验证:605 一致 / 0 分歧。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>luoqi committed
-
- 03 Jun, 2026 9 commits
-
-
后端 · 召回 & 摄入口径 - diagnosis.yaml:深窝沟/脱矿/牙本质敏感/牙菌斑堆积/食物嵌塞 摘出疾病码(预防/风险/症状, 落 code=null 不召、病历照原文显示;菌斑性龈炎等真病灶保留) - 处置(EMR.dispose)→ actual 治疗:treat_plan 空时拆 dispose,message union 进 treatment_actual_rows, 复用现有 keyword_mapping 分类 + treatment.parser(不加 assembler/parser/置信度)。 filter `empty` 谓词升级:空壳 JSON 数组([{treatName:""}] 占位行)也算空 → 正确去 dispose 找治疗。 treatment_actual keyword 顺序修:窝沟封闭提到充填前、牙周去裸"洁牙"(避开"清洁牙面"误命中)。 - 召回按牙相减(修多牙诊断被部分治疗整体误抑制): scenario LATERAL 算 sig_teeth / resolved_teeth(⑤a同类∪⑤c拔除∪⑤e替代,按牙)/ remaining; 有牙位信号 → 剩余未治牙位非空才召、reason 牙位=剩余;全口信号沿用 category 级。 例 龚靖舜 浅龋@16;26;46;36 补了16 → 召 caries_no_filling@26;36;46(不再整簇误压)。 前端 - 关键事实卡加「牙位 →」抽屉:每颗牙 + 全口(牙周/正畸/其他)泳道,时间倒序、零推断展示。 - 事实时间轴 + 牙位抽屉:同一时刻按类型排序,随整体倒序(治疗→计划→建议→影像→诊断)。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>luoqi committed -
markAlternativeClosed 的 ALT_CATS 漏了 cosmetic — 同牙做了贴面(定性修复) 不算"已被替代",导致 K00 乳牙滞留链卡在 discovered: 李梦维 K00 1B;4C — 4C 粘结桥(prosthodontic 已覆盖)+ 1B 贴面(cosmetic 漏判) → 全牙位覆盖闸不通过 → 链一直"已发现",实际两颗都已修复。 加 cosmetic 后两颗全覆盖 → 链闭环(已被替代);画像缺口 2→1(只剩种植46,与召回一致)。 顺带 altSources 去重(同牙多条同类 actual 如"贴面修复+戴贴面"会重复)。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
luoqi committed -
旧版按 plannedFor 取最新 planned treatment 置顶,不管它是否已被后续治疗超越。 韩滨:拆线47(计划 2026-02-06)早于最新实际治疗(2026-03-16)→ 实为过期/已执行 的旧计划,却仍标"治疗计划"。改为:仅当计划日期 > 最近一次实际治疗日才显示。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
luoqi committed -
1) 召回反馈剥离(执行 → plan 自身) - schema: FollowupPlan 加 recall_feedback(up/down)+ recall_feedback_note(2 列); PlanExecution 删 recall_feedback。migration 20260603090000。 - 端点 POST /plans/:id/recall-feedback { feedback, note? } → 写 plan;/full 回显。 - 详情页标题栏(优先级右边)拇指:👍 直接记;👎 弹 shadcn Dialog, 预选项=快速输入到文本框(沿用 RECALL_FEEDBACK_OPTIONS)+ 自由补充。 - 执行表单移除原召回反馈多选块;执行链路 schema/service/types 去掉 recallFeedback。 2) 画像治疗链缺口数口径统一(韩滨 1→2) - treatment_chain_status 旧版类别级判定漏算被无关同类治疗掩盖的缺口; 改为复用 ChainComposerService,数 discovered 且非替代闭环的链 = 缺口, 与治疗链面板 / 召回理由逐条一致。PersonaModule 注入 ChainComposerService。 3) 病历快读 评估段 加医生诊断原文,且与"本次治疗"同结构:[标签] 原文(深色) · 牙位 (数据已在 diagnosis_record.content.name_zh,纯展示)。 4) 患者事实时间轴 加单牙位筛选(下拉,牙位归一去重),与类型筛选叠加。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>luoqi committed -
EMR.treat_plan = 本次治疗(actual,本次确实做了);EMR.plan = 治疗计划(planned)。 treatment_review_rows 100% 来自 treat_plan(plan 字段的复查项当前 drop), 但 treatment_review.yaml 原写死 action=treatment_planned → parser 推 kind=planned, 导致"拆线/复查/暂观"等本次做的事被错误落到「治疗计划」。 修复:treatment_review.yaml action → treatment_completed(kind=actual / status=fulfilled)。 - 韩滨 2024-04-07 拆线 18;48 现正确落「本次治疗」,与源数据 treat_plan 一致 - 验证无副作用:chain S4 复查信号按 category='review' 匹配(不看 kind); review 已排除在 actual 治疗链 S3 外、不触发 scenario ⑤a → 召回逻辑不受影响 - 留注释:未来若 union EMR.plan 的复查项进来(那才是 planned),需按来源分流 kind 至此 treatment_record 的 kind 完全由来源字段决定:treat_plan→actual / plan→planned。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
luoqi committed -
WhyCard 的替代闭环抑制原先只按牙位收集 altCoveredTeeth,把某条 alternativeClosedBy 链覆盖的牙位上【所有】召回理由都 drop。同一颗牙若 存在不同病程会互相误杀: 韩滨 11 号牙:2024 龋齿(K02)→修复 已闭环(altClosedBy), 误删了 2025 缺牙(K08)→种植 的召回理由(分 85,本应是主理由), WhyCard 退而显示 perio(分 47)→ 与治疗链「种植修复·11 潜在新链」口径对不上。 修复:按 (诊断码 + 牙位 overlap) 把 reason 对齐到【它自己】那条 altClosedBy 链才抑制(reasonAltClosed)。K02 闭环不再误杀 K08 召回; 而 K04 根管被同牙后续替代关闭(同一条 K04 链的 altClosedBy)仍正确抑制。 - mock-data / plan-detail-types: Chain 加 code 字段;adapt-data 透传 code - visibleReasons 上提到父组件,WhyCard 召回理由卡 + 诊断/目标治疗标签 + TopBar 共用同一份,口径统一(避免卡片显示 A、标签显示 B) - 真实数据验证:韩滨主理由 => missing_tooth@11(缺失牙·11),与治疗链一致 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
luoqi committed -
医生建议(plan 字段长尾"建议X")原先 MVP 直接 drop,现忠实保留并在病历快读显示: - transforms 新增 union 算子(表级合并)— 补上"transforms 无 union"的 TODO - manifest:plan 的"建议"→ _plan_recommendation_raw → union 并入 treat_plan 的 _recommendation_raw - recommendation.yaml:加 name(医生原文,无 enum)+ sourceEncounterExternalId(按接诊匹配) - fact-content-schemas:recommendation.code 改可空 + 加 name / source_encounter_external_id - recommendation.parser:未命中白名单不再丢(code=null 但保留原文 name);空 code 不触发召回 - emr-soap-view:P 段加「医生建议」(忠实原文,如"建议更换 · 11;12;…") 病历牙位:SOAP 全部牙位完整展示(formatToothPosition maxShow=999),不再"等 N 颗"。 注:存量患者需重摄入才有历史"建议";新增量自动带。无 DB migration(content 为 JSON)。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
luoqi committed -
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
luoqi committed -
患者级抑制门(与具体诊断信号无关):最近一次到诊(encounter/emr)在 POST_VISIT_COOLDOWN_DAYS(默认 14)天内 → 本轮不入召回池,别催刚来过的人。 - 锚"最近到诊",跟诊断 cooldown(锚诊断日、按 K 码定长)不同,二者并存各补各的洞: cooldown 给新诊断缓冲;本门拦"旧诊断 + 近期又来过"。 - 配合已有的"0 命中关闭遗留 plan":患者一到诊,下次重算自动从召回列表撤下。 - 不含 appointment(预约不一定到诊;未来预约已由 ⑤b 排除)。 - 现内联在 initiation scenario;将来上复购 scenario 时抽成共享 fragment 复用。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
luoqi committed
-