docs: 校准 PHIS 档案 upsert 任务
This commit is contained in:
@@ -46,6 +46,8 @@ scripts/*.json
|
|||||||
*_results.json
|
*_results.json
|
||||||
*_result.json
|
*_result.json
|
||||||
/*.json
|
/*.json
|
||||||
|
# PHIS 原始响应样本(真实身份证/住址/医生账密,文件名即身份证号)——只本地留存
|
||||||
|
/payloads/
|
||||||
# 账号/凭据(userName/密码/主机/代理)——只本地留存
|
# 账号/凭据(userName/密码/主机/代理)——只本地留存
|
||||||
/docs/账号.txt
|
/docs/账号.txt
|
||||||
# 本地联调探针脚本(硬编码了 ask/orgCode/身份证等真实值)——只本地留存
|
# 本地联调探针脚本(硬编码了 ask/orgCode/身份证等真实值)——只本地留存
|
||||||
|
|||||||
+2
-2
@@ -245,7 +245,7 @@ checkId = 截断20位( 编码( 源系统标识 | dataType | 源记录主键 [ |
|
|||||||
|
|
||||||
## 10. JKDA 创建/更新请求契约(T-206 本地基线)
|
## 10. JKDA 创建/更新请求契约(T-206 本地基线)
|
||||||
|
|
||||||
T-206 已建立本地契约与客户端方法,真实写入验收暂未执行,原因见 `progress.md` 对应记录。
|
T-206 已完成本地契约与客户端方法并通过单测;真实写入验收拆为 T-215,当前等待明确写入授权与安全测试档案。
|
||||||
|
|
||||||
- `JKDA00001`:`/osi/api/jkda/create` → `osi.CreateHealthRecord`
|
- `JKDA00001`:`/osi/api/jkda/create` → `osi.CreateHealthRecord`
|
||||||
- `JKDA00003`:`/osi/api/jkda/update` → `osi.UpdateHealthRecord`
|
- `JKDA00003`:`/osi/api/jkda/update` → `osi.UpdateHealthRecord`
|
||||||
@@ -253,7 +253,7 @@ T-206 已建立本地契约与客户端方法,真实写入验收暂未执行
|
|||||||
- 创建请求侧门牌号字段使用 `addressNumber`;查询响应侧仍以实测错拼 `adressNumber` 建模,二者不能混用。
|
- 创建请求侧门牌号字段使用 `addressNumber`;查询响应侧仍以实测错拼 `adressNumber` 建模,二者不能混用。
|
||||||
- `mapping.BuildHealthRecordCreate` 负责把 `MappedHealthRecord` 组装成 `contract.HealthRecordCreate`,保留确定性 `checkId`,并由 `manaDoctorId/manaUnitId` 派生 `createUser/createUnit`。
|
- `mapping.BuildHealthRecordCreate` 负责把 `MappedHealthRecord` 组装成 `contract.HealthRecordCreate`,保留确定性 `checkId`,并由 `manaDoctorId/manaUnitId` 派生 `createUser/createUnit`。
|
||||||
|
|
||||||
真实 create/update 联调完成后,需要在本节补回平台返回样本、`phrId` 字段确认、同一 `checkId` 重复 create 的幂等语义。
|
T-215 真实 create/update 联调完成后,需要在本节补回平台返回样本、`phrId` 字段确认、同一 `checkId` 重复提交的幂等语义、更新目标标识、`addressNumber` 落库结果及逐档案 `operateUser` 规则。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
+6
-3
@@ -30,10 +30,13 @@
|
|||||||
- [x] `contract/jkda.go` 查询响应结构体(T-201;创建/更新请求结构体留到 T-206)。
|
- [x] `contract/jkda.go` 查询响应结构体(T-201;创建/更新请求结构体留到 T-206)。
|
||||||
- [x] `mapping/health_record.go` + `mapping/checkid.go`。
|
- [x] `mapping/health_record.go` + `mapping/checkid.go`。
|
||||||
- [x] `osi/jkda.go`:Find/FindRqbj(T-203;Find 已真实请求验收,FindRqbj 已按文档契约单测覆盖)。
|
- [x] `osi/jkda.go`:Find/FindRqbj(T-203;Find 已真实请求验收,FindRqbj 已按文档契约单测覆盖)。
|
||||||
- [ ] `osi/jkda.go`:Create/Update(T-206,依赖映射与字典缓存)。
|
- [x] `osi/jkda.go`:Create/Update 本地契约与客户端能力(T-206);真实平台验收拆至 T-215。
|
||||||
- [ ] `handler` + `router`:暴露 `/api/health-record/save`(server 模式联调用)。
|
- [ ] PHIS 真实档案 DTO + PHIS→CHIS 完整转换器(T-212)。
|
||||||
|
- [ ] 按身份证查询后 create/update 的 upsert 应用服务(T-213)。
|
||||||
|
- [ ] `handler` + `router`:暴露 `POST /api/health-record/upsert`(T-204,server 模式联调用)。
|
||||||
|
- [ ] 用授权测试档案完成 create→query→update→query 真实验收(T-215)。
|
||||||
- [x] 用 01 文档样例 + 联调样本写映射单测。
|
- [x] 用 01 文档样例 + 联调样本写映射单测。
|
||||||
- **验收**:一条 PHIS 档案 → 映射 → create → 平台返回成功码(实测 `"01"`)与 `phrId`;重复投递被幂等跳过。
|
- **验收**:一条 PHIS 档案 → 映射 → 查询判定 → create/update → 平台返回成功码(实测 `"01"`)并回查一致;重复投递被幂等跳过。
|
||||||
|
|
||||||
## 阶段 3 · 投递流水线
|
## 阶段 3 · 投递流水线
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
查询链路已打通,接下来"其余业务线查询 + 将来写入"被以下三件卡着,**建议同一封邮件一起催**,避免写入阶段既缺授权又缺规则双重卡壳:
|
查询链路已打通,接下来"其余业务线查询 + 将来写入"被以下三件卡着,**建议同一封邮件一起催**,避免写入阶段既缺授权又缺规则双重卡壳:
|
||||||
|
|
||||||
1. **写入授权 + 安全测试档案**(见 D3)——解 T-206(档案 create)阻塞,进而解 T-204。
|
1. **写入授权 + 安全测试档案**(见 D3)——解 T-215(档案 create/update 真实验收)阻塞,进而完成 T-204 真实 curl 验收。
|
||||||
2. **缺失的列表/查询接口 serviceId + 路径**(见 B1、B2、B4)——解 T-304 列表查询、T-303 老年人查询的 serviceId 缺口。
|
2. **缺失的列表/查询接口 serviceId + 路径**(见 B1、B2、B4)——解 T-304 列表查询、T-303 老年人查询的 serviceId 缺口。
|
||||||
3. **写入业务规则**:checkId 去重语义 + 完整度谁算(见 C1、C2)——写入阶段前置,现在问以免后置返工。
|
3. **写入业务规则**:checkId 去重语义 + 完整度谁算(见 C1、C2)——写入阶段前置,现在问以免后置返工。
|
||||||
|
|
||||||
|
|||||||
@@ -5,15 +5,15 @@
|
|||||||
|
|
||||||
## 当前快照
|
## 当前快照
|
||||||
|
|
||||||
- 日期:2026-07-09
|
- 日期:2026-07-15
|
||||||
- 阶段:**Phase D 创建/更新代码基线完成,真实写入验收受阻;T-303 老年人生活自理能力评估查询代码完成、真实联调受阻**;T-001~T-006、T-201、T-203、T-102、T-202、T-205、T-101、T-103、T-209、T-210 已验收;T-206 已完成本地契约/客户端/映射组装代码,但未执行真实 `JKDA00001` create
|
- 阶段:**T-206 创建/更新本地能力已完成;进入 Phase U 的 PHIS 档案转换与 upsert,真实写入验收由 T-215 单独受阻**;T-303 老年人生活自理能力评估查询代码完成、真实联调受阻
|
||||||
- 技术栈:Go 1.24 单二进制;`main.go -mode server|deliver`;配置读取使用 viper,支持环境变量覆盖;OSI 客户端已具备签名、信封、传输、基础判码、JKDA00002 Find、JKDA00005 FindRqbj(人群分类,已按实测 auto 路径校准)、JKDA00001 Create、JKDA00003 Update、LNRZLPG00002 老年人生活自理能力查询(待真实联调),以及 WGDZ/ZRYS/YPML/CXJG 四个公开查询薄封装
|
- 技术栈:Go 1.24 单二进制;`main.go -mode server|deliver`;配置读取使用 viper,支持环境变量覆盖;OSI 客户端已具备签名、信封、传输、基础判码、JKDA00002 Find、JKDA00005 FindRqbj(人群分类,已按实测 auto 路径校准)、JKDA00001 Create、JKDA00003 Update、LNRZLPG00002 老年人生活自理能力查询(待真实联调),以及 WGDZ/ZRYS/YPML/CXJG 四个公开查询薄封装
|
||||||
- 生产代码:已有 `main.go`、`config/`、`contract/envelope.go`、`contract/jkda.go`、`contract/lnr.go`、`osi/` 薄客户端、`cache/dictionary.go`、`verify_jkda.go`、`go.mod`/`go.sum`;`mapping/dict.go`、`mapping/health_record.go`、`mapping/checkid.go` 已建立映射纯函数、码表基线、主数据反查接入点和创建请求组装;`handler/health_record.go`+`handler/elderly.go`+`handler/public.go`+`server.go` 提供 server 模式档案查询、人群分类查询、老年人自理能力查询、网格地址、责任医生、药品目录、机构查询端点;`pipeline/` 等业务模块仍待后续任务建立
|
- 生产代码:已有 `main.go`、`config/`、`contract/envelope.go`、`contract/jkda.go`、`contract/lnr.go`、`osi/` 薄客户端、`cache/dictionary.go`、`verify_jkda.go`、`go.mod`/`go.sum`;`mapping/dict.go`、`mapping/health_record.go`、`mapping/checkid.go` 已建立映射纯函数、码表基线、主数据反查接入点和创建请求组装;`handler/health_record.go`+`handler/elderly.go`+`handler/public.go`+`server.go` 提供 server 模式档案查询、人群分类查询、老年人自理能力查询、网格地址、责任医生、药品目录、机构查询端点;`pipeline/` 等业务模块仍待后续任务建立
|
||||||
- 联调现实:**JKDA00002 个人档案查询已用 Go 侧真实请求打通**,返回 `code="01" message="操作成功" data_count=1`;**公开查询 WGDZ00001/ZRYS00001/CXJG00002 已用真实档案主数据验证通过**,均返回 `code="01"` 且数组非空;药品目录 YPML00001 已完成客户端封装和单测,尚未做真实药品关键字样本验证;**JKDA00001 create 未跑真实请求**,避免在没有安全测试居民/写入授权时污染平台档案
|
- 联调现实:**JKDA00002 个人档案查询已用 Go 侧真实请求打通**,返回 `code="01" message="操作成功" data_count=1`;**公开查询 WGDZ00001/ZRYS00001/CXJG00002 已用真实档案主数据验证通过**,均返回 `code="01"` 且数组非空;药品目录 YPML00001 已完成客户端封装和单测,尚未做真实药品关键字样本验证;**JKDA00001 create 未跑真实请求**,避免在没有安全测试居民/写入授权时污染平台档案
|
||||||
- 测试:`go test ./...` 通过;当前测试覆盖 mode 解析、配置加载与环境变量覆盖、MD5 签名、请求头组装、JSON POST 传输、头名大小写保留、identity 响应编码声明、超时配置、SOCKS5 代理地址校验、信封结构、serviceId 路由、成功/重试判码、Client.Call 请求与响应解析、JKDA00002 查询响应契约、JKDA00001/00003 创建更新请求契约与客户端方法、JKDA00002 Find、JKDA00005 FindRqbj(personSign/idCard/phrId)、公开查询四接口、公开查询 HTTP API、字典缓存快照与持久化失败不阻断、映射码表双向查找、民族 01~56 完整性、健康档案映射必填/码表校验、主数据名称反查、创建请求组装、checkId 确定性、docx/联调风格映射样本基线、JKDA00002 验证入口
|
- 测试:`go test ./...` 通过;当前测试覆盖 mode 解析、配置加载与环境变量覆盖、MD5 签名、请求头组装、JSON POST 传输、头名大小写保留、identity 响应编码声明、超时配置、SOCKS5 代理地址校验、信封结构、serviceId 路由、成功/重试判码、Client.Call 请求与响应解析、JKDA00002 查询响应契约、JKDA00001/00003 创建更新请求契约与客户端方法、JKDA00002 Find、JKDA00005 FindRqbj(personSign/idCard/phrId)、公开查询四接口、公开查询 HTTP API、字典缓存快照与持久化失败不阻断、映射码表双向查找、民族 01~56 完整性、健康档案映射必填/码表校验、主数据名称反查、创建请求组装、checkId 确定性、docx/联调风格映射样本基线、JKDA00002 验证入口
|
||||||
- 标准启动路径:`./init.sh` 已配置三步:依赖下载、`go test ./...`、`go run . -mode server -config config.yaml.example`
|
- 标准启动路径:`./init.sh` 已配置三步:依赖下载、`go test ./...`、`go run . -mode server -config config.yaml.example`
|
||||||
- 标准验证路径:`go test ./...`、`go build ./...`
|
- 标准验证路径:`go test ./...`、`go build ./...`
|
||||||
- 当前 blocker:T-206 真实 create 验收缺少可写入沙箱的安全测试居民资料或明确写入授权。软限制:当前机器从 Git Bash 启动 Go 会出现标准库路径/构建缓存权限异常,`init.sh` 无法完整跑完;PowerShell 下等价 Go 命令和真实查询通过。厂家侧 B1/B2/B4/B5 契约缺口只影响阶段 4
|
- 当前 blocker:T-215 真实 create/update 验收缺少可写入沙箱的安全测试居民资料或明确写入授权;该 blocker 不影响先做 T-212 转换器和 T-213 假依赖编排。PHIS `archId/businessId/phrId/empiId` 的稳定主键语义、逐档案 `operateUser` 规则也需在 T-212/T-215 中确认。软限制:当前机器从 Git Bash 启动 Go 会出现标准库路径/构建缓存权限异常,`init.sh` 无法完整跑完;PowerShell 下等价 Go 命令和真实查询通过。厂家侧 B1/B2/B4/B5 契约缺口只影响阶段 4
|
||||||
|
|
||||||
## 当前目录要点
|
## 当前目录要点
|
||||||
|
|
||||||
@@ -98,13 +98,13 @@ python3 scripts/query_health_record.py
|
|||||||
|
|
||||||
## 下一步
|
## 下一步
|
||||||
|
|
||||||
> 读先行调整(2026-07-08):写入(T-206/T-204)被厂家授权锁死,先推其余业务线查询。
|
> 2026-07-15 已把本地能力与真实验收拆开:T-206 标记本地 DONE,T-215 承接授权后的真实写入验收。
|
||||||
|
|
||||||
1. ✅ T-301/T-305 体检查询(最近一次 + 名单)、T-302 体检 HTTP 端点 —— 均已完成。
|
1. **T-212**:确认 PHIS 四类标识语义,建立脱敏 DTO/fixture、完整字段转换器和逐档案操作上下文。
|
||||||
2. **T-303 真实联调**:提供安全测试身份证后,确认 `LNRZLPG00002`、`/auto/lnr/query` 与响应字段;当前代码/单测已完成。
|
2. **T-213**:用假 OSI、幂等、report、PHIS 回写接口完成 upsert 应用编排;不等待写入授权。
|
||||||
3. T-307 老年人中医体质辨识查询仍待厂家补查询文档(docs/06 B4)。
|
3. **T-204**:复用 T-213 暴露 `POST /api/health-record/upsert`,handler 不复制业务逻辑。
|
||||||
4. 并行催厂家(docs/06 ★ 优先催办):写入授权+测试档案、缺失单查/老年人体质 serviceId、checkId/完整度规则。
|
4. 并行催厂家/PHIS 维护方:写入授权与可写测试档案、稳定源主键语义、更新目标标识、逐档案 `operateUser` 规则。
|
||||||
4. 授权到位后回到 T-206 真实 create 验收 → T-204。
|
5. 授权到位后执行 T-215 真实 create→query→update→query 验收。
|
||||||
|
|
||||||
## 维护规则
|
## 维护规则
|
||||||
|
|
||||||
|
|||||||
+23
@@ -317,3 +317,26 @@
|
|||||||
- 验证:openapi YAML 合法、drugs pageNo required=true、grid-addresses 共享 pageNo 仍 false;Go 静态自检通过;现有 drugs 测试(pageNo=1/pageNo=bad)不受影响。待用户 `go test ./...` 复验。
|
- 验证:openapi YAML 合法、drugs pageNo required=true、grid-addresses 共享 pageNo 仍 false;Go 静态自检通过;现有 drugs 测试(pageNo=1/pageNo=bad)不受影响。待用户 `go test ./...` 复验。
|
||||||
- 决策:只修请求侧分页契约(清晰的 bug);不扩 `Drug` 响应结构体(缺 ypxh/ypjl/ycjl),因 YPML00001 未真实联调、避免照 docx 猜类型,且 HTTP 走 Raw 不影响输出。全程注明 docx 契约待联调。
|
- 决策:只修请求侧分页契约(清晰的 bug);不扩 `Drug` 响应结构体(缺 ypxh/ypjl/ycjl),因 YPML00001 未真实联调、避免照 docx 猜类型,且 HTTP 走 Raw 不影响输出。全程注明 docx 契约待联调。
|
||||||
- 下一步:联调 YPML00001 拿真实分页样本后,确认 pageNo/pageSize 真契约并补 Drug 响应字段。
|
- 下一步:联调 YPML00001 拿真实分页样本后,确认 pageNo/pageSize 真契约并补 Drug 响应字段。
|
||||||
|
|
||||||
|
## 2026-07-15 T-212/T-213 任务卡评审与校准(全栈视角 review codex 落卡)
|
||||||
|
|
||||||
|
- 状态:任务卡已按评审修订,T-212/T-213 均保持 TODO
|
||||||
|
- 评审结论:拆分方向正确(纯转换 vs upsert 编排、依赖链诚实),upsert 7 条防御规则(查询失败禁降级创建、多条转人工、失败不互相回退)与凭据隔离要求保留不动。
|
||||||
|
- 修订 1(checkId):T-212 的"更新时间不参与稳定标识"实为对已 DONE 代码的行为修改——现有 `mapping/health_record.go` 把 `src.UpdatedAt` 传入 `GenerateCheckID`。卡片补注:改现有调用+同步 T-205 基线单测+落 ADR(CLAUDE.md checkId 保守处理项;依据 T-206"Update 沿用 checkId")。
|
||||||
|
- 修订 2(contract 范围):删除"扩至 docx 写入字段全集"——违反"不照搬 docx 字段表"铁律且写入路径无联调样本兜底;收窄为只扩 PHIS 实际提供+映射需要的字段。
|
||||||
|
- 修订 3(adressNumber):`adressNumber→addressNumber` 改名仅有 docx 依据(查询响应实测是错拼 adressNumber),卡片标注为首次真实创建后的联调必核对项。
|
||||||
|
- 修订 4(T-213 边界收窄):`source/` 与 PHIS 回写契约(阶段 5)尚不存在——T-213 只定义回写 interface+假实现验收,真实回写拆出 T-214 登记到延期任务表;幂等/状态存储注明与阶段 3 pipeline 共用一套。
|
||||||
|
- 附带:真实样本 `businessId == archId` 同值,回退分支需人工构造 fixture(已注入卡片)。
|
||||||
|
- 安全修复:`payloads/`(文件名即真实身份证号,内容含住址/手机号/医生账密)未被 gitignore,已补 `/payloads/` 并以 `git check-ignore` 验证生效。
|
||||||
|
- 下一步:提交 tasks.md/.gitignore/progress.md;领取 T-212 时按修订后的卡片执行。
|
||||||
|
|
||||||
|
## 2026-07-15 T-212/T-213 评审建议二次校准
|
||||||
|
|
||||||
|
- 状态:任务与依赖已重排,未领取实现任务;T-212/T-213/T-204 保持 TODO,T-215 因真实写入授权 BLOCKED。
|
||||||
|
- 决策:把原 T-206 拆为“本地写入能力”和“真实平台验收”。既有 T-206 代码与本地测试证据满足前者,状态改 DONE;新增 T-215 承接授权后的 create→query→update→query 验收,使 T-213 可在假依赖下先开发。
|
||||||
|
- 决策:不再根据单个样例假定 `businessId` 优先。T-212 先确认 `archId/businessId/phrId/empiId` 的稳定性,再通过 ADR 固化 `ResolveSourceRecordKey` 与 checkId 兼容策略。
|
||||||
|
- 决策:补充逐档案 `operateUser`、更新目标/机构/状态校验、PHIS 空值不覆盖平台值、既往史“无”代码、`isFillShhj` 条件组装和脱敏 fixture 位置等验收边界。
|
||||||
|
- 决策:T-213 只实现可复用 upsert 应用服务和注入接口,用内存假实现验收;持久化幂等/report、重试调度和熔断归路线图阶段 3,PHIS 真实状态适配归 T-214,HTTP 入口归 T-204。
|
||||||
|
- 安全:保留 `/payloads/` 整体忽略规则,并清理新增规则的异常行尾;真实样本不进入 Git。
|
||||||
|
- 验证:`go test ./...` 通过;`go build ./...` 通过;`git diff --check` 通过。
|
||||||
|
- 验证:`git check-ignore -v payloads\\441625198611255416_phis_health_record.json` 命中 `.gitignore:50:/payloads/`,真实 PHIS 样本未进入 Git。
|
||||||
|
|||||||
@@ -57,9 +57,9 @@
|
|||||||
|
|
||||||
## Phase D · 字典服务与创建闭环(真实主数据反查)
|
## Phase D · 字典服务与创建闭环(真实主数据反查)
|
||||||
|
|
||||||
> **读先行调整(2026-07-08)**:档案**创建/更新**(T-206/T-204)真实验收依赖厂家写入授权 + 安全测试档案(docs/06 D3),当前锁死。
|
> **读先行调整(2026-07-08)**:档案**创建/更新真实验收**(现拆为 T-215)依赖厂家写入授权 + 安全测试档案(docs/06 D3),当前锁死。
|
||||||
> 故把**其余业务线的查询**(Phase Q2)提到写入之前先做——读路径不被授权阻塞,且顺带摸清各业务线响应字段,为将来写入去风险。
|
> 故把**其余业务线的查询**(Phase Q2)提到写入之前先做——读路径不被授权阻塞,且顺带摸清各业务线响应字段,为将来写入去风险。
|
||||||
> T-206 创建代码已完成并入库,保持不动,授权到位后再回来验收。
|
> T-206 本地契约、客户端和映射组装代码已完成并通过测试;真实平台验收不再阻塞后续本地编排开发。
|
||||||
|
|
||||||
| ID | 任务 | 依赖 | 验收要点 | 状态 |
|
| ID | 任务 | 依赖 | 验收要点 | 状态 |
|
||||||
| --- | --- | --- | --- | --- |
|
| --- | --- | --- | --- | --- |
|
||||||
@@ -67,8 +67,8 @@
|
|||||||
| T-103 | 字典缓存(内存 + redis 可选) | T-101, T-102 | 映射层能反查 `regionCode/manaDoctorId/manaUnitId`;redis 不可用不阻断 | DONE |
|
| T-103 | 字典缓存(内存 + redis 可选) | T-101, T-102 | 映射层能反查 `regionCode/manaDoctorId/manaUnitId`;redis 不可用不阻断 | DONE |
|
||||||
| T-210 | 公开查询 HTTP API(人群分类、网格地址、责任医生、药品目录、机构) | T-101, T-209 | server 模式暴露人群分类与四类公开查询 HTTP API;原样回写平台 JSON;同步 `docs/07` 与 `docs/openapi.yaml`;按内网部署场景明确绑定地址/鉴权边界 | DONE |
|
| T-210 | 公开查询 HTTP API(人群分类、网格地址、责任医生、药品目录、机构) | T-101, T-209 | server 模式暴露人群分类与四类公开查询 HTTP API;原样回写平台 JSON;同步 `docs/07` 与 `docs/openapi.yaml`;按内网部署场景明确绑定地址/鉴权边界 | DONE |
|
||||||
| T-211 | 药品目录查询按分页契约修正 YPML00001 | T-210 | 依 docx:`pageNo` 必填(去 `omitempty`+handler 缺则 400)、补 `pageSize`;`docs/07 §8`+`openapi.yaml` 标 pageNo 必填并补 pageSize;docx 契约未联调,注明待厂家样本核对(尤其 pageNo 是否真必填、响应 `ypxh/ypjl/ycjl` 字段)| DONE |
|
| T-211 | 药品目录查询按分页契约修正 YPML00001 | T-210 | 依 docx:`pageNo` 必填(去 `omitempty`+handler 缺则 400)、补 `pageSize`;`docs/07 §8`+`openapi.yaml` 标 pageNo 必填并补 pageSize;docx 契约未联调,注明待厂家样本核对(尤其 pageNo 是否真必填、响应 `ypxh/ypjl/ycjl` 字段)| DONE |
|
||||||
| T-206 | `osi/jkda.go`:**Create/Update** + `contract/jkda.go` 补创建请求结构体 | T-201, T-202, T-103 | 一条档案经映射(真实字典快照)→ create → 平台返回成功码与 `phrId`;Update 沿用 checkId | BLOCKED(代码完成;待写入授权/测试档案,排在 Phase Q2 之后) |
|
| T-206 | `osi/jkda.go`:**Create/Update 本地能力** + `contract/jkda.go` 写入请求结构体 | T-201, T-202, T-103 | JKDA00001/00003 serviceId、路径、uploadinfo 同级节点、响应解码和映射组装均有单测;`go test ./contract ./osi ./mapping` 通过 | DONE(真实写入验收拆至 T-215) |
|
||||||
| T-204 | `handler`+`router`:`/api/health-record/save` | T-206 | server 模式起服务,curl 全链路返回投递结果 | TODO(待 T-206 解阻塞) |
|
| T-204 | `handler`+`router`:`POST /api/health-record/upsert` | T-213 | server 模式接收 PHIS 档案 DTO,调用同一 upsert 应用服务并返回结构化结果;handler 假依赖测试覆盖 create/update/manual_review/error,默认仍只绑定本机 | TODO(真实 curl 验收待 T-215) |
|
||||||
|
|
||||||
## Phase Q2 · 其余业务线查询(读先行)
|
## Phase Q2 · 其余业务线查询(读先行)
|
||||||
|
|
||||||
@@ -84,13 +84,61 @@
|
|||||||
| T-305 | 体检已检/未检名单查询 JKTJLIST00002(`osi` 方法 + 契约)| T-004 | `auto/jktjlist/query` 探针实测已部署(code=01 返回名单);`osi.ListHealthCheckPeople` 按 checkYear+idCard 返回名单(含 checkType 状态),契约见 docs/04 §11.4 | DONE |
|
| T-305 | 体检已检/未检名单查询 JKTJLIST00002(`osi` 方法 + 契约)| T-004 | `auto/jktjlist/query` 探针实测已部署(code=01 返回名单);`osi.ListHealthCheckPeople` 按 checkYear+idCard 返回名单(含 checkType 状态),契约见 docs/04 §11.4 | DONE |
|
||||||
| T-304 | 列表类查询(**档案 / 老年人自理·体质 / 中医指导** 列表,serviceId docx 缺漏)| T-004 | 各列表路径+serviceId 到位后返回分页数组 | BLOCKED(待 docs/06 B1/B2 厂家回填)|
|
| T-304 | 列表类查询(**档案 / 老年人自理·体质 / 中医指导** 列表,serviceId docx 缺漏)| T-004 | 各列表路径+serviceId 到位后返回分页数组 | BLOCKED(待 docs/06 B1/B2 厂家回填)|
|
||||||
|
|
||||||
|
## Phase U · PHIS 健康档案转换与 upsert
|
||||||
|
|
||||||
|
> 输入事实来源为本地 `payloads/441625198611255416_phis_health_record.json`,目标契约来源为
|
||||||
|
> `docs/统一对外服务接口文档.docx` 中 JKDA00001/JKDA00003,以及 `docs/01`、`docs/04` 的已整理契约。
|
||||||
|
> 两份本地原始材料均可能包含个人信息或凭据,只用于分析和生成脱敏测试夹具,不得提交 Git。
|
||||||
|
|
||||||
|
| ID | 任务 | 依赖 | 验收要点 | 状态 |
|
||||||
|
| --- | --- | --- | --- | --- |
|
||||||
|
| T-212 | PHIS 健康档案真实结构建模与 PHIS→CHIS 转换器 | T-202, T-103 | 建模 PHIS `data.doctor/data.record/archId/businessId/empiId/phrId`;先确认稳定源主键语义并落 ADR;完整转换 JKDA 主体、既往史和生活环境;校验必填/长度/日期/码表;脱敏 fixture 回归;按档案责任医生生成请求操作上下文 | TODO |
|
||||||
|
| T-213 | 健康档案 upsert 应用编排(外部能力均接口注入) | T-212, T-203, T-206 | 按身份证查询 CHIS:0 条创建、1 条合规档案更新、多条/跨机构/不可更新状态转人工;查询失败不得降级创建;用假 OSI/幂等/report/PHIS 回写实现验收,不在本任务实现持久化 | TODO |
|
||||||
|
| T-215 | JKDA 健康档案真实 create/update 验收 | T-212, T-213 | 经明确授权的安全测试档案完成 create→query 回查→update→query 回查;确认 `phrId`、checkId、更新目标标识、`addressNumber`、责任医生/机构及重复提交语义,并回填 docs/03 §8、docs/04 §10 | BLOCKED(待写入授权和可写测试档案) |
|
||||||
|
|
||||||
|
### T-212 需求与解决方案
|
||||||
|
|
||||||
|
**需求**
|
||||||
|
|
||||||
|
- 接收 PHIS 健康档案响应,保留业务主键和档案数据;`doctor.sxtAccount/sxtPassword` 等凭据不得进入领域模型、日志、OSI 请求或测试夹具。
|
||||||
|
- 把 PHIS 扁平字段转换为 CHIS `uploadinfo` 下同级的 `healthRecord`、`pastHistory`、`jwsjb`、`jwsss`、`jwsws`、`jwssx`、`familyMiddle`。
|
||||||
|
- 支持字段改名:PHIS `adressNumber` → CHIS 写入字段 `addressNumber`。⚠ 该拼写仅有 docx 依据(查询响应实测是错拼 `adressNumber`,见 `contract/jkda.go` 查询结构体),**列为首次真实创建后的联调必核对项**:创建成功后回查该字段是否落库,若平台写入端实际收 `adressNumber` 则改名方向反转。
|
||||||
|
- 支持结构转换:`diseasetext_*` → 既往史对象/数组,`shhjCheck*` → 生活环境对象;多选值统一输出英文逗号。
|
||||||
|
- PHIS 未提供且 CHIS 非必填的 `phoneNumber/addressCode/homePlaceCode/insuranceType/personGroup` 不伪造值,按空值省略;后续若取得独立人群分类数据,再单独补充 `personGroup`。
|
||||||
|
- 不根据单个样例预设 `businessId` 或 `archId` 的优先级。先向 PHIS 契约/维护方确认 `archId/businessId/phrId/empiId` 的语义、生命周期和更新时是否稳定,再由 `ResolveSourceRecordKey` 统一选择稳定源主键。
|
||||||
|
- `checkId` 的同一源档案多次重试和多版本更新必须稳定;更新时间只用于版本审计。该调整会改变现有 `GenerateCheckID(..., src.UpdatedAt)` 行为,落地时必须同步修改调用、T-205 基线单测,并在 `docs/decisions/` 记录主键事实、选择规则、回退规则和兼容影响;主键语义未确认前不得把策略标记为最终完成。
|
||||||
|
- `manageInfo.DSFMC/operateUnit` 来自可信配置;`operateUser` 使用经责任医生字典验证的档案 `manaDoctorId`。若平台只允许固定配置医生,则必须校验二者一致,不得由客户端静默覆盖。
|
||||||
|
|
||||||
|
**解决方案**
|
||||||
|
|
||||||
|
- 在 `source/` 定义只含业务字段的 PHIS DTO,并提供 JSON 解码;对外层 `code/msg/compress` 和业务 `data` 分层建模。未知的医生账号/密码字段由解码器忽略,脱敏 fixture 放在 `source/testdata/` 或 `mapping/testdata/`,不放入整体忽略的 `payloads/`。
|
||||||
|
- 在 `mapping/` 保持纯函数转换:直传字段显式赋值,码表字段统一走 `dict.go`,主数据通过 `MapContext.MasterData` 校验/反查,嵌套结构由专用小函数组装。
|
||||||
|
- 扩充 `contract.HealthRecordCreateInfo`、`PastHistory` 和四类既往史结构,**范围只到 PHIS 实际提供 + 本期映射需要的字段**——不照搬 docx 写入字段全集(CLAUDE.md 铁律:docx 字段名/类型有前科,写入路径尚无联调样本兜底);docx 独有且 PHIS 给不出的字段不进结构体,确需预留的逐个标"待联调核对"。创建和更新复用同一业务数据契约,仅 serviceId/path 不同。
|
||||||
|
- 返回结构化 `ValidationError`;身份证、日期、字段长度、CHIS 必填项、枚举和多选码未通过时禁止调用 OSI。
|
||||||
|
- 建立逐字段映射表并由表驱动测试覆盖:主体直传字段;`diseasetext_check_gm/check_bl/check_fq/CheckMQ/CheckXDJM/CheckZN/RedioYCBS/CheckCJ` → `pastHistory`;`diseasetext_radio_jb/ss/ws/sx` → 四类数组;`shhjCheckCFPFSS/RLLX/YS/CS/QCL` → `familyMiddle`。
|
||||||
|
- 既往史代码非空时生成对应节点(包括“无”代码),空值省略;名称/日期未提供时不伪造。`isFillShhj=n` 时省略 `familyMiddle`,为 `y` 时才校验并组装生活环境。真实写入后由 T-215 校准平台对“无”代码节点的最终要求。
|
||||||
|
- 从真实 payload 派生脱敏 fixture,覆盖完整转换、可选字段省略、未知码值、缺失必填、空既往史、生活环境未填写、稳定主键跨版本不变,以及人工构造的主键缺失/回退场景。
|
||||||
|
|
||||||
|
### T-213 upsert 规则
|
||||||
|
|
||||||
|
1. 用 PHIS `record.idCard` 调用 JKDA00002 查询,只有明确成功响应才允许判断记录数量。
|
||||||
|
2. 查询结果为 0 条:构造 JKDA00001 创建请求;查询结果为 1 条时,先校验身份证精确一致、档案状态可更新、目标机构/责任医生符合授权范围,再构造 JKDA00003 更新请求。
|
||||||
|
3. 查询结果超过 1 条、跨机构或状态不可更新时停止投递并标记人工处理,禁止任选一条更新。
|
||||||
|
4. 查询网络错误、超时、平台业务错误或响应无法解析时进入可重试/失败流程,禁止按“不存在”执行创建。
|
||||||
|
5. 更新失败不得自动回退创建;创建失败也不得自动改走更新,避免平台状态不明时产生重复档案。
|
||||||
|
6. 更新目标单独建模为 `UpdateTarget`,保留查询返回的 `phrId/empiId/checkId/manaUnitId/status`;仅把 T-215 真实契约确认允许的标识写入更新请求,不用 PHIS 空值覆盖平台已有值。
|
||||||
|
7. 以稳定 `checkId` 和身份证建立幂等/并发保护;成功事件只记录脱敏后的 `phrId`、serviceId、响应码和 trace_id,禁止把原始 payload、OSI 完整请求/响应写入普通日志。
|
||||||
|
8. 内部状态定义为 `done/retry/failed/manual_review`,只有 CHIS 明确成功码才标 `done`。T-213 只定义并注入 `IdempotencyStore/ReportSink/PHISStatusWriter` 接口,用内存假实现验证编排;Redis/文件持久化、重试调度和熔断统一留给路线图阶段 3。
|
||||||
|
9. PHIS 真实回写由 T-214 实现;内部状态与 PHIS 实际支持状态分开建模,由适配器完成映射,不能预设 PHIS 原生支持 `manual_review`。
|
||||||
|
10. T-213 提供可被 HTTP handler 和未来 `deliver-worker` 复用的单一应用服务;T-204 只做 HTTP 适配,不复制 upsert 逻辑。
|
||||||
|
|
||||||
## 里程碑
|
## 里程碑
|
||||||
|
|
||||||
- M1 = T-005:Go 客户端与平台真实握手成功(签名/信封/判码全对)。
|
- M1 = T-005:Go 客户端与平台真实握手成功(签名/信封/判码全对)。
|
||||||
- M2 = T-203:**Go 版查询档案打通**(Find,不碰字典)。
|
- M2 = T-203:**Go 版查询档案打通**(Find,不碰字典)。
|
||||||
- M3 = T-205:映射层就绪 + 单测基线(假字典快照)。
|
- M3 = T-205:映射层就绪 + 单测基线(假字典快照)。
|
||||||
- M4 = T-301:**体检查询打通**(其余业务线读先行第一条)。
|
- M4 = T-301:**体检查询打通**(其余业务线读先行第一条)。
|
||||||
- M5 = T-206:真实创建闭环 + 幂等(授权到位后,字典反查主数据 → create → phrId)。
|
- M5 = T-215:真实 upsert 闭环(授权到位后,PHIS 转换 → create/query/update → 回查确认)。
|
||||||
|
|
||||||
## 待办池(Backlog,按路线图阶段 3~6 展开,进入时再拆小任务)
|
## 待办池(Backlog,按路线图阶段 3~6 展开,进入时再拆小任务)
|
||||||
|
|
||||||
@@ -105,5 +153,6 @@
|
|||||||
| ID | 任务 | 触发条件 | 验收要点 | 状态 |
|
| ID | 任务 | 触发条件 | 验收要点 | 状态 |
|
||||||
| --- | --- | --- | --- | --- |
|
| --- | --- | --- | --- | --- |
|
||||||
| T-007 | 传输层支持 https/TLS | **生产环境地址确认为 https 时必须先做**(沙箱是 http,不阻塞当前开发) | `osi/transport.go` 裸 HTTP/1.1 写目前仅支持 http(明文 TCP、`scheme != "http"` 直接报错)。需在 TLS 下同样保留 `orgCode/deviceSN/userName` 头名大小写策略;对 https 目标能发起真实请求并拿到 `code`;单测覆盖 https 路径 | TODO(生产前 gate) |
|
| T-007 | 传输层支持 https/TLS | **生产环境地址确认为 https 时必须先做**(沙箱是 http,不阻塞当前开发) | `osi/transport.go` 裸 HTTP/1.1 写目前仅支持 http(明文 TCP、`scheme != "http"` 直接报错)。需在 TLS 下同样保留 `orgCode/deviceSN/userName` 头名大小写策略;对 https 目标能发起真实请求并拿到 `code`;单测覆盖 https 路径 | TODO(生产前 gate) |
|
||||||
|
| T-214 | PHIS 状态真实回写(替换 T-213 假实现) | PHIS 回写接口契约到位(路线图阶段 5,回写接口/字段/状态码确认后启动) | 实现 T-213 的 `PHISStatusWriter`:把内部 `done/retry/failed/manual_review` 映射为 PHIS 实际支持的状态/字段;回写失败不覆盖本地最终状态并可补偿重试;日志脱敏 | TODO(依赖 PHIS 侧契约) |
|
||||||
|
|
||||||
> 来源:`docs/review/2026-07-06-phase0-review.md` P1-2。向厂家确认生产地址协议(见 `docs/06` A10)后,若为 https 则本任务提升为阻断项;若确认生产仍是 http,则关闭本任务并在传输层注释说明。
|
> 来源:`docs/review/2026-07-06-phase0-review.md` P1-2。向厂家确认生产地址协议(见 `docs/06` A10)后,若为 https 则本任务提升为阻断项;若确认生产仍是 http,则关闭本任务并在传输层注释说明。
|
||||||
|
|||||||
Reference in New Issue
Block a user