Files
chis_osi/progress.md
T

15 KiB
Raw Blame History

执行进度记录

只追加的历史流水:每轮做了什么、跑了什么验证、遇到什么阻塞、做了什么决策。 当前目录/命令/下一步等可覆盖快照写 docs/current-state.md,不在本文重复。 任务状态以 tasks.md 为准。

记录格式

## YYYY-MM-DD T-编号 任务名(或事件名)

- 状态:DONE / BLOCKED / PARTIAL
- 变更:改了哪些文件或模块
- 验证:运行的真实命令和结果
- 阻塞:如有,写明原因和需要谁决策
- 决策:如有,记录本轮确定的关键取舍
- 下一步:建议下一个任务 ID 或待确认事项

执行记录

2026-05~06 设计文档集初始化(pre-code)

  • 状态:DONE
  • 变更:docs/01~06 设计文档集、CLAUDE.md、.gitignore(源材料不入库)。详见 git log 3498542..1fd2569。
  • 决策:扁平目录布局对齐 chis_upload;OSI 为无状态 MD5 签名接口,不引入旧项目逆向复杂度;幂等键用 checkId。

2026-07-06 JKDA00002 联调打通 + 文档校准

  • 状态:DONE
  • 变更:scripts/query_health_record.py(本地,不入库)打通真实查询;据实测样本校准 docs/01(成功码/信封/机构码分层/坑点坐实)、docs/04(新增 §8 实测契约)、docs/06(A1~A9/B3/B6/C3/D2/D3 回填)。
  • 验证:沙箱真实请求返回 code="01" message="操作成功",data 为档案聚合数组;脚本离线自检(编译 + 信封 + 判码逻辑)通过。
  • 决策:成功码为 "01" 非 docx 所示 "1",判定按去前导零;查询也走 uploadinfo 信封;请求头 orgCode 用 18 位统一社会信用代码(9 位码是 manaUnitId,两者不可混用)。
  • 阻塞:tests/test_query_health_record.py 测的是旧脚本 API,已失效(import 报错)→ 登记为 T-000。
  • 下一步:T-000,然后 T-001 起步阶段 0。

2026-07-06 接入 harness coding 文档工件

  • 状态:DONE
  • 变更:新建 tasks.md(看板)、progress.md(本文)、docs/current-state.md(快照)、init.sh(统一验证入口)、AGENTS.md(通用 agent 薄入口);更新 CLAUDE.md 会话启动流程与文档同步表、docs/README.md 导航、docs/05 成功码勘误。
  • 决策:任务看板放根目录 tasks.md;现有 docs/01~06 设计文档不重命名不重排;模板可选增强集(rubric/quality/method-map)暂不引入。
  • 下一步:T-000。

2026-07-06 T-000 处理失效测试

  • 状态:DONE
  • 变更:删除 tests/(test_query_health_record.py 及 __pycache__)——文件从未被 git 跟踪,无需 git rm。
  • 验证:git status --short 确认删除前后均无该目录的跟踪历史;删除后工作区干净。
  • 决策:不改写为新契约的最小测试,直接删除——脚本是硬编码的本地联调工具(不入库),暂不需要自动化测试覆盖。
  • 下一步:T-001,进入路线图阶段 0(go module + 双子命令骨架)。

2026-07-06 T-001 初始化 Go module 与双子命令骨架

  • 状态:DONE
  • 变更:新增 go.mod/go.sum、main.go、main_test.go、config/config.go、config/config_test.go、config.yaml.example;tasks.md 标记 T-001 完成;docs/05 勾选阶段 0 第一项。
  • 验证:go test ./... 通过;go build ./... 通过;go run . -mode server -config config.yaml.example 输出 chis_osi mode=server;go run . -mode deliver -config config.yaml.example 输出 chis_osi mode=deliver。
  • 验证补充:bash init.sh 在当前 Windows 环境失败,系统提示未安装 WSL;已用等价 Go 命令完成验收。
  • 决策:Go module 使用本地模块名 chis_osi;main.go 只打印 mode,不打印配置值,避免泄露真实环境信息;config.yaml.example 只保留占位值。
  • 下一步:T-002(osi/sign.go MD5 头签名 + 单测)。

2026-07-06 T-002 MD5 头签名

  • 状态:DONE
  • 变更:新增 osi/sign.go 与 osi/sign_test.go;BuildHeaders 组装 OSI 必需请求头,SignPassword 按 md5("ts=<ts>&ask=<ask>") 输出 32 位小写;tasks.md 标记 T-002 完成;docs/05 勾选阶段 0 第二项。
  • 验证:先运行 go test ./osi 看到缺少 SignPassword/BuildHeaders/HeaderInput 的预期失败;实现后 go test ./osi 通过;go test ./... 通过;go build ./... 通过。
  • 决策:固定测试向量 ts=1700000000123&ask=secret-key -> 008aceff8247cb42d2a99b2c48d0ac88 来自 Python hashlib.md5(...).hexdigest(),用于对齐本地联调脚本签名算法;ask 只参与签名,不进入 headers。
  • 下一步:T-003(osi/transport.go 传输层,保留 SOCKS5/超时)。

2026-07-06 看板重排(查询先行)

  • 状态:DONE(规划调整,无代码)
  • 变更:tasks.md 把 Phase 1(字典)/Phase 2(档案) 重排为 Phase Q(查询)→M(映射)→D(字典+创建);osi/jkda.go 拆为 T-203(Find/FindRqbj) 与 T-206(Create/Update);docs/05 加执行顺序注记。任务 ID 不变。
  • 决策:查询档案(Find)不依赖字典,映射纯函数单测只需码表+注入假字典快照,只有真实创建闭环才需 T-101/T-103 字典反查——故把字典接口降到创建之前、查询之后。顺带把"Create 依赖字典缓存"从隐性依赖显式化到 T-206。
  • 下一步:仍是 T-003(Phase 0 未变),Phase 0 完成后按 Q→M→D 领取。

2026-07-06 T-003 OSI 传输层骨架

  • 状态:DONE
  • 变更:新增 osi/transport.go 与 osi/transport_test.go;传输层支持 JSON POST、请求超时、可选 SOCKS5 代理;不设置 Cookie/Origin/Referer/X-Requested-With 等网页拟态头;tasks.md 标记 T-003 完成;docs/05 勾选阶段 0 传输层项。
  • 验证:先运行 go test ./osi 看到 NewTransport/TransportConfig 未定义的预期失败;实现后 go test ./osi 通过;go test ./... 通过;go build ./... 通过。
  • 决策:socks5_proxy 支持 host:port 和 socks5://host:port 两种写法;非空时只配置 OSI 客户端代理,不做直连回退;传输层只返回 HTTP status 和原始响应体,业务判码留给 T-004 的 client/codes。
  • 下一步:T-004(osi/client.go Call + osi/codes.go + contract/envelope.go)。

2026-07-06 T-004 OSI Client Call + 信封 + 判码

  • 状态:DONE
  • 变更:新增 contract/envelope.go、osi/codes.go、osi/client.go 及对应单测;Client.Call 负责拼 /osi/api 路径、组装 MD5 签名请求头、构造 serviceId + uploadinfo{baseInfo,manageInfo} 信封、发送 JSON、解析 {code,message,data};tasks.md 标记 T-004 完成;docs/05 勾选 client/codes/envelope 两项。
  • 验证:先运行 go test ./contract ./osi 看到 Envelope、NewClient、IsSuccessCode 等未定义的预期失败;实现后 go test -count=1 ./contract ./osi 通过;go test ./... 通过;go build ./... 通过。
  • 决策:成功码统一按去前导零后等于 "1" 判定,兼容实测 "01";405 归类为可重试;osi.base_url 按主机地址处理,Client 自动拼 /osi/api,同时兼容已带 /osi/api 的输入。
  • 下一步:T-005(阶段 0 验收:Go 侧真实请求打通 + 配置 init.sh)。

2026-07-06 T-005 阶段 0 验收:Go 侧真实请求打通 + init.sh

  • 状态:DONE
  • 变更:新增 verify_jkda.go/verify_jkda_test.go,main.go 增加 JKDA00002 验证入口(T-006 后改为 -verify-jkda + OSI_VERIFY_ID_CARD);config 支持 OSI_* 等环境变量覆盖;osi/transport.go 改为按原始 HTTP/1.1 写请求以保留 orgCode/deviceSN/userName 头名大小写;init.sh 配置依赖下载、go test ./...、启动三步命令;补充传输层头名与基础请求头单测。
  • 验证:go test ./... 通过;go build ./... 通过;使用本地环境变量发起 Go 版 JKDA00002 真实请求,返回 JKDA00002 code=01 message=操作成功 data_count=1。
  • 验证补充:init.sh 三命令已替换;当前机器从 Git Bash 启动 Go 会出现标准库路径/构建缓存权限异常,导致脚本运行环境未能完整验收。等价 PowerShell 下直接执行 go test ./...、go build ./... 与 Go 真实请求均通过。
  • 决策:真实平台/代理对请求头大小写敏感,Go net/http 会规范化头名并触发 EOF;传输层因此对 OSI 调用使用原始 HTTP/1.1 写入,保留 Python requests 已验证的头名大小写与基础头语义。
  • 下一步:T-201(contract/jkda.go 查询响应结构体)。

2026-07-06 T-006 Phase 0 review hardening

  • 状态:DONE
  • 变更:osi/transport.go 默认 Accept-Encoding 改为 identity,避免声明 gzip/br 却不解压;删除传输层未使用的 http.Client/roundTripper 残留;main.go 验证入口改为 -verify-jkda 并从 OSI_VERIFY_ID_CARD 读取身份证;删除 contract.Envelope 顶层 BaseInfo,保留 uploadinfo.baseInfo;同步 docs/03、docs/current-state.md 与 tasks.md。
  • 验证:按 TDD 先看到 TestTransportRequestsIdentityEncoding、TestEnvelopeDoesNotExposeTopLevelBaseInfo、TestResolveVerifyIDCard* 失败;实现后目标测试通过;go test ./... 通过;go build ./... 通过;git diff --check 通过。
  • 决策:Phase 0 先避免压缩响应风险,不实现 gzip/br 解压;https 支持仍按当前沙箱事实 fail-fast,生产若切 https 需另起任务处理 TLS 下的头名保留策略。
  • 下一步:T-201(contract/jkda.go 查询响应结构体)。

2026-07-06 复评 T-006 + 登记延期任务 T-007

  • 状态:DONE(评审与看板维护)
  • 变更:复评 T-006 对 docs/review/2026-07-06-phase0-review.md 的修复情况;tasks.md 新增延期任务 T-007(传输层 https/TLS 支持,生产前 gate),落地 review P1-2 的"延期须登记"要求。
  • 复评结论:T-006 认领的 4 项(gzip 声明/传输死代码/命令行 PII/Envelope 冗余)均已修复并补测;review 其余项中——P1-2 https 以 T-007 登记延期;P2-2(裸写根因抓包对照)、P3(nil-transport 静默兜底、UA 写死、init.sh 本机不通)仍未处理,作为后续小整改候选。P1-1(未提交即标 DONE)本轮 T-005/T-006 均已补交、不再漂移。
  • 决策:https 是否阻断取决于生产地址协议(挂钩 docs/06 A10);沙箱 http 不阻塞当前开发,故 T-007 置于 Backlog 而非当前 Phase。
  • 下一步:T-201。

2026-07-07 T-201 JKDA00002 查询响应契约

  • 状态:DONE
  • 变更:新增 contract/jkda.go 与 contract/jkda_test.go;按 docs/04 §8 建立 FindHealthRecordResponse、FindHealthRecord、HealthRecord、PastHistory、既往疾病/手术/外伤/输血数组和 FamilyMiddle 查询响应结构体;保留响应侧错拼字段 adressNumber;checkId、insuranceType、otherPersonGroup 等 nullable 字段使用指针。
  • 验证:按 TDD 先看到 go test ./contract -run TestFindHealthRecordDeserializesMeasuredJKDA00002Data -count=1 因 FindHealthRecord 未定义失败;补结构体后通过。随后看到 go test ./contract -run TestFindHealthRecordResponseDeserializesDataArray -count=1 因 FindHealthRecordResponse 未定义失败;补响应结构体后通过。最终 go test ./contract -count=1 通过,go test ./... 通过。
  • 决策:T-201 只建查询响应契约;创建/更新请求结构体仍按看板留到 T-206,避免提前把未联调字段固化。
  • 下一步:T-203(osi/jkda.go:Find + FindRqbj)。

2026-07-07 T-203 JKDA Find / FindRqbj

  • 状态:DONE
  • 变更:新增 osi/jkda.go 与 osi/jkda_test.go;实现 Client.FindHealthRecord(JKDA00002 /auto/jkda/find)和 Client.FindRqbj(JKDA00005 /jkda/findrqbj);查询入参按单一 key 校验,支持 idCard、empiId、phrid、personName(Find)以及 idCard/phrid(FindRqbj);verify_jkda.go 改为复用正式 Find 方法。
  • 验证:按 TDD 先运行 go test ./osi -run "TestFind(HealthRecord|Rqbj)" -count=1,因 FindHealthRecord/FindRqbj 与查询类型未定义失败;实现后目标测试通过。随后 go test . -run TestRunJKDAFindCheckUsesConfiguredOSIClient -count=1 通过,go test ./... 通过;使用本地环境变量发起正式 Go Find 真实请求,返回 JKDA00002 code=01 message=操作成功 data_count=1。
  • 决策:FindRqbj 已有 serviceId/path 与 personSign 契约,先以单测覆盖;当前只对 JKDA00002 Find 做真实请求验收,因为本地已有可查档案样本。
  • 下一步:T-102(mapping/dict.go 全量码表)。

2026-07-07 T-102 映射码表基线

  • 状态:DONE
  • 变更:新增 mapping/dict.go 与 mapping/dict_test.go;建立通用 Dict/Entry 双向查表结构和 ValidationError;落地性别、民族(01~56 + 99 其他)、血型、RH、文化程度、职业、婚姻、医保、人群标记 personSign 初始码表。
  • 验证:按 TDD 先运行 go test ./mapping -count=1,因 SexDict/Dict/ValidationError 等未定义失败;实现后 go test ./mapping -count=1 通过;补充民族 01~56 连续码检查后再次通过。最终 go test ./... 通过,go build ./... 通过。
  • 决策:当前文档未给 PHIS 侧差异码值,T-102 先以 PHIS 与 OSI 同码作为静态基线;保留 Entry{PHIS, OSI} 结构,后续 T-202 若发现 PHIS 码值差异可局部覆盖,不改调用方。
  • 下一步:T-202(mapping/health_record.go + mapping/checkid.go)。

2026-07-07 T-202 健康档案映射与 checkId

  • 状态:DONE
  • 变更:新增 mapping/health_record.go、mapping/checkid.go 与 mapping/health_record_test.go;建立 PHIS 健康档案输入、映射层 MappedHealthRecord 草稿、MapContext/DictSnapshot 注入点;主数据直传字段、码表字段、必填校验、结构化 ValidationError 与确定性 GenerateCheckID 已覆盖。
  • 验证:按 TDD 先运行 go test ./mapping -run "TestMapHealthRecord|TestGenerateCheckID" -count=1,因 MapHealthRecord/MapContext/GenerateCheckID 未定义失败;实现后目标测试通过。最终 go test ./mapping -count=1、go test ./...、go build ./...、git diff --check 均通过。
  • 决策:创建请求结构体仍留到 T-206;T-202 只输出映射层草稿结构,先把纯函数、校验、字典注入和 checkId 稳定性打牢。
  • 下一步:T-205(映射单测基线:docx 样例 + 联调样本)。

2026-07-07 T-205 映射单测基线

  • 状态:DONE
  • 变更:新增 mapping/health_record_baseline_test.go;补 docx 风格完整样例、联调样本风格脱敏样例、脏数据样例三组映射回归测试,覆盖主数据字段映射、码表转换、必填校验、码表未命中和 checkId 稳定生成。
  • 验证:go test ./mapping -count=1 通过;go test ./... 通过。
  • 决策:样本全部脱敏,不提交本地真实身份证/姓名/电话;T-205 只建立映射测试基线,不扩展创建请求结构体。
  • 下一步:T-101(osi/public.go 四个字典查询)。