Commit 0ef13ebb by luoqi

docs(deploy): reparse SOP 写入 deployment-data-ingest + 标 task#46 完成 + 诊断 code 长尾待办

- 新增 §六bis Reparse SOP:原理(raw_payload 离线重跑、非破坏、不连 DW)/ 用法(dry-run/全量/
  --patient/--no-recompute/docker)/ 实测基线(全量 541k ~28min,内存 ~630MB;单批 274 ~46s)/
  典型场景(诊断漏 code → 漏召,正畸 5554→1)。
- §五运维表 + §六 yaml 变更表:truncate 重导 → 改指向 reparse。
- §八已知边界:reparse 模式缺  已落地;新增"诊断 code 长尾待评估"(松动牙/种植体周围炎,
  需业务决策,不是补 code 能解决)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
parent 807ded08
......@@ -326,8 +326,8 @@ ORDER BY started_at DESC LIMIT 1;
| **手动补跑昨日增量** | `pnpm sync-incremental -- --dir=./data/jvs-dw` |
| **某 patient 召回不对,临时单刷** | `pnpm recompute-plans -- --host=jvs-dw`(全 host)/ 详情页 "刷新" 按钮(单 patient) |
| **看某 patient 治疗链** | `pnpm exec ts-node src/cli/verify-chain.cli.ts --id=<uuid>` |
| **改 yaml/scenario 后强制重算 plan** | 删旧 plan: `TRUNCATE followup_plans CASCADE;` + `pnpm recompute-plans -- --host=jvs-dw` |
| **改 yaml 后强制 reparse 旧数据** | (task #46 待做)目前只能 truncate facts + 重 cold-import |
| **改 scenario SQL 后强制重算 plan** | `pnpm recompute-plans -- --host=jvs-dw`(scenario 改口径、facts 不变,无需 reparse) |
| **改 yaml 字典后补存量 fact(reparse)** | `pnpm reparse -- --host=jvs-dw --subject-type=<canonical> [--patient=..] [--dry-run] [--no-recompute]`(离线、非破坏,见 §六bis)|
---
......@@ -337,14 +337,70 @@ ORDER BY started_at DESC LIMIT 1;
| 改动类型 | 影响 | 处理 |
|---|---|---|
| **enum_mapping 加 host 术式** | 新数据生效,老数据需要 reparse | 配 task #46 / 暂时 truncate facts 重导 |
| **enum_mapping / keyword_mapping 加/改术语** | 新数据生效,老数据需 reparse | **`pnpm reparse -- --subject-type=<canonical>`**(§六bis;不用全量重摄)|
| **field_mapping 改字段名** | 同上 | 同上 |
| **transforms 改 split/derive** | 影响管道 | 同上 |
| **scenario SQL 改召回口径** | 立即生效(下次 cron 跑就用) | 删旧 plan + 等 cron 或手动 recompute-plans |
| **transforms 改 split/derive** | 影响管道 | 同上(reparse 会重跑 transforms)|
| **scenario SQL 改召回口径** | 立即生效(下次 cron 跑就用) | 等 cron 或手动 `recompute-plans`(facts 不变,无需 reparse)|
| **canonical-codes.ts 改字典** | 立即生效(chain composer 用) | 重启 pac-service |
---
## 六bis、Reparse — yaml 字典改了补存量 ⭐(不用全量重摄)
改了 assembler yaml(enum_mapping / keyword_mapping / field_mapping / transforms)后,要把**已入库的老
fact 按新口径重新衍生** —— **不用** truncate + 全量重摄(那会拉 DW ~2h 且 `TRUNCATE` 删掉
plan_executions / 分配)。`reparse` 用已存的 `transaction.rawPayload`(host 原始源行)**离线**重跑
transformEngine + assembler + parser:
- **非破坏**:fact 走版本流(内容变 → supersede 升版本,不变 → 幂等跳过);不 truncate、不碰 transaction
账本 → 客服执行历史 / 分配全保住。
- **不连 DW**:rawPayload 在本地 → 比全量重摄快一个量级。
- **可圈定**:按 host / subject_type / 患者集 / dry-run / 是否重算。
- **覆盖**:field/enum/keyword_mapping + transforms 算子 + parser 改动(长尾字典修补 ~99%)。
**不覆盖**:改了 CH `sql_source` 的 SELECT 本身(要从 DW 多拉原来没拉的列/表)→ 那才需真重摄;
非 transform 产出的资源(如 `image_finding_rows` = CH SQL 视图)会**自动跳过**(rawPayload 非其装配输入)。
### 用法
```bash
# dry-run:报 scope(患者数 / txn 数),不写库
pnpm reparse:prod -- --host=jvs-dw --subject-type=diagnosis --dry-run
# 实跑全量某资源(按患者分批,内存恒定;自动定向重算【变更患者】的 persona/plan)
pnpm reparse:prod -- --host=jvs-dw --subject-type=diagnosis
# 限定患者(快):只重解析这些患者(改 keyword 只影响一小批时用,秒级)
pnpm reparse:prod -- --host=jvs-dw --subject-type=diagnosis --patient=<uuid>,<uuid>,...
# 只重衍 fact、不重算(超大批量时,稍后单独 pnpm recompute-plans:prod)
pnpm reparse:prod -- --host=jvs-dw --subject-type=diagnosis --no-recompute
# docker 部署(prod)容器内 detached 跑 + 看日志
docker compose --env-file apps/pac-service/.env -f docker-compose.prod.yml \
exec -d pac-service sh -c "pnpm reparse:prod -- --host=jvs-dw --subject-type=diagnosis > /tmp/reparse.log 2>&1"
docker compose -f docker-compose.prod.yml exec -T pac-service tail -f /tmp/reparse.log
```
参数:
- `--subject-type=<canonical>` — 限定资源(diagnosis / treatment_actual …);空 = 全部 transform 产出的 subject 资源。
- `--patient=<uuid,...>` — 限定患者集(秒级);空 = 全 host(分批)。
- `--dry-run` / `--no-recompute` — 只报 scope / 只重衍 fact 不重算。
- env `PAC_REPARSE_BATCH`(默认 3000)— 全量时每批患者数(控内存)。
### 实测基线(瑞尔全量 diagnosis,116809 患者)
- 541k 诊断 / 290k EMR 源行,分 39 批,**内存恒定 ~630MB**(峰值 1.6G,远低于 8G heap);
- fact 重衍 ~18min(只动变更的、其余幂等跳过)+ 定向重算变更患者 ~10min;
- 单患者 / 小批 `--patient`:**秒级~分钟级**(274 患者 ~46s)。
### 典型场景:诊断术语漏 code → 漏召回(本能力第一个用例)
host 中文诊断名变体极多(实测 98% 无 ICD 码,全靠 enum/keyword 白名单翻译),漏映射 → `code=null`
→ 进不了该病种召回(FN)。修法:`diagnosis.yaml` 加 keyword → `pnpm reparse:prod -- --subject-type=diagnosis`
**案例**:正畸"反合 / 开合 / 错牙合 / 牙列间隙"等变体补 K07,全院正畸漏召 **5,554 → 1**,新增 ~1,600 条正畸召回。
---
## 七、灾备 / 回滚
### 7.1 数据备份
......@@ -390,7 +446,8 @@ WHERE status='running' AND started_at < NOW() - INTERVAL '12 hours';
| 项 | 现状 | 影响 | 何时解决 |
|---|---|---|---|
| reparse 模式缺 | yaml 改后历史数据需 truncate + `pnpm sync --full` 重导 | 改 yaml 不能"原地补"老 facts | task #46(W5+) |
| ~~reparse 模式缺~~ ✅ | `pnpm reparse` 离线重解析(raw_payload 重跑装配+解析,不连 DW、非破坏,见 §六bis)| 改 yaml 字典秒级~分钟级补存量,不用全量重摄 | **已落地**(原 task #46)|
| 诊断 code 长尾待评估 | 松动牙(~1100)/ 种植体周围炎(~290)等真病暂未映射 code | 前者映射 K05 有过召风险(含生理性松动)、后者无对应召回 scenario | 待业务/产品决策(种植体周围炎或可开"种植维护"召回场景)|
| 告警接通道 | log ERROR + 人工看 | 滞后无即时告警 | W5+ 加 webhook 钉钉/飞书 |
| 并行 stale 锁清理 | 人工 SQL(7.4) | 崩溃后需手动 abort | W5+ 加 cron 看门狗自动清 |
| COPY 未上 | 用 prisma createMany(已 10-20x) | 极限性能还差 COPY 的 3-5x | PR5c(可选,按需) |
......
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