- 03 Jun, 2026 2 commits
-
-
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
-
- 02 Jun, 2026 17 commits
-
-
参考话术: - 去默认 demo 话术,未生成显示空态;原文模式默认全展开;诊断·目标治疗标签 - 4 段 id/标题对齐(opening/informMissed/reviewAdvice/closing),去时长显示 侧栏: - 患者画像移到「为什么召回」下;关键事实默认展开,改 4 行(主治医生/专属客服/累计消费/保险客户-显示保险名) - 为什么召回:只显示一条 + "+N" hover card 看其余(对齐列表页) - 新增「治疗历史」卡(治疗计划置顶 + actual 倒序,标在右,4 行高滚动)+「历史联系」占位;隐藏召回建议 头部 + 病历: - 去"普通患者"占位;病历号显示在名字后(括号) - 头部登录用户显示人名(dictionary)+ 中文角色(userDisplayName/roleNameZh) - 模拟登录按钮显示岗位·人名 - 病历快读 SOAP:P 段加「本次治疗」(actual 治疗,同次接诊) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
luoqi committed -
话术(draft-plan-script): - 删 AI_SCRIPT_USE_SKILLS 开关与 legacy system prompt(只剩 skills 路径) - 术语 漏诊→应治未治 全量对齐;base/成人/儿童 skill 逐字还原业务原模板 - 清除 system + user prompt 污染(去 PAC 内部说明/解释/溯源/内部元数据/金额/FDI/方案词) - 占位符统一:{xxx}=填值替换、【xxx】=原样保留(时间段/具体预约时间/缺失牙位) - 停用 14 个旧 skill(诊断 K00-K09/场景/关系/异议库/safety-rules)— 不在业务规格内且与新结构冲突 - composer:age 未知默认成人;skill 拼接去内部 name/version - 自报家门用登录客服 岗位+姓名(input.agent;controller resolveAgent;mockLogin 配演示人名) 聚合(plan-aggregate): - parseScriptMarkdownToSections 标题/ID 对齐新 4 段(修"刷新后话术空白") - 透出 病历号 medicalRecordNumber、专属客服 dedicatedCs、persona feature.data(保险等) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>luoqi committed -
页面加载中仍显示旧 4 段标题:根因 use-script-stream 硬编码旧 id/label (opening/followup/objection/close)做加载骨架。修: - use-script-stream:ServerSection.id + LABEL_FALLBACK + makeEmptySections 改新 4 段 (开场白/告知应治未治/复查建议/结束回访语) - 去掉建议时长显示(script-viewer 3 处 durationHint span;无意义) - 告知漏诊项目 → 告知应治未治(orchestrator label + markdown header + mock + 前端 fallback) web TS 0 + service TS 0;本地 pac-service 已重启载新标题。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
luoqi committed -
改了 schema/prompt/skills 但没 bump version → PromptCacheService 按 promptVersion+input 缓存,同患者"重新生成"返回旧结果(老 5 段)。bump 后缓存失效,新 4 模块生效。 (本地 dev 服务 .md 启动只读一次,改 skill 需重启进程才重载——已重启) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
luoqi committed -
按业务"年龄群先不细分、保持原汁原味": - 撤 adult SKILL.md 里我加的"年龄微调(青少年/老年)"段(原提示词没有) - 撤 prompt 里"年龄适应性(青年/中年/老年)"注入 + resolveAgeGroup 用法 - 仅保留 儿童≤12 / 成人≥13 两分支(原提示词口径) - script-facts 的 ageFit 数据 + resolveAgeGroup 函数保留休眠(原配置自带,未来要细分再启用,现不注入) typecheck 0 + build + 25 测试通过。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
luoqi committed -
- 删 population/teen(14-17)/elder(65+):你的提示词是 2 分支(儿童≤12/成人≥13), 二者都落在"成人",且正文还是旧 5 段 → 删之归并;老年/青少年沟通微调并入 adult skill, 年龄适应性细节已由 script-facts ageFit(青年/中年/老年)注入,不丢东西 - 页面:script-viewer 本就是通用渲染(sections.map by label/markdown)→ 自动适配新 4 段; mock-data demo 段同步成 4 模块(开场白/告知漏诊项目/复查建议/结束回访语)短句版 - (诊断 skill 里几处 population-elder/teen 是注释性文字提及,无害,低优先后清) web TS 0 + service TS 0 + build 通过。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
luoqi committed -
聚焦一个漏诊项时,喂 LLM 的上下文应针对该项目,而非泛泛"最近一次就诊": - orchestrator resolveReasonTrigger 扩展:除触发医生/日期,再取该诊断**那次接诊的主诉** (evidence.factIds[0]→诊断 fact→source_encounter→该 encounter 的 emr.illness_desc) - reason 加 triggerChiefComplaint;prompt 注入: · 智能日期 = top.triggerDate(该漏诊项诊断日期)优先,非最近就诊 · "那次就诊主诉" = top.triggerChiefComplaint(那次为什么来),非最近一次主诉 · 医生 = top.triggerDoctor 优先 - 临床上下文"最近一次接触"降级为仅参考;fallback 同步用项目相关日期/医生 避免"缺牙2025-12诊断却说自从2026-03洁牙后"的错位。typecheck 0 + build + 25 测试通过。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
luoqi committed -
对齐业务提示词"只处理最高优先级漏诊项,其他完全忽略": - 之前 user prompt 仍把全部 reason + 全部待做治疗塞进去 → LLM 看得到就可能提其他项 - 改:只喂 priorityScore 最高那条 reason 的触发详情;其他 reason **不展示**(渐进式披露, LLM 看不到自然不会提)+ 显式标注"另有 N 项,本次一律不提,下次召回单独处理" - 删 pendingTreatments 多项列表(主漏诊项已覆盖);ongoingChains 保留(语义不同:已在管别再约) typecheck 0 + build 通过。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
luoqi committed -
- 上次主诉:emr_record.illness_desc 原文接入(自由文本直喂 LLM,无需结构化) → input.clinicalContext.lastChiefComplaint + orchestrator 取最近 emr + prompt 注入 - population/adult SKILL.md:按业务"成人漏诊话术模板"原样重写(4 模块 + 各小节句式/示例) - population/child SKILL.md:按业务"儿童话术模板"原样重写(对象=家长,间隙保持器路径,≤18禁拍片) - 年龄分档对齐业务口径:child ageMax 13→12,adult ageMin 18→13(≥13/未知=成人模板), 跟 script-facts.resolveAgeBranch(≤12童/≥13成人)一致 typecheck 0 + build 通过 + registry 正常加载。 待续:teen/elder SKILL.md 旧结构增量微调(低优先,base-system 已主导)、页面 4 段、live 验证。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
luoqi committed -
补字段(PAC 有的补上,没有的优雅降级): - prompt.ts:user prompt 加「程序已算好的事实」块 — 称呼/智能日期/主漏诊项(转换层)/ 接诊医生/复查时长/风险要点/治疗优势/年龄适应性,全 TS 算好直接给,LLM 不再判断 - 病历号(patient.medicalRecordNumber,PAC patients 表有)补进 input + orchestrator - PAC 没有的:客服岗位角色/姓名 → 开场用"我是{诊所}的客服"兜底(不编头衔); 上次主诉(无结构化)→ 省略;联系人姓名(无)→ 儿童称呼用 患者姓+家长 - base-system.md 重写:旧 5 段 → 4 模块铁律(医疗关怀非销售 / 只讲单漏诊项 / 用"程序算好的事实" / 时间用【占位】/ ≤18禁拍片 / 禁费用·方案·推销 / 短句互动 / 主动约) - safety/任务footer 同步 4 段 typecheck 0 + build 通过;script-facts 单测 25 通过。 待续:population 成人/儿童 SKILL.md 正文重写(+年龄分档对齐 ≤12/≥13)、页面4段、live 验证。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>luoqi committed -
确认"漏诊项" = PAC treatment_initiation_recall 的 reason(K00-K09 应治未治): - SUBKEY_TO_MISSED:10 个子场景 subKey(missing_tooth/perio_no_srp/ortho_no_consult…) → 漏诊项配置 key + 患者口径 label(missedFromReason,带 @tooth 后缀处理 + 文本兜底) - 补齐 PAC 子场景对应的 key-points(牙周炎/错颌畸形/牙体损伤/牙龈问题/恒牙萌出空间不足/ 儿牙早矫)+ 复查时长,确保每个子场景都查得到 - 主漏诊项 = priorityScore 最高的 reason(用 PAC 6 因子排序,不另用业务硬优先级) - fallback 改用 missedFromReason(plan.reasons 最高分那条) script-facts 单测 25 通过(+5 转换层),typecheck 0。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
luoqi committed -
吸收业务"参考话术"提示词,把本该程序判断的确定性逻辑从 LLM 提取出来: - script-facts.ts(新):年龄分支(≤12童/≥13成人/未知→成人)、智能日期(今年X月X号/ 去年X月/更早XXXX年X月,替代提示词里的 python)、智能称呼(姓+先生/女士·家长·您好)、 漏诊项优先级挑选 + 归一、MISSED_DIAGNOSIS_KEY_POINTS / TREATMENT_DURATION 字典查表 → LLM 不再做年龄分支/日期格式/优先级/查表;渐进式只塞命中那一条,不发全表 - schema/output:5段(opening/followup/objection/close)→ 4模块 (opening 开场白 / informMissed 告知漏诊项目 / reviewAdvice 复查建议 / closing 结束回访语) - orchestrator:section id/title + fullMarkdown 同步 4 模块 - safetyRules:精简为 no_forbidden_phrases / no_commit_phrasing / no_bold_concrete_time (≤18禁拍片改 prompt 约束,SafetyContext 不带 age);fallback 重写为 4 模块占位版 - 缓存/渐进式:静态铁律→system(前缀缓存),确定性事实→TS 算好塞 user(下一阶段注入) 骨架验证:script-facts 单测 20 通过,service typecheck 0 错 + build 通过。 下一阶段(待续):base-system/成人+儿童 SKILL.md 正文重写、prompt.ts 注入计算事实、 orchestrator 补字段(漏诊项/岗位/上次处置/主诉/就诊日期)、页面 4 段、live 验证。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
luoqi committed -
按业务重新归类通话结果(EXECUTION_OUTCOME_META 单一真理源,前后端同步): - 成功(close→completed):「转化新预约」(原"成功转化为新预约");去掉"近期不考虑" - 不成功(give_up):明确拒绝、已在外院治疗(终态 abandoned)+ 再考虑(冷静期7天) · 再考虑 = 原 declined_recent 改 drivesStatus=keep + suppressDays=7(非终态,7天后自动浮现) - 保持(keep):打不通(原"未接通")、秒挂(新 quick_hangup,算保持)、约定下次回访 - 待跟进/无效 → hiddenInForm(不在表单展示,仅翻译历史) - 新建预约按钮常显(不再仅"成功"时出现) - group label 改 成功/不成功/保持(仅 outcome-form 消费,不影响列表 tab) resolveSnoozedUntil(suppressDays!=null → now+N)天然支持 再考虑=keep+7天;测试更新通过。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
luoqi committed -
evidence 语义是"为什么(证据溯源)",塞业务 payload 越界。改用独立 data Json? 列: - schema: persona_features 加 data Json?(+ migration 20260602054612) - PersonaFeatureDraft.data 顶层字段(从 evidence.data 移出);evidence 回归只放 factIds - persona.service 写入 + 序列化透出 data 列 - entitlement extractor 结构化明细写 data 列 本地验证(6857):data 列含 {commercialInsurers/lastCommercialInsuranceAt/...},evidence 只剩 factIds。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>luoqi committed -
luoqi committed
-
吸收 CDP 画像字典 v3.0「权益身份」+「专属客服」,落 PAC 三层: 权益身份(entitlement_status persona feature,事实投影型): - 商业保险强时效(雇主团险换工作即失效,DW 无保单有效期)→ 不断言"当前在保", 产「史 + 最近日期」:everCommercial + insurers[] + lastInsuranceAt + monthsSinceLast, 时效判断留给读取方(UI 按日期变措辞 / scorer 按 monthsSinceLast 套窗口) - 判定 channel='insurance' OR content.insurance_name 非空(拆单支付里保险非主导也能捕获) - 保司名 57 脏名在 feature 层 canonicalInsurer 归一(别名折叠 + 排除测试数据) - 零 DB 迁移:description 人读串 / score=monthsSinceLast / evidence.data 放结构化明细 fact 层:payment_record 加 insurance_name(payment.yaml 映射 + parser + zod schema) 专属客服(current_task_director):路由属性非画像,并入 patients.preferences.dedicatedCs (mergePatientPreferences 共享 helper,cold-import + dispatcher 两处 upsert,零迁移) 本地端到端验证(患者 6857):payment.insurance_name 写入 / entitlement="商保客户·平安 健康险·最近2026-03(2个月前)"(PINGAN+PingHealth 归一为一家)/ dedicatedCs={832,康慧捧} Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>luoqi committed -
修"正畸/牙周误召"(40393fbe)后暴露的两个独立引擎缺口。 缺口1(主):0 命中时不关闭遗留 active plan recomputeForPatient 在 hits.length===0 时直接 return,runAllForHost 只遍历 hitsByPatient(有命中的患者)→ 患者治完疗变 0 命中后,旧召回 plan 永远残留召回池(status 一直 active,该结案却不结)。 修复: - recomputeForPatient 0 命中 → closeStaleActivePlan supersede 关闭 该患者 active(非 assigned)plan。 - runAllForHost upsert 循环后,扫该 (host,tenant) 全部 status='active' plan,凡不在本轮 hitsByPatient 的 supersede 关闭。 - 纪律:按 tenant 限定;assigned 不动(客服跟进中);终态不动; 不建后继版本(无信号是终结,非版本演进);循环后扫避免误关本轮新 active。 - 新增 plansClosed 计数(EngineRunResult + recomputeForPatient 返回 + CLI 日志)。 缺口2(次):scenario 排除/聚类不消费 wholeMouth flag K05 标了 wholeMouth(牙周全口病)但 ⑤a 排除 SQL / tooth-overlap 聚类 都没消费 → K05 诊断带具体牙位(如@38)、牙周治疗在别的牙(@36)时被当 单牙不重叠 → 误召 perio_no_srp@38。 修复:wholeMouth 码把"信号牙位"统一替换成 NULL(sigToothExpr)→ - ⑤a 第一分支"信号无牙位"恒真 → category 级排除 - ⑤c/⑤e"信号有牙位"守卫恒假 → 单颗拔除/冠桥不误终结全口病 - 主 SELECT tooth=null → 聚类归 'whole' cluster(sub_key=...@whole) K07 经临床确认正畸=全牙弓矫治,同加 wholeMouth(K07 + ORTHO_CONSULT_RECOMMENDED),消除残留 3 例 ortho 误召。 测试:plan-engine-stale-close.spec.ts 覆盖 - 有命中→0命中→plan 被关闭(recomputeForPatient 4 例 + runAllForHost 3 例) - wholeMouth flag 标注防漂移(K05/K07/SRP/ORTHO 标,K02/K04/K08 不标) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
luoqi committed
-
- 01 Jun, 2026 5 commits
-
-
根因(陈施羽 998421 复现): 1. 分类 bug:keyword "二期" 太宽,把"二期隐形矫正"(正畸)误判成 implant 种植 → treatment_actual.yaml: 二期 → 种植二期;ortho 加"隐形矫"兜底 2. 时间方向:正畸/牙周全口慢性病,复诊反复重记诊断,"治疗须晚于诊断"失效 → 误召"未启动" → canonical-codes K05/K07 加 excludeIfEverTreated;scenario ⑤a 对其忽略时间方向(曾做过即排除) 按牙位的码(K02/K04/K08 等)规则不变 定向重处理工具(线上只重摄受影响的 ~1493 人,不全量): - cold-import: PAC_COHORT_ONLY_PATIENT 支持逗号列表(IN 过滤) - recompute-persona / recompute-plans: 加 --pids=<逗号externalId> 定向重算 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
luoqi committed -
- ListPlansQuerySchema 加 targetClinicIds(逗号串 preprocess 拆数组) - plan.service list 按 targetClinicId IN [...] 过滤(仍受 staff clinic 隔离 OR 取交集) - plans-api 数组序列化为逗号串上线 - 前端 ClinicFilter(Popover + 复选框),选项来自 token dictionary.clinics(用户可见诊所),>1 诊所才显示 - 选中存进 query.targetClinicIds,切换回第一页 + 清选择 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
luoqi committed -
Twilio 不支持拨打中国大陆(CN 不在其 218 个自助可拨国家列表,需工单审批且高资费/美国主叫), 不适合国内患者召回外呼。撤掉集成,保留"拨打"按钮做占位,点击提示"需企业资质认证 + 接入国内合规外呼线路"。 生产改接国内线路(阿里云语音/腾讯云/容联等)时,本架构(token+voice回调+拨打组件)可平移。 - 删 telephony 后端模块 + use-twilio-call hook - call-widget 简化为占位按钮 + toast 提示 - 移除 twilio / @twilio/voice-sdk 依赖、configuration twilio 块、wrap-response twilio 跳过、.env TWILIO 变量 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
luoqi committed -
- 后端 telephony 模块:POST /twilio/token(签 Voice AccessToken,JWT)+ POST /twilio/voice(@Public,Twilio 回调返回 <Dial> TwiML) - 患者真号不下发浏览器(前端传 planId,后端查库解析);API Key Secret 只服务端 - TWILIO_FORCE_TO 联调开关(trial 账号只能打已验证号 → 强制拨它) - 前端 use-twilio-call hook(@twilio/voice-sdk 动态 import)+ CallWidget(拨打/呼叫中/计时/静音/挂断/重拨),挂在详情页"通话结果"头部 - wrap-response 拦截器跳过 /twilio/voice(返回裸 TwiML XML) - 配置:twilio 块(accountSid/apiKeySid/apiKeySecret/twimlAppSid/callerId/forceTo) 注:trial 阶段只能拨已验证号 + 美国主叫;生产需 Upgrade + China geo permissions,主叫建议换国内合规线路 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
luoqi committed -
召回闭环(snoozedUntil 列): - execution 按 outcome 写 snoozedUntil(成功60/拒绝90/外院·无效永久/熔断30/约定回访到回访日) - upsertPlan 信号级抑制:终态+冷静期内同 (scenario,subKey) 不复活;患者新长的别的诊断照常召回 - pool 视图过滤未到期 snooze;去掉 considering 的 likelihood 加权 - 回收 cron(每10min):超时 assigned 自动回池,跳过约定回访中的(snooze 未到不收) 详情页: - 患者级"召回历史"卡(跨版本最近8条)+ "暂缓跟进"角标 - 终态(已完成/已放弃)提交按钮置灰 + 提示 工作台修复: - 结案保留 assigneeUserId(我的已完成/转化率不再恒为0) - "全部我的"含已完成;assigned 状态文案改"进行中" 通话结果重构:13→3 大类(结案/保持/放弃),group
↔ 状态机↔ 列表tab 一一对应 召回反馈:plan_executions.recall_feedback,5 tag 选填收集一线对召回准确性的反馈(喂算法迭代) 日期组件:shadcn Date Picker(Calendar+Popover,captionLayout dropdown)+ 原生时间输入 迁移:20260601032022_add_plan_snoozed_until / 20260601072323_add_execution_recall_feedback Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>luoqi committed
-
- 31 May, 2026 4 commits
-
-
每个病历一个点 → 病历多(13+)时溢出。改窗口化:最多 9 个点跟随当前居中, 首尾小点暗示更多,容器 overflow-hidden 兜底;精确位置由"第 N/M 次"文字给出。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
luoqi committed -
skills 正文已直接注入 system,user prompt 末尾再列名字纯冗余(还易困惑);删之。 promptVersion bump 到 skills-base-v2 便于 eval 区分。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
luoqi committed -
prompt_template 只存 user prompt;新增 system_prompt 列存完整 system(base-system + 注入的 skills 正文),一键审计完整 prompt,免去用 input+promptVersion 重跑 composeSystem。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
luoqi committed -
详情页正中底部麦克风钮 → 旁听患者语音 → 字幕式实时输出给客服的单句提示。 - 后端独立模块 realtime-coach:WS 网关(socket.io,JWT 握手)+ DashScope/Gemini Live 两套代理(同 RealtimeProvider 接口,按 provider 选);DASHSCOPE/GEMINI key 只服务端 - 复用话术的患者上下文装配(buildScriptInputForPlan),教练专属指令(抓主诉/循序渐进, 不复用销售脚本);turn-end(患者停顿)触发,前端 VAD 静音门控 - 前端独立组件:麦克风浮钮 + 字幕浮层(逐级虚化)+ 真实电平波形 + 背景虚化 + 模型切换 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
luoqi committed
-
- 30 May, 2026 6 commits
-
-
详情页"刷新"原走 recomputeForPatient→runAllForHost,对整个租户跑召回 SQL 并重写全员 plan(13万规模拖到分钟级 / >120s)。 - ScenarioScope 加可选 patientId;scenario SQL 注入 AND p.id=patientId 收窄 - recomputeForPatient 改真·单患者:只 selectHits 该患者 + 只 upsert 这一个 plan - loadTablesForPatient 6 张源表 Promise.all 并行(跨洋 RTT 6×→1×) 本地验证:刷新 success、单患者 hits 正确、无回归。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
luoqi committed -
usePlansList 初始 query 带上默认 sort + setQuery 引用稳定(值没变返回原对象), 消除"先无 sort 拉一次、再 [sort] effect 带 sort 拉一次"的重复请求(2→1)。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
luoqi committed -
- 后端:@ai-sdk/google 接入 Gemini provider;AiProviderService.resolve 支持 deepseek-* / gemini-* 前缀,返回规范化 modelId(落账/计费用之); config 加 GEMINI_API_KEY/BASE_URL/DEFAULT_MODEL(默认 gemini-3.5-flash)+ 价格表 - 前端:shadcn DropdownMenu 拆分"重新生成 ▾"按钮,直列具体型号 (DeepSeek V4 Pro / V4 Flash / Gemini 3.5 Flash),选中即用该模型重生 - 生成中效果精简:只保留 4 个标题 shimmer 扫光(globals.css), 移除三点脉冲/AI正在生成/流式输出中等其余提示 本地三模型端到端验证 succeeded(deepseek-v4-pro/flash + gemini-3.5-flash) 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 -
诊断时间精度(摄入): - diagnosis/treatment/recommendation/review 的 occurredAt 从 rq(纯日期→零点)改 created_date (精确就诊时刻,实测 100% 同 rq 日 + 就诊时段分布)→ 跟带时间的预约能正确比先后 (修 Miyabe Juria 阻生牙被同次就诊预约误判"已进入"而误排召回) 召回/治疗链口径对齐(chain-composer 镜像 scenario,消除"召回有/链没有"分叉): - 无牙位 perio/ortho actual = 全口覆盖(镜像 ⑤a b0b9705a)→ 曾松柏 K06@45;46 显示在管 - 桶有同牙位 category actual(笼统 subtype milestone 没匹配)→ ongoing 不再 discovered(Ammu 36 bare"种植") - recommendation-only 链(只 planned_for)gapDays 用 effectiveTime → 不再被 cooldown 误滤(36 建议戴冠) - 废用牙/无功能牙不立"种植修复·发现机会"潜在链,改中性标签 + 建议拔除/观察(常量收口到 canonical-codes) - milestone 关键词补术式全称/缩写:根管治疗/RCT、种植修复/戴牙/即拔即种、正畸、牙周基础治疗 等 - implant 加 terminalSteps(戴冠=完成)+ 种植二/三期归 placement 展示: - 召回理由"距今天数"实时化(signalOccurredAt 锚点,与治疗链断口同源,免随天数陈旧) - 年龄缺失显示"?"岁(对齐列表页,不再"0岁") - 再启 banner 用真实再诊断日/名 + emr 真实医嘱(替硬编码"医嘱建议X个月内") 96 测试通过;本地 100 患者已按此重摄(rq→created_date)+ 重算核验。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
luoqi committed -
nest-cli deleteOutDir 删 dist 后,base 的 incremental:true 留下的 *.tsbuildinfo 让 tsc 误判"已构建"跳过 emit → dist 缺 config 等 → 启动 Cannot find module (nest-cli#3312 / typescript-starter#186)。 - apps/pac-service 新增 tsconfig.build.json(incremental:false,nest build 默认优先用它); IDE 仍用 tsconfig.json 保留 incremental - packages/types|utils 关 incremental(叶子包,类型检查瞬时) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
luoqi committed
-
- 29 May, 2026 3 commits
-
-
host diagnosis enum_mapping 把"废用牙/无功能牙"也映射到 K08(标注"临床功能性缺失"), 于是它们走 missing_tooth 子场景被当缺牙、召回种植。但临床上废用牙是"牙还在、无咬合功能 (对颌缺失/过长)"→ 该拔除或观察,不是修复(种植/桥/义齿)对象。 案例:826790 的 missing_tooth@18;28;38;48(name_zh=废用牙)被召回且 91 分排第一 = 催患者 来种植废用智齿(误召);韩雷 38;48 同理。 修:scenario WHERE 加临床语义剔除 —— sig.content->>'name_zh' ∈ {废用牙,无功能牙} 不进召回。 host 原文 name_zh 在 diagnosis_record.content 留底,据此精确剔除,免改 yaml / 免 reparse。 这俩名只映射到 K08 → 仅 missing_tooth 受影响,其余子场景无副作用。 验证(本地 100):826790 91 分误召消失;K08 诊断里 废用牙8+无功能牙6=14 条误召剔除, 真缺失(缺失/缺失牙/牙列缺损)12 条仍正常召回。全量 89 测试通过,tsc 0。 (拔牙本身不做泛召回;真缺失修复召回不变 — 详见 docs 讨论。) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>luoqi committed -
召回 SQL 排除口径比治疗链 markAlternativeClosed 窄:链会因同牙后续做了 implant/prosthodontic(种植/冠桥 = definitive 替代治疗)而替代闭环,召回 SQL 却只看 本类目 actual(⑤a)+ 同牙拔除(⑤c),漏了"做了冠/种植即定性"。 例 韩雷:K04@11 但 11 已戴冠(prosthodontic,无 endodontic actual 记录)→ 治疗链替代 闭环 → UI "可不召回",但召回 SQL 仍产 endo_no_rct@11 → 误建 plan → 患者进召回列表却 显示"可不召回",自相矛盾。 修:加 ⑤e —— 诊断后同牙位(交集)有 implant/prosthodontic 的 actual → 排除该诊断召回。 (surgical 拔除已由 ⑤c;K08 的 implant/prosthodontic 已在 ⑤a,此处冗余无害;仅对有牙位 信号生效,全口诊断 K05 不触发。) 验证:韩雷 → 0 plan(掉出召回列表);826790 → 仍正确召回 31;32;41;42;43(无 implant/ prosthodontic 覆盖,不误伤)。全量 89 测试通过,tsc 0。 注(后续):runAllForHost 只处理"有 hit 的 patient",不会 abandon"已不再命中"的存量 active/assigned plan(患者治好后旧 plan 仍滞留)。此为独立 gap,待补"无 hit 清理"+ assigned plan 复评策略。 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
luoqi committed -
排除闸 ⑤a 的"actual 无牙位 → 视为覆盖该类全部牙位"对所有 excludeCats 生效, 导致一次无牙位外科处置(如切开引流)被当成"全口 surgical 治疗",误杀同患者所有 含 surgical 类目的 per-tooth 召回(K03/K06 等)。 实测 826790:K03 不良修复体@31;32;41;42;43(2024-11-28)被 2025-05-30 的无牙位 切开引流(surgical)误排除;而 11;12(2025-12-30,晚于引流)正常召回 → 自相矛盾。 修:无牙位 actual 仅当 category ∈ {periodontic, orthodontic} 才视为全口覆盖 (实测 actual 牙位有/无分布:牙周 134:1、正畸 19:1 压倒性无牙位 = 整牙弓治疗; surgical 1:41、restorative 1:91、prosthodontic 0:19 压倒性 per-tooth,无牙位多是 录入缺失或急性处置)。其余类目要求 actual 有牙位且与诊断牙位交集。 验证:826790 → 新增 hard_tissue_damage@31;32;41;42;43 召回;45;46(K06)仍被 牙周全口洁治正确排除(periodontic 保留全口覆盖)。本地 100 患者 patientsHit 37→39 (救回 2 个被无牙位外科误杀的)。全量 89 测试通过,tsc 0。 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>luoqi committed
-
- 28 May, 2026 3 commits
-
-
concurrency=5 时每批 5 表并行 → 25 个并行 CH 查询打远程阿里云 DW,公网扛不住 → read ETIMEDOUT → 整轮 fatal abort(并连锁触发 teardown 中 Prisma "Engine is not yet connected")。根因:queryJsonWithRetry 瞬时正则只匹配 "timeout",不匹配 "ETIMEDOUT"(无该子串)→ 没重试就直接抛。 补:ETIMEDOUT / ECONNREFUSED / EHOSTUNREACH / ENETUNREACH / EPIPE / "HTTP request error" / "fetch failed" 进瞬时白名单,可退避重试。 注:并发本身仍是 DW 限制 —— 实测 concurrency=3(15 并行)稳,5(25 并行)超时。 此 host 走 concurrency=3 为上限;重试只兜偶发抖动,不是提并发的许可证。 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
luoqi committed -
问题:每日增量同步的 host 清单写在 env(PAC_INCREMENTAL_HOSTS=jvs-dw)。接入新 host (manifest + 冷启都做了)却忘了改这条 env → 静默不被 cron 同步,不报错。env 跟 host 配置分离,易 drift。 改:把"是否自动增量"声明进 host 自己的 manifest(顶层 auto_sync: bool,默认 false)。 - manifest.schema 加 auto_sync 字段。 - ColdImportService.discoverAutoSyncHostDirs(dataDir):扫各 host 子目录 manifest, 返回 auto_sync=true 的目录名(宽松:无 manifest/解析失败/无 flag 跳过)。 - scheduler:env 设了 → 显式 override(escape hatch);未设 → 自动发现。无 host → warn+skip。 - jvs-dw manifest 置 auto_sync: true;.env.example PAC_INCREMENTAL_HOSTS 改为可选/默认空。 效果:接入新 host 只在其 manifest 置 auto_sync: true 即纳入每晚同步,不碰 env。 验证:real data/ → [jvs-dw];synthetic(有flag/无flag/无manifest/坏yaml)→ 只 [hostA]。 tsc 0,全量 89 测试通过。 注:服务器 .env 现仍有 PAC_INCREMENTAL_HOSTS=jvs-dw(override 生效,行为不变); 要切到 manifest 自动发现,部署时清空该 env 即可。 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
luoqi committed -
问题:actual-only(无诊断)链立链判据是 category 级(`!dxCategories.has(cat)`)。 当某 cat 恰好被一个【不同牙位】的诊断占了槽,该 cat 落在其他牙位的 actual 就既进不了 诊断链(牙位不重叠)、又立不了自己的链 → 整条隐身。 李梦维:K00(先天/萌出,主类目=surgical)占了 surgical 槽,3 次拔除(28/18/15)隐身 → "已被替代:外科手术·28" 指向一条不存在的链(看着自相矛盾)。 修:改成牙位级 —— cat 有诊断桶但 actual 落在【同类诊断未覆盖的牙位】→ 单独立 actual-only 桶(tooth=未覆盖牙位,只收这些牙,不跟诊断链重叠;code='' 不参与召回 ★,纯展示)。 李梦维 → 多出 "外科手术·15;18;28" 闭环链,K00 仍 ★,替代标注指向真实链。 防双显:无牙位诊断(host 诊断常不填牙位)覆盖范围未知 → 视为该 cat 全覆盖,不 carve (否则诊断链借 actual 牙位显示,跟新链撞同 (cat,tooth);023cbb47 K02 无牙位+充填 17;47 即此坑)。 回归(800 患者):总链 1722→1751(+29 条原本隐身的真实治疗现身),同 (cat,tooth) 双显 违规 11→11(我引入 0;那 11 条是 K02+K03 同牙的既有现象,与本改无关)。全量 89 测试通过。 注:治疗链 read-time 合成,无需重算 DB。 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
luoqi committed
-