docs: 初始化 chis_osi 设计文档与协作规范

- docs/: OSI 接口规范分析、旧项目架构评估、目标架构设计、字段与接口映射、实施路线图
- CLAUDE.md: 协作规则(项目认知、osi/mapping/pipeline 三层技术约束、安全/验证、提交规范)
- .gitignore: 补充项目特定忽略(config.yaml/logs/样本等)
- 随项目留存厂家 OSI 规范源材料(docx/xlsx,内部保密,仅限本私有仓库)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
ila
2026-05-30 13:10:17 +08:00
co-authored by Claude Opus 4.8
parent 18bf9a82af
commit 3498542b07
11 changed files with 1014 additions and 28 deletions
+164
View File
@@ -0,0 +1,164 @@
# CLAUDE.md
适用于 `chis_osi` 仓库的 Claude Code 协作规则。
> **当前为 pre-code 阶段**:已 git 管理,仅有设计文档与源材料,代码骨架尚未建立(见路线图阶段 0)。
---
## 会话启动
1. 读取 `docs/README.md` — 了解文档集结构与一句话结论
2. 执行 `git log --oneline -10` — 了解上次做到哪里
3. 确认当前所处阶段(见 `docs/05-实施路线图.md` 的阶段 0~6)
> 需要架构细节读 `docs/03-目标架构设计.md`;需要接口字段/码表读 `docs/01-OSI接口规范分析.md` 与 `docs/04-字段与接口映射.md`。
> 用户说"继续开发""继续上次的"时,完成以上步骤后直接接续,不重新介绍项目背景。
---
## 项目定位
**chis_osi**——对接「广东省基层医疗机构管理系统(CHIS)」厂家(和宇健康科技)提供的**官方统一对外服务接口(OSI)**,
把上游 PHIS(公卫系统)数据转换并投递到省基卫平台。
- **当前阶段**:设计完成、待编码(脚手架尚未建立,见路线图阶段 0)
- **语言/运行**:Go 1.24,单二进制双子命令(`cmd/server` 同步 API、`cmd/deliver` 投递 worker)
- **团队定位**:默认由初级程序员维护,所有改动优先保证可读、可理解、可接手,避免过度抽象
- **核心链路**:PHIS(拉取)→ 字段映射 → MD5 签名 + 统一信封 → CHIS OSI(POST `/osi/api/...`)→ 状态回写
**关键架构判断(务必牢记):**
OSI 是**无状态服务端接口**,鉴权 = 请求头 MD5 签名(`password=md5("ts=<ts>&ask=<ask>")` 32 位小写)。
参考项目 `/mnt/d/GoP/chis_upload`(逆向 Chrome F12 实现)里的 SM2 登录 / Cookie / Redis 会话 / 身份链反查 / 网页报文对齐这部分复杂度**在本项目不存在、不要引入**。
本项目核心资产是 **PHIS→OSI 表驱动字段映射层** 与 **投递流水线**(重试分类/幂等/熔断/批次报告),幂等键用 OSI 的 `checkId`。
源材料(`docs/`):`统一对外服务接口文档-.docx`(OSI 规范 V1.5.7)、`广东省基层...需要的接口.xlsx`(本期 25 个接口)。这两份是厂家标注"内部资料注意保密"的材料,仅在本私有仓库内随项目留存,不得外发或推送到公开仓库。
---
## 目录职责
> 以下为**目标**结构(见 `docs/03-目标架构设计.md` 第 3 节),多数目录尚未创建,按路线图阶段逐步建立。
| 目录 | 说明 |
|------|------|
| `cmd/server/` `cmd/deliver/` | 双入口:同步投递 API / 定时投递 worker |
| `internal/osi/` | ★ 薄客户端:签名、传输、`Call`、各业务域调用方法 |
| `internal/contract/` | ★ 校验后的接口契约(结构体 + serviceId 常量),docx 坑点的唯一修正点 |
| `internal/mapping/` | ★ PHIS→OSI 字段/字典映射 + checkId 生成(本项目核心) |
| `internal/source/phis/` | PHIS 拉取客户端 + 任务模型 + 状态回写 |
| `internal/pipeline/` | 投递编排:校验→映射→调用→分类重试→幂等→熔断→报告 |
| `internal/observ/` `internal/store/` | report log(redis 优先、文件降级)/ redis(可选)+文件存储 |
| `handler/` `router/` | server 模式对外 HTTP 接口与路由 |
| `config/` | viper 读取配置(osi / phis / redis / proxy) |
| `docs/` | 所有设计文档,与代码同等重要 |
---
## 修改原则
- 先读现有实现和相关文档,再动手;优先最小化改动范围。
- 已有实现可复用时,不新增平行实现。
- 先定位根因,再修复问题,不做只遮盖现象的补丁。
- 非任务要求,不改对外接口字段、返回结构、配置键名、文件名、编码。
- 涉及**签名逻辑、serviceId 常量、checkId 生成、码表、幂等存储**时必须保守处理——它们直接影响平台对账与重复建档。
- **不照搬 docx 字段表**:docx 有复制粘贴错误(serviceId 串台、字段名/类型不一致,见 `docs/01` 第 7 节)。以 `contract/` + 联调真实样本为准。
- 架构或字段映射发生变化时,同步更新 `docs/` 对应文件(`docs/03` 架构、`docs/04` 字段映射),不让代码改了文档没跟上。
---
## 技术约定
### 通用
- **语言**:Go 1.24,**优先标准库**,谨慎引入第三方依赖。
- **注释**:必要的中文注释,只写 WHY 不写 WHAT;重点注释业务规则不直观处(字段映射、码表、分支判定)、外部系统约束(OSI 固定字段/签名规则)、易误改的关键路径(签名、checkId、幂等)。
- **错误**:显式处理不吞错;**命名**直接表达用途,避免过度抽象。
### osi(薄客户端)
- 签名只在 `osi` 层完成,业务层无感;用 `crypto/md5` 即可,**不引入 SM2/任何加密库**。
- `ts` 取 13 位毫秒;`password` 取 32 位小写;`ask` **仅参与签名**,不进请求头、不进报文、不进日志。
- 返回判定集中在 `codes.go`:`code=="1"` 成功(注意是**字符串**);`405` 超时(可重试);其它失败。
- 传输层移植自 `chis_upload`(保留 SOCKS5/超时,**去掉 cookiejar 与网页拟态头**)。
### mapping(核心)
- 码表集中 `dict.go`,双向查表,**未命中显式报 ValidationError,绝不静默置空**。
- 映射函数为纯函数,返回结构化校验错误,便于用文档样例 + 联调样本单测。
- `checkId` 必须**确定性生成**:同一源记录重试得同一 checkId,防止平台重复建档。
- 完整度(completeLevel/perfection)**默认不本地计算**,依赖平台;联调确认需自算后再移植旧逻辑。
### pipeline / 可观测
- 重试分类:网络错误 / HTTP 5xx / 429 / `code==405` 可重试;参数错、权限错、映射校验错不可重试;退避 `2s*attempt`,最多 3 次。
- 幂等键 = `checkId`;存储 redis 优先、本地 JSON 降级。
- Redis 完全可选:启动失败不阻断(沿用 `chis_upload` 行为)。
- 一套 report log,不重建 apitrace/snapshot 多套追踪。
---
## 安全要求
- **严禁**将 `ask` 密钥、`orgCode`/`userName`/`deviceSN`、PHIS token、真实账号、含真实地址的配置提交到 git。
- `ask` 等敏感项走环境变量或部署密文,不写进仓库配置、不打印到日志。
- 配置示例用 `config.yaml.example`(占位值,不含真实地址与密钥)。
- 不提交 `logs/`、快照、抓包样本中含真实身份证/个人信息的文件。
---
## 验证要求
改动完成后做最小必要验证:
- **签名改动**:单测校验 `password` 形态(32 位小写)+ 用最简查询接口(机构查询 CXJG00002)打通真实请求。
- **映射改动**:补/跑 `mapping` 单测,用 docx 样例与联调样本对齐;确认必填/码表/格式校验生效。
- **投递流水线改动**:跑批确认批次报告字段(total/success/failed/skipped/retry)与幂等跳过、熔断行为正确。
- 至少执行 `go test ./...` 或与改动最相关的包级测试;无法验证时说明原因和风险。
---
## 文档同步要求
代码和文档同步,不允许代码改了文档没跟上。完成一组相关改动(1~3 个功能/修复/重构)后,自主判断是否同步更新 `docs/`,无需用户提醒。
| 发生什么 | 必须更新 |
|---------|---------|
| 架构或分层发生变化 | `docs/03-目标架构设计.md` |
| serviceId / 接口路径 / 字段映射 / 码表校准 | `docs/01-OSI接口规范分析.md`、`docs/04-字段与接口映射.md` |
| 联调确认了开放问题(完整度 / checkId 规则 / 缺漏接口等) | `docs/03` 第 8 节、`docs/04` 第 7 节待补清单 |
| 阶段推进或验收通过 | `docs/05-实施路线图.md` 勾选项与阶段状态 |
| 做了重要技术决策 | `docs/decisions/00N-简短描述.md`(背景 / 决策 / 原因 / 影响) |
---
## 提交规范
> 提交、推送仅在用户要求时进行。代码按每个逻辑改动单独 commit。
格式:`<type>(<scope>): <简短描述>`
| type | 用途 | | scope | 对应 |
|------|------|---|------|------|
| `feat` | 新功能 | | `osi` | 薄客户端 |
| `fix` | 修复问题 | | `mapping` | 字段/码表映射 |
| `docs` | 文档变更 | | `pipeline` | 投递流水线 |
| `refactor` | 重构(不改功能) | | `contract` | 接口契约 |
| `chore` | 构建/配置/依赖 | | `phis` | 任务源 |
| `test` | 测试相关 | | `config` `handler` … | 其余包/文档 |
```
feat(osi): 实现 MD5 头签名与统一 Call
feat(mapping): 落地健康档案字段映射与 checkId 生成
docs: 校准 jkda serviceId 并更新接口映射文档
chore: 初始化 go module 与双子命令骨架
```
---
## 提交前检查
- [ ] 未改动无关文件,未引入不必要重构或第三方依赖
- [ ] 未硬编码 `ask` 密钥、机构码、账号、PHIS token、服务器地址
- [ ] 未提交 `config.yaml`、`logs/`、含个人信息的样本
- [ ] 未留下临时代码、调试输出、未说明的 `TODO`
- [ ] serviceId / 字段映射 / 架构变更已同步更新 `docs/` 对应文件
- [ ] 重要技术决策已补 `docs/decisions/` ADR 文件
- [ ] `go test ./...` 通过(或说明未验证的原因与风险)