-
refactor(plan): 到诊派生字段落 patient_profiles —— 不进画像、不加宽主表 · d05d4b0f
返工上一版:visit_recency 曾做成 persona 特征,当天被否 ——「上次到诊 2022-06-19」是 **原始事实**,而画像该是「重要价值 / 流失客 / 禁忌」这类判断。做成特征会混进患者详情的 画像标签抽屉、并喂给画像摘要 LLM。该特征一行都没写进生产就撤了。 【落在哪】patient_profiles(1:1 副表),不是 patients: profile 本来就装派生 / 摄入属性(获客渠道、转介绍统计),patients 是主数据。 派生的归派生,主表不被越搞越宽,也不用新建一张表。 【为什么必须物化】跨全池筛选没有不物化的:否则「上次到诊在 3-6 个月」要对 2,500 万行 patient_facts 做 GROUP BY … HAVING max(occurred_at),交互式扛不住。 画像筛选也一样物化了 —— 它的柱子就叫 persona_features,只是立得早、又用 JSONB 做成了 免 DDL 的扩展点,所以加维度时感觉不到成本。这三个字段不属于画像,没有现成柱子可搭。 【
⭐ 存日期不存分档 —— 零定时任务】 存 `0_3m` 这种分档,时间流逝自己就会错(今天 2 个月、下月变 3 个月)→ 得配到期重扫 (上一版为此实现了 nextBoundaryAt);存日期则**只有患者又来了才会变**,而"又来了"必然 先写到诊 fact → 推进事实水位 → 触发该患者画像重算 → 三列顺路刷新。触发时机与既有机制 天然重合,自洽。0-3 / 3-6 / … 的区间在**查询时**按 now 现算(visitRecencyRange)。 【⭐ 到诊口径 = encounter + 实际治疗 + 挂号 + 病历】 本地实测:17,637 个有事实的患者里 **8,586 个(48.7%)只有病历、没有 encounter/治疗/挂号** (宿主 appointment.in_time 缺失等)。只用 visitFactsOf 会让近一半患者「上次到诊」为空 —— 本轮实测正是如此(487 → 加病历后 2,408,近 5 倍)。医生写了病历,患者必然到过场; 详情页 lastVisit 早就是这个并集口径,这里与它对齐。⚠ ️ 顺带发现:rfm / lifecycle_stage / urgency_level 仍用窄口径 visitFactsOf, 同一批患者会因此少算就诊次数 —— 值得另开一件事核实,本次不动。 【卡片与筛选同源】两者都读这三列,不做"取不到就现算"的兜底 —— 那会让展示值与筛选口径再次分叉,正是本次返工要消灭的问题。 首次重算前为 NULL:卡片留空、筛选筛不到、医生名单为空,都是可接受的降级。 其余:PersonaTagFilterDim 加 source/patientField 分流查询;医生名单接口改查 patient_profiles; 写入挂在画像重算遍历上(顺路,失败只告警不中断 —— 它不是画像的一部分); persona-spec-drift 的 key 校验跳过 source='patient' 维度。 655 tests / 42 suites 全过;types / service / web typecheck 通过; 本地重算实测卡片显示「2022-06-19 · 张 敏」,与筛选同源。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>luoqi committed
| Name |
Last commit
|
Last update |
|---|---|---|
| .. | ||
| migrations | Loading commit data... | |
| schema.prisma | Loading commit data... | |
| seed.ts | Loading commit data... |