全量 reparse 的时间几乎全花在"证明没变"上。2026-07-27 测试服实测:
全量范围 260,434 患者 / 87 批 / ~4.5 小时
改 clinical-signals 字典 → 真正受影响 ~40,000 患者(15%) → 6.5 倍
改 planned「二期」规则 → 真正受影响 1,017 患者(0.4%) → 250 倍(2 分钟)
已有 --patient=<uuid>,... 但几千个 uuid 塞不进命令行(ARG_MAX),缺的就是文件入口。
用法:先用 SQL 圈出受影响患者,dump 成一行一个 id,再喂进来。
psql -tAc "SELECT DISTINCT patient_id FROM patient_facts
WHERE type='treatment_record' AND kind='planned'
AND content->>'subtype' LIKE '%二期%'" > /tmp/ids.txt
pnpm reparse -- --host=jvs-dw --subject-type=treatment --patients-file=/tmp/ids.txt
文件格式刻意宽容(操作者多半是 psql 直接倒出来的):uuid 与 externalId 混写、
# 整行/行尾注释、空行、行尾逗号分号、CRLF 全收;但不做猜测性纠错 —— 认不出的
原样送去库里查,查不到就 WARN 报出前 5 个,不静默丢(否则"为什么少跑了几百人"是无头案)。
⭐ 空结果必须硬失败,这是本次最要紧的一条:
服务侧 `if (!scopePatientIds?.length)` 把空数组当"不限定" ——
一个路径写错的收窄命令会静默变成 4.5 小时全量,且日志上完全看不出异常。
现在解析为 0 / 一个都对不上库,都直接报错退出。
── 顺带修一个我自己踩出来的隐患 ──
CLI 末尾是 `void main()`(全仓 CLI 通例),我最初把纯函数留在 CLI 里、测试直接 import,
结果测试跑起来对本地库真跑了一次 reparse(115 行 Nest 日志)。两道修:
① 纯函数拆到 src/cli/reparse-patients-file.ts,测试只碰这里
② CLI 末尾加 `if (require.main === module)` 闸 —— 以后任何 import 都不会再误启动
实测(本地 friday):
空文件 → reparse 失败:解析后为 0 个患者(拒绝退化成全量)
混写清单 → 读到 4 token(uuid 1 / externalId 3 → 认领 2),WARN 1 个查不到,
最终限定 3 患者,ColdImportService 确认「范围 3 患者」
测试 547 passed(新增 13 例)。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>