34 KiB
34 KiB
执行进度记录
只追加的历史流水:每轮做了什么、跑了什么验证、遇到什么阻塞、做了什么决策。 当前目录/命令/下一步等可覆盖快照写
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.goMD5 头签名 + 单测)。
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来自 Pythonhashlib.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.goCall+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四个字典查询)。
2026-07-07 T-101 公开字典查询
- 变更:新增
osi/public.go,实现QueryGridAddress、QueryDoctors、QueryDrugs、QueryOrgs四个公开查询薄封装;补充WGDZ00001、ZRYS00001、YPML00001、CXJG00002serviceId 路由。 - 测试:先补
osi/public_test.go,覆盖四个接口的 path、serviceId、baseInfo 组装与 data 解码。 - RED:
go test ./osi -run "TestQuery(GridAddress|Doctors|Drugs|Orgs)" -count=1初次失败,缺少公开查询类型、serviceId 常量与方法。 - GREEN:
go test ./osi -run "TestQuery(GridAddress|Doctors|Drugs|Orgs)" -count=1通过。 - 验证:
go test ./osi -count=1通过。 - 验证:
go test ./...通过。 - 验证:
go build ./...通过。 - 联调:使用本地未入库脚本中的沙箱凭据和身份证,仅在临时 Go 程序内读取;先 JKDA00002 取一条档案主数据,再调用公开查询。结果:Find
code=01 count=1;责任医生code=01 count>0;机构code=01 count>0;网格code=01 count>0。未输出真实身份证、机构码、医生姓名或密钥。 - 说明:药品目录查询本次完成客户端封装和单测,T-101 验收要求未要求真实药品目录联调;后续需要用药品关键字/拼音码时再补真实样本。
2026-07-07 T-103 字典缓存
- 状态:DONE
- 变更:新增
cache/dictionary.go与cache/dictionary_test.go;建立DictionarySnapshot内存快照,支持按名称反查regionCode、manaDoctorId、manaUnitId;新增DictionaryService.Refresh,从 T-101 公开查询结果刷新内存快照,并通过可选PersistentStore保存。 - 变更:
mapping.PHISHealthRecord增加RegionName、ManaDoctorName、ManaUnitName;MapContext增加MasterDataLookup,当 PHIS 未直接提供平台码时,映射层可通过主数据快照反查补齐必填主数据。 - RED:
go test ./cache -count=1初次失败,缺少NewDictionarySnapshot、NewDictionaryService、RefreshParams、DictionarySnapshot;go test ./mapping -run TestMapHealthRecordUsesMasterDataLookupWhenCodesMissing -count=1初次失败,缺少名称字段与MasterData上下文。 - GREEN:补最小实现后,
go test ./cache -count=1通过;go test ./mapping -run TestMapHealthRecordUsesMasterDataLookupWhenCodesMissing -count=1通过。 - 验证:
go test ./cache ./mapping -count=1通过。 - 验证:
go test ./...通过。 - 验证:
go build ./...通过。 - 决策:T-103 不引入 Redis 客户端依赖,只定义可选持久化接口;持久化失败被忽略,内存快照仍刷新,满足“redis 不可用不阻断”。
- 下一步:T-206(健康档案 Create/Update + 创建请求契约)。
2026-07-07 T-206 健康档案 Create/Update(代码完成,真实写入受阻)
- 状态:BLOCKED(代码与本地验证完成;真实 create 写入平台待安全测试档案/写入授权)。
- 变更:
contract/jkda.go新增HealthRecordCreate、HealthRecordBaseInfo、HealthRecordCreateInfo、HealthRecordSaveResult;创建请求侧使用addressNumber,保留查询响应侧adressNumber。 - 变更:
osi/codes.go新增JKDA00001/JKDA00003与/jkda/create、/jkda/update路由;osi/client.go增加内部callUploadInfo,支持创建/更新把healthRecord/pastHistory/...放在uploadinfo同级节点;osi/jkda.go新增CreateHealthRecord、UpdateHealthRecord。 - 变更:
mapping.BuildHealthRecordCreate将MappedHealthRecord转为创建请求契约,保留确定性checkId与regionCode/manaDoctorId/manaUnitId,并派生createUser/createUnit。 - RED:
go test ./contract -run TestHealthRecordCreateSerializesCreateFieldNames -count=1初次失败,缺少创建请求结构体;go test ./osi -run "Test(Create|Update)HealthRecord" -count=1初次失败,缺少 create/update 方法与 serviceId;go test ./mapping -run TestBuildHealthRecordCreateUsesMappedFieldsAndCheckID -count=1初次失败,缺少构建函数。 - GREEN:补最小实现后上述三组目标测试通过。
- 验证:
go test ./contract ./osi ./mapping -count=1通过。 - 验证:
go test ./...通过。 - 验证:
go build ./...通过。 - 阻塞:未执行真实
JKDA00001create。原因是当前只有真实查询样本,没有明确的安全测试居民/身份证和写入授权;直接用现有真实样本创建/更新可能污染平台档案或触发重复建档。解除条件:提供可写入沙箱的测试居民资料,或明确授权使用某条测试数据做 create。
2026-07-08 T-208 server 模式健康档案查询端点
- 状态:DONE
- 变更:新增
handler/health_record.go(GET /api/health-record/find,回写平台完整响应,不裁字段)、handler/health_record_test.go(完整回写 + 缺标识符 400)、server.go(server 模式起 HTTP 服务 + 路由)、osi_client.go(抽出buildOSIClient共用构造);verify_jkda.go改用共用构造消除重复;main.go加-addr、server 模式真正启动服务;tasks.md/current-state.md同步。 - 验证:用户在 Windows 侧
go test ./...、go build ./...通过;go run . -mode server起服务后curl .../find?idCard=<..>返回平台完整档案 JSON。(本 WSL 离线无 go 工具链,未在本环境复跑。) - 决策:查询端点直接回写
Result.Raw(平台原始{code,message,data}),保证未建模字段不丢失;默认监听127.0.0.1:8080而非:8080,因端点返回真实档案 PII,避免绑 0.0.0.0 暴露到局域网;身份证经 URL query 传入,仅作本机查看工具,勿反代外网。 - 下一步:解 T-206 阻塞(真实 create),或按需为查询端点加鉴权后再考虑对外。
2026-07-08 看板重排(读先行:查询优先、写入后置)
- 状态:DONE(规划调整,无代码)
- 变更:
tasks.md新增 Phase Q2(其余业务线查询:T-301 体检查询 / T-302 体检端点 / T-303 老年人查询 / T-304 列表查询),把写入 T-206(BLOCKED)/T-204 明确降到 Q2 之后;里程碑加 M4=体检查询、M5=创建闭环。docs/06顶部加"★ 当前批次优先催办",把写入授权(D3)+缺失 serviceId(B1/B2/B4)+写入规则(C1/C2) 归拢成一封邮件一起催。docs/current-state.md下一步改为 T-301 起。 - 决策(全栈分析):真实 create 被厂家写入授权外部锁死,垂直切片走不通;改按读/写横切、读先行——读路径不被授权阻塞、只读零风险、且各查询响应是将来写入映射的事实侦察。T-206 创建代码保留不作废,授权到位再验收。
- 下一步:T-301 体检查询打通。
2026-07-08 T-301 体检查询打通(最近一次)
- 状态:DONE
- 变更:新增
contract/jktj.go(HealthCheckSummary 定位字段)、osi/jktj.go(LastHealthCheckJKTJLSJL00002)、osi/jktj_test.go(脱敏假数据测路径/解码/Raw/idcard 小写映射/单键校验);osi/codes.go登记 JKTJLSJL00002 + JKTJLIST00002 路由;docs/04新增 §11 体检字段清单(~260 项/7 节点),docs/01 §5.2标注各体检接口联调状态。 - 验证:真实"最近一次体检"查询已通(用户侧 Python 脚本 code=01,返回单个体检对象)。Go 侧因本环境离线无工具链未复跑,需用户
go test ./...确认编译与单测。 - 发现:① 单条 JKTJ00002
auto/jktj/query平台实测"没有url的接口配置"(未部署),auto/jktj/find待确认 → docs/06 B5。② 体检 data 为单对象(档案 find 是数组)。③ 体检身份证字段小写idcard(档案idCard)。④ 体检主键checkId(与档案幂等 checkId 同名不同义),子节点healthCheck外键指向它。 - 决策:查询只强类型化定位字段,完整内容留
Result.Raw;~260 全量字段建模留到体检 create(写入才需逐字段,避免照单样本猜 null 类型)。 - 下一步:T-302 体检 HTTP 查询端点(复用 T-208 handler 模式);或按 docs/06 催厂家确认单查/列表接口。
2026-07-08 拆分 T-305 体检名单查询、收窄 T-304
- 状态:DONE(看板+文档维护)
- 变更:从 docx 扒出 JKTJLIST00002 完整契约(checkYear/page/rows 在 baseInfo,返回人员名单+checkType 状态),记入
docs/04 §11.4;tasks.md拆出 T-305(体检已检/未检名单,契约齐全仅待沙箱部署验证,TODO 可领),把 T-304 收窄为真正缺 serviceId 的列表(档案/老年人/中医指导);scripts/query_health_check.py的 list 模式改为 docx 正确参数。 - 决策:JKTJLIST00002 契约不缺(docx 完整),不该被 B1/B2 阻塞——只差运行时确认端点是否部署,故独立成可领任务;纠正原 T-304"一刀切 BLOCKED"把能做的和真卡的混在一起。它是名单/进度接口,不含体检明细,非数据源。
- 下一步:跑 list 探针确认部署 → 若通即领 T-305 建 osi 方法;未部署则归 docs/06 B5 催厂家。
2026-07-08 T-305 体检已检/未检名单查询打通
- 状态:DONE
- 变更:
contract/jktj.go加HealthCheckPerson(名单一行 20 字段,字段名按实测校正);osi/jktj.go加ListHealthCheckPeople(JKTJLIST00002)+ListHealthCheckQuery(checkYear 必填、page/rows 默认、idCard/checkType 可选);osi/jktj_test.go加名单解码/路径/baseInfo分页/checkYear 校验测试(脱敏假数据);docs/04 §11.4校正实测字段名并标端点已部署;docs/01 §5.2标 JKTJLIST00002 联调可用。 - 验证:Python 探针
list实测code=01,返回 10 人名单(每人 checkType 状态)。Go 侧待用户go test ./...复验(本环境离线)。 - 发现:实测字段名与 docx 多处不符——
birthday(非 birthDay)、phrId(非 phrid,驼峰)、manaDoctorId(非 manadoctorId),另有 docx 未列的manaDocterName(拼写 Docter)/empiId/manaUnitText。再次印证以实测样本为准。 - 决策:名单行字段稳定且均为字符串(20 项),全部强类型化(区别于体检明细 260 项只留 Raw);单查 JKTJ00002 仍未部署,与本条无关。
- 下一步:T-302 体检 HTTP 端点;或按需把名单也暴露成 HTTP 端点。
2026-07-08 T-302 体检 HTTP 查询端点
- 状态:DONE
- 变更:新增
handler/health_check.go(GET /api/health-check/last最近一次 +/list年度名单,回写平台完整响应)、handler/health_check_test.go(脱敏假 OSI 后端测 last/list 的路径/原样回写/缺参 400);server.go注册两条体检路由并打印;抽writeRawOrError共用回写。tasks.md/docs/current-state.md同步。 - 验证:待用户
go test ./...、go build ./...复验(本环境离线无工具链)。 - 决策:端点直接回写
Result.Raw(同档案端点 T-208),完整内容不裁字段;last 按 idCard/phrid/empiId,list 按 checkYear(必填)+idCard+checkType;默认仅绑 127.0.0.1(返回真实档案/名单 PII)。 - 下一步:T-303 老年人查询探针。
2026-07-08 JKTJ00002 某人全部体检查询打通
- 状态:DONE
- 变更:
osi/codes.go登记ServiceIDJKTJQuery=JKTJ00002→/auto/jktj/query;contract/jktj.go加HealthCheckRecordSummary(驼峰 idCard、checkId 可空);osi/jktj.go加QueryHealthChecks(返回数组);handler/health_check.go加/api/health-check/all端点;server.go注册路由;osi/jktj_test.go/handler/health_check_test.go加测试(含 null checkId 场景);docs/01 §5.2、docs/04 §11.1校准。 - 验证:Python 探针实测 JKTJ00002
code=01,返回 8 条体检历史(2013–2026)。Go 侧待用户go test ./...。 - 发现(实测校准):① JKTJ00002 身份证字段是驼峰
idCard(≠ 最近一次小写idcard;体检三接口 last 独用小写);②checkId仅近年记录有值,历史记录为null(本样本仅最近 2 条有编号)——历史体检只能按checkDate定位;③ 数组元素结构同 §11.3。 - 决策:数组查询只强类型化定位字段(checkId/checkDate/idCard/personName),完整体检走 Result.Raw;单独建
HealthCheckRecordSummary(驼峰 idCard)不复用最近一次的HealthCheckSummary(小写 idcard),因平台字段大小写不一致。 - 下一步:go test 复验后提交;体检查询三接口(最近一次/全部/名单)osi+HTTP 全齐。
2026-07-08 新增 docs/07 本项目 HTTP 接口文档
- 状态:DONE
- 变更:新建
docs/07-本项目HTTP接口.md,整理 server 模式 5 个查询端点(档案 find + 体检 last/all/list)的参数/上游 serviceId/返回形态/PII 警示/通用约定;docs/README.md导航登记;CLAUDE.md文档同步表加"HTTP 端点增改 → docs/07"。 - 决策:区分两层接口文档——上游 OSI 契约以 docs/01+04(实测)为准,本项目对外接口以 docs/07 为单一事实来源;docx 反复被证明不可靠,只作参考。
- 下一步:新增端点时同步 docs/07;对外前补鉴权/日志/限流。
2026-07-09 登记 T-209 人群分类查询优化
- 状态:DONE(看板+契约文档维护)
- 来源:用户更新
scripts/query_crow_with_idcard.py,并提供本地响应样本scripts/query_crow_with_idcard.json(含真实身份证/phrId,不入库)。 - 发现:JKDA00005 实测请求路径为
/osi/api/auto/jkda/findrqbj,响应data是对象,字段含personSign、idCard、phrId;当前 Go 侧只建模personSign,且路径仍是早期/jkda/findrqbj。 - 变更:
tasks.md新增 T-209;docs/01、docs/04 §12登记实测契约和待改点。 - 下一步:实现 T-209,修正
osi路由/响应结构,并补 server 模式人群分类查询端点。
2026-07-09 T-209 人群分类查询优化
- 状态:DONE
- 变更:
osi/codes.go修正 JKDA00005 路由为/auto/jkda/findrqbj;osi.PersonSignResult补idCard、phrId字段;handler.HealthRecordHandler新增GET /api/health-record/crowd,原样回写平台响应;server.go注册新端点。 - RED:
go test ./osi -run TestFindRqbjCallsJKDA00005AndDecodesPersonSign -count=1初次失败,缺少idCard/phrId字段;go test ./handler -run TestHealthRecordCrowdReturnsRawPlatformResponse -count=1初次失败,缺少Crowdhandler。 - GREEN:补实现后上述目标测试通过。
- 验证:
go test ./...通过。 - 验证:
go build ./...通过。 - 验证:
git diff --check通过。 - 决策:HTTP 端点继续采用查询类统一策略,直接回写
Result.Raw,避免裁掉平台后续新增字段;真实样本 JSON 仍只本地留存,不提交。
2026-07-09 登记 T-210 公开查询 HTTP API
- 状态:DONE(看板+文档维护)
- 变更:
tasks.md新增 T-210,范围为把人群分类、网格地址、责任医生、药品目录、机构查询统一暴露为 server 模式 HTTP API;同步登记docs/openapi.yaml作为本项目 HTTP API 的机器可读文档。 - 决策:T-210 依赖 T-101(四类公开查询 OSI 客户端已完成)与 T-209(人群分类 HTTP 端点已存在)。实现时不再重复写 OSI 客户端,只补 handler/router、HTTP 测试、
docs/07与 OpenAPI。项目后续以内网部署为目标,但接口仍返回 PII/主数据,需在文档中明确绑定地址和鉴权边界。 - 验证:文档登记阶段运行
git diff --check;代码实现阶段再跑go test ./...、go build ./...。 - 下一步:开始 T-210,实现公开查询 HTTP API。
2026-07-09 T-210 公开查询 HTTP API
- 状态:DONE
- 变更:新增
handler/public.go与handler/public_test.go,暴露GET /api/dictionaries/grid-addresses、/doctors、/drugs、/orgs;server.go注册四个公开查询路由并打印启动提示;既有人群分类端点/api/health-record/crowd保持不变。 - 变更:同步
docs/07-本项目HTTP接口.md与docs/openapi.yaml,补网格地址、责任医生、药品目录、机构查询;更新内网部署说明,明确服务本身不内置鉴权。 - RED:
go test ./handler -run TestPublic -count=1初次失败,缺少NewPublicHandler。 - GREEN:补最小实现后
go test ./handler -run TestPublic -count=1通过。 - 验证:
go test ./...通过;go build ./...通过;python -c "import yaml; yaml.safe_load(open('docs/openapi.yaml', encoding='utf-8'))"通过;git diff --check通过。 - 决策:公开查询端点继续原样回写平台 JSON,不裁字段;
pageNo做 HTTP 层整数校验,其余查询条件按上游查询透传。项目按内网部署推进,但 API 返回主数据/PII 相关上下文,生产暴露前仍需网关鉴权和日志脱敏。 - 下一步:T-303 老年人查询探针;或继续补内网部署鉴权/访问控制任务。
2026-07-13 登记 T-303 老年人生活自理能力评估查询
- 状态:DONE(任务拆分与契约文档维护)
- 来源:厂家新增《老年人生活自理能力评估查询服务.docx》。参数表给出
POST /osi/api/auto/lnr/query、serviceId=LNRZLPG00002、idCard必填及评估数组响应字段。 - 变更:将 T-303 收窄为生活自理能力评估查询;新增 T-307 跟踪仍缺契约的中医体质辨识查询;同步 docs/01、docs/04 §13、docs/06 B1/B4 与当前快照。
- 风险:docx 请求样例错误写
LNR00004且缺uploadinfo/manageInfo,仅能以参数表和既有查询信封实施;服务路径、serviceId、字段仍须真实请求验收后确认。 - 下一步:领取 T-303,先做
contract/lnr.go、osi/lnr.go、HTTP handler 与回归测试,再以安全测试居民探针联调。
2026-07-09 T-211 药品目录分页契约修正(登记)
- 状态:DOING
- 背景:docx YPML00001 药品目录查询是分页列表——
pageNo必填、有pageSize、返回药品数组(ypxh/ypmc/ypdw/ypgg/ypjl/ycjl/jldw)。当前实现把pageNo当可选(DrugQuery.PageNo带 omitempty、handlerparseOptionalInt、docs/07 标"否"),且缺pageSize——pageNo=0会被 omitempty 丢弃,平台可能报必填错。 - 计划:
osi.DrugQuery去 pageNo omitempty + 加 PageSize;handler 缺 pageNo 返回 400 + 读 pageSize;docs/07 §8+openapi.yaml标 pageNo 必填并补 pageSize;docx 契约未联调,全程注明待厂家样本核对。 - 注意:YPML00001 从未真实联调(current-state 自述),本次按 docx 校准,pageNo 是否真必填、响应字段名待联调确认;不扩
Drug响应结构体(避免照单样本猜类型),HTTP 走 Raw 不受影响。
2026-07-09 T-211 药品目录分页契约修正(完成)
- 状态:DONE
- 变更:
osi/public.goDrugQuery.PageNo去 omitempty(确保 pageNo=0 也上送)+ 加PageSize;handler/public.goDrugs 改 pageNo 必填(新增parseRequiredInt,缺则 400)+ 读 pageSize;handler/public_test.go加"缺 pageNo→400"测试;docs/07 §8标 pageNo 必填+补 pageSize+分页说明+未联调警示;docs/openapi.yamldrugs 内联 pageNo(required)+pageSize(不动共享 pageNo,网格地址仍可选)。 - 验证: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 契约待联调。 - 下一步:联调 YPML00001 拿真实分页样本后,确认 pageNo/pageSize 真契约并补 Drug 响应字段。