Files
chis_osi/progress.md
T

129 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 执行进度记录
> 只追加的历史流水:每轮做了什么、跑了什么验证、遇到什么阻塞、做了什么决策。
> 当前目录/命令/下一步等可覆盖快照写 [`docs/current-state.md`](docs/current-state.md),不在本文重复。
> 任务状态以 [`tasks.md`](tasks.md) 为准。
## 记录格式
```markdown
## 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` 全量码表)。