diff --git a/.gitignore b/.gitignore index 36b13f1..69850a1 100644 --- a/.gitignore +++ b/.gitignore @@ -174,3 +174,4 @@ cython_debug/ # PyPI configuration file .pypirc +reverse_file/ \ No newline at end of file diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..4d42b74 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,51 @@ +# AGENTS.md + +> Codex / AI coding agent 的仓库级入口。进入本仓库后,先读本文,再进入 `docs/00-ai-start-here.md`。 + +## 项目定位 + +`chisup` 是一个基卫 CHIS 上报数据后端服务,第一版目标是提供 API 给第三方提交体检数据,并将数据转换为 CHIS 体检保存接口所需格式后提交到 CHIS。 + +当前不是完整代码仓库,处于文档和逆向资料整理阶段。已有 `reverse_file/` 中的 CHIS 前端脚本、schema 和 HAR;`D:\hans\chupd\chis\login_client_v2.py` 可作为 CHIS 登录链路参考,`reverse_file/20260704_query_health_check.har` 可作为体检详情只读查询参考。 + +## 必读顺序 + +每次开始工作前,按顺序读取: + +1. `README.md`:了解项目定位和文档集合。 +2. `docs/README.md`:了解文档导航。 +3. `docs/00-ai-start-here.md`:理解 AI 开发入口流程。 +4. `docs/05-coding-rules.md`:理解编码和安全纪律。 +5. `docs/current-state.md`:确认当前仓库现实。 +6. `docs/06-tasks.md`:领取本轮唯一任务。 +7. 与当前任务相关的具体文档。 + +如果用户提供新的 CHIS 请求样例、schema 或业务规则,先把事实同步到相关文档,再进入实现。 + +## 工作规则 + +- 不臆造 CHIS 字段、接口、错误码、登录参数和加密规则。 +- 不把真实账号、密码、Cookie、内网地址、token 写入代码或文档样例。 +- CHIS 逆向资料仅作为事实来源之一;最终以可运行请求、用户提供代码和实际响应为准。 +- view 层保持薄,业务转换放在 service / mapper,CHIS 网络调用放在 client / auth。 +- 第三方调用鉴权、CHIS 账号凭证、Redis 会话缓存、幂等和日志脱敏是必须重点关注的边界。 +- 任务完成必须有真实验证命令或明确说明当前无法验证的原因。 + +## 当前优先级 + +1. 建立 Flask 3.0.3 + Python 3.8 最小可运行地基。 +2. 迁移 CHIS 登录链路,并用账号信息查询确认会话有效。 +3. 设计 Redis 会话缓存和失效重登策略。 +4. 先跑通体检详情只读查询,验证登录、会话、加密和通用 request。 +5. 建立第三方体检上报 API 合约、参数校验和幂等。 +6. 实现体检数据转换和 CHIS 保存提交。 + +## 验证 + +当前尚未有生产代码,暂以文件和文档检查为主: + +```powershell +Get-ChildItem -Recurse -File +``` + +项目初始化后,必须把真实安装、测试和启动命令同步到 `docs/03-tech-stack.md`、`docs/05-coding-rules.md` 和 `docs/current-state.md`。 diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..51d9a90 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,11 @@ +# CLAUDE.md + +> Claude Code 的仓库级薄入口。进入本仓库后,先读本文,再读 [AGENTS.md](AGENTS.md)。 + +本仓库的权威 agent 规则、文档入口、工作边界和验证方式统一维护在 [AGENTS.md](AGENTS.md)。 + +Claude Code 处理本仓库任务时: + +1. 先读取 [AGENTS.md](AGENTS.md)。 +2. 再按 `AGENTS.md` 的要求进入 [docs/00-ai-start-here.md](docs/00-ai-start-here.md) 和相关文档。 +3. 不在本文重复维护任务流程、编码规则或文档清单,避免和 `AGENTS.md` 漂移。 diff --git a/README.md b/README.md index dff7b36..3d76d32 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,45 @@ # chisup -chis upload python \ No newline at end of file +基卫 CHIS 上报数据项目。项目目标是提供稳定的后端 API,供第三方系统提交体检数据;`chisup` 负责校验、转换、维护 CHIS 登录会话,并把符合 CHIS 接口格式的数据提交到基卫 CHIS。 + +当前仓库处于 MVP 起步阶段:已有 `reverse_file/` 中的 CHIS 逆向资料,还未初始化 Flask 生产代码。当前已确认可参考 `D:\hans\chupd\chis\login_client_v2.py` 迁移 CHIS 登录链路,public key 由配置提供;保存上报前先实现只读体检详情查询来验证登录、会话、加密和通用请求。 + +## 文档入口 + +| 文档 | 作用 | +| --- | --- | +| [AGENTS.md](AGENTS.md) | Codex / AI coding agent 的仓库级入口 | +| [CLAUDE.md](CLAUDE.md) | Claude Code 薄入口,指向 `AGENTS.md` | +| [tasks.md](tasks.md) | 根目录任务总览,详细任务以 `docs/06-tasks.md` 为准 | +| [progress.md](progress.md) | 执行历史流水,只追加记录 | +| [docs/README.md](docs/README.md) | 项目文档导航 | +| [docs/00-ai-start-here.md](docs/00-ai-start-here.md) | AI 开发入口、阅读顺序和任务领取规则 | +| [docs/01-vision.md](docs/01-vision.md) | 项目愿景、价值和非目标 | +| [docs/02-requirements.md](docs/02-requirements.md) | MVP 需求和验收标准 | +| [docs/03-tech-stack.md](docs/03-tech-stack.md) | 技术栈、运行命令和待定项 | +| [docs/04-architecture.md](docs/04-architecture.md) | 架构设计、模块职责、数据流和风险 | +| [docs/05-coding-rules.md](docs/05-coding-rules.md) | 编码纪律和验证规则 | +| [docs/06-tasks.md](docs/06-tasks.md) | 可逐步交付的任务看板 | +| [docs/api.md](docs/api.md) | 对第三方 API 与内部模块合约 | +| [docs/current-state.md](docs/current-state.md) | 当前代码现实、可运行命令和下一步 | +| [docs/clean-state-checklist.md](docs/clean-state-checklist.md) | 每轮结束前的收尾检查 | + +## 当前事实 + +- Python 版本目标:Python 3.8。 +- Web 框架目标:Flask 3.0.3。 +- 计划使用 Redis 保存 CHIS 会话缓存。 +- 当前已有资料:`reverse_file/` 下的 CHIS 前端脚本、schema 和 HAR。 +- 当前已有查询 HAR:`reverse_file/20260704_query_health_check.har`,包含 `getHMNIListOfHTML` 和 `getCheckInfoDetail`。 +- 当前尚未确认:最终项目目录、依赖文件、数据库、部署方式、第三方鉴权方式、仅凭 `healthCheck` 反查查询详情所需参数的链路。 + +## 推荐开工方式 + +新一轮开发先读: + +1. [AGENTS.md](AGENTS.md) +2. [docs/00-ai-start-here.md](docs/00-ai-start-here.md) +3. [docs/current-state.md](docs/current-state.md) +4. [docs/06-tasks.md](docs/06-tasks.md) + +编码前优先完成任务看板中的 Phase 0,先建立最小可运行 Flask 地基,再接入 CHIS 登录与会话验证,随后跑通只读体检详情查询,最后再做保存上报。 diff --git a/docs/00-ai-start-here.md b/docs/00-ai-start-here.md new file mode 100644 index 0000000..0d6a32e --- /dev/null +++ b/docs/00-ai-start-here.md @@ -0,0 +1,73 @@ +# AI 开发入口 + +> 给 AI coding agent 的项目入口。这里负责导航和流程,硬性编码规则见 [05-coding-rules.md](05-coding-rules.md)。 + +## 一句话定位 + +`chisup` 是基卫 CHIS 体检数据上报中间服务。MVP 先完成稳定后端 API:先用 CHIS 只读体检详情查询验证登录、会话、加密和通用请求,再接入第三方体检数据上报与 CHIS 保存。 + +## 必读顺序 + +每次开始写代码前,按这个顺序建立上下文: + +1. [../AGENTS.md](../AGENTS.md):仓库级规则。 +2. [01-vision.md](01-vision.md):为什么做、为谁做、什么不做。 +3. [02-requirements.md](02-requirements.md):MVP 要什么、怎么算达成。 +4. [03-tech-stack.md](03-tech-stack.md):既定技术选型。 +5. [04-architecture.md](04-architecture.md):系统结构、职责划分、数据流和风险。 +6. [05-coding-rules.md](05-coding-rules.md):写代码前必须遵守的规则。 +7. [06-tasks.md](06-tasks.md):领取本轮唯一任务。 +8. [../progress.md](../progress.md):历史执行记录、验证结果、阻塞点和关键决策。 +9. [current-state.md](current-state.md):当前代码现实、可运行命令、下一步任务。 + +## 固定开工流程 + +1. `pwd`:确认在 `D:\PythonP\chisup`。 +2. 读 [../progress.md](../progress.md) 和 [current-state.md](current-state.md)。 +3. 查看当前文件清单和最近改动;如果未来接入 git,先看 `git status` 和 `git log --oneline -5`。 +4. 若已有项目代码,运行标准验证命令;如果还未初始化代码,先完成 Phase 0 任务。 +5. 从 [06-tasks.md](06-tasks.md) 领取第一个 `TODO` 且依赖均完成的任务。 +6. 开始前把任务标为 `DOING`,完成并验证后标为 `DONE`。 +7. 结束前更新 [current-state.md](current-state.md),向 [../progress.md](../progress.md) 追加记录,并检查 [clean-state-checklist.md](clean-state-checklist.md)。 + +## MVP 边界 + +MVP 只做: + +- 第三方体检上报 API。 +- 第三方请求鉴权、参数校验和幂等。 +- CHIS 登录会话管理:优先复用 Redis 中有效会话,失效后重登。 +- 用账号信息查询或等价接口确认 CHIS 会话有效。 +- 体检详情只读查询:先用 `healthCheck + phrId + idCard + checkDate` 验证 CHIS 通道。 +- 体检数据到 CHIS 保存请求的最小转换闭环。 +- 通用 CHIS request 封装、错误码映射、日志脱敏。 + +MVP 不做: + +- 管理后台。 +- 多业务类型全面覆盖。 +- 批量导入 UI。 +- 绕过 CHIS 权限、验证码、风控或审计。 +- 把第三方数据直接落入 CHIS 数据库。 + +## 常见任务该看哪里 + +做 API:先看 [api.md](api.md),再看 [04-architecture.md](04-architecture.md)。 + +做 CHIS 登录:先看 `D:\hans\chupd\chis\login_client_v2.py`,再看 HAR 中 `myRoles`、`myApps` 链路;public key 从配置读取,不硬编码。 + +做 CHIS 只读查询:先看 `reverse_file/20260704_query_health_check.har`,优先实现 `getHMNIListOfHTML` 和 `getCheckInfoDetail`;当前不能假设只传 `healthCheck` 就能查详情。 + +做体检转换:先看 `reverse_file/chis.application.hc.script.HealthCheckHtmlForm.js` 的 `getSaveRequest` 和 `saveToServer`,再看 schema 文件,最后补充 mapper 测试。 + +做 Redis 会话:先看 [04-architecture.md](04-architecture.md) 的会话对象设计,不要只保存裸 cookie。 + +## 当前验证命令 + +当前尚未初始化代码,文档检查命令: + +```powershell +Get-ChildItem -Recurse -File +``` + +项目初始化后,把真实命令同步到 [03-tech-stack.md](03-tech-stack.md)、[05-coding-rules.md](05-coding-rules.md) 和 [current-state.md](current-state.md)。 diff --git a/docs/01-vision.md b/docs/01-vision.md new file mode 100644 index 0000000..1dd5fcd --- /dev/null +++ b/docs/01-vision.md @@ -0,0 +1,41 @@ +# 项目愿景 + +## 一、核心目标 + +`chisup` 要解决第三方体检系统向基卫 CHIS 上报数据时,登录、会话、格式转换、错误处理和重复提交都难以稳定维护的问题。 + +> 让第三方系统只按约定提交业务数据,由 `chisup` 负责 CHIS 会话和 CHIS 接口格式细节。 + +它不是 CHIS 替代系统,也不是前端自动化脚本,而是一个面向第三方系统的后端中间服务。 + +## 二、目标用户 + +- 第三方业务系统:通过 API 提交体检数据,不直接理解 CHIS 前端接口细节。 +- 项目维护人员:维护 CHIS 登录、会话、字段映射和问题排查。 +- 医卫业务实施人员:通过稳定接口减少重复录入和手工导入成本。 + +## 三、产品原则 + +- 核心闭环优先:先跑通单条体检上报,再扩展更多业务类型。 +- 真实接口优先:字段、接口、错误码以实际 CHIS 请求和响应为准。 +- 安全优先:账号、密码、Cookie、身份证号、体检数据必须脱敏处理。 +- 会话复用优先:不要每次请求都登录 CHIS;优先复用有效 Redis 会话。 +- 可追踪:每次上报要能通过 trace_id 查到入参摘要、转换结果、CHIS 请求结果和错误原因。 +- 可维护:view、service、mapper、CHIS client、auth、repository 边界清晰。 + +## 四、核心价值主张 + +| 价值点 | 说明 | +| --- | --- | +| 降低接入成本 | 第三方不需要直接适配 CHIS 复杂请求格式 | +| 提高稳定性 | 统一处理 CHIS 登录、会话失效、重登、错误翻译 | +| 避免重复提交 | 通过幂等键控制第三方重试导致的重复体检记录 | +| 便于排查 | 统一日志、错误码和请求流水,减少线上问题定位成本 | + +## 五、不做什么(非目标) + +- 不绕过 CHIS 的账号权限、角色、机构和审计规则。 +- 不保存真实明文 CHIS 密码到代码、文档或日志。 +- 不直接写 CHIS 数据库。 +- 不在 MVP 做可视化管理后台。 +- 不一次性覆盖 CHIS 全部业务模块;先完成体检上报闭环。 diff --git a/docs/02-requirements.md b/docs/02-requirements.md new file mode 100644 index 0000000..7793ce5 --- /dev/null +++ b/docs/02-requirements.md @@ -0,0 +1,87 @@ +# 需求 + +> 本文只描述要什么与怎么算达成。技术方案、数据结构、字段定义见 [架构设计](04-architecture.md)。 + +## 一、业务现状 + +| 项 | 状态 | +| --- | --- | +| 用户 | 第三方系统需要把体检数据提交到基卫 CHIS | +| 数据 | 已有 CHIS 体检前端脚本、schema 和 HAR;第三方最终请求体待定 | +| 现有系统 | CHIS 是外部系统;本项目负责中间 API 和请求转发 | +| 约束 | 涉及 CHIS 账号权限、居民个人信息、体检隐私数据、内网接口和会话安全 | + +## 二、用户角色 + +- 第三方系统:调用 `chisup` API 提交体检数据,接收统一成功或失败结果。 +- `chisup` 服务:校验、转换、维护 CHIS 会话、提交 CHIS。 +- CHIS 账号持有人 / 机构:提供合法账号、角色、机构权限。 +- 运维 / 开发人员:排查上报失败、会话失效、字段转换错误。 + +## 三、功能清单 + +### 第一版 MVP + +| 功能 | 用户能做什么 | 优先级 | +| --- | --- | --- | +| 第三方鉴权 | 通过 app_key / token 等方式调用上报接口 | P0 | +| 单条体检上报 | 提交一条体检数据并获得统一结果 | P0 | +| CHIS 会话管理 | 系统复用 Redis 会话,失效时自动重登 | P0 | +| 会话有效性确认 | 通过账号信息查询或等价接口确认登录有效 | P0 | +| 体检详情只读查询 | 根据体检主键和必要关联参数查询 CHIS 体检详情 | P0 | +| 体检数据转换 | 将第三方输入转换为 CHIS `hcData` 等保存结构 | P0 | +| 通用 CHIS request | 统一处理超时、错误码、登录失效、日志脱敏 | P0 | +| 幂等控制 | 第三方重试不会重复创建体检记录 | P0 | + +### 后续迭代 + +| 功能 | 描述 | 阶段 | +| --- | --- | --- | +| 更多业务类型 | 高血压、糖尿病、老年人等专项随访或档案业务 | V2 | +| 管理后台 | 查看上报流水、失败重试、机构配置 | V2 | +| 异步队列 | 大批量上报、失败重试、削峰 | V2 | +| 字典管理 | CHIS 字典同步、映射配置可维护 | V3 | + +## 四、核心用户故事(MVP) + +1. 作为第三方系统,我可以携带合法鉴权信息提交体检数据。 +2. 如果 CHIS 账号密码错误或没有权限,系统会提前返回清晰错误,不继续提交业务数据。 +3. 如果 Redis 中已有有效 CHIS 会话,系统直接复用,不重复登录。 +4. 如果 CHIS 会话失效,系统会重登一次并重试当前请求。 +5. 作为开发和运维人员,我可以先用只读体检详情查询验证 CHIS 登录、加密、cookie 和通用请求是否可用。 +6. 如果同一业务流水重复提交,系统返回同一处理结果或明确提示重复,不在 CHIS 产生重复记录。 +7. 当字段校验失败、CHIS 接口失败或网络超时时,第三方能收到统一错误码和 trace_id。 + +## 五、验收标准(MVP) + +- 第三方鉴权:未授权请求被拒绝,响应不泄露内部细节。 +- 参数校验:缺少身份证号、体检日期、CHIS 账号引用、业务流水号等关键字段时返回参数错误。 +- CHIS 登录:给定有效账号时可获取会话;无效账号提前返回登录失败。 +- 会话复用:同一账号在 Redis 会话有效时,不重复执行完整登录链路。 +- 会话失效:CHIS 返回未登录或账号信息查询失败时,自动清理缓存并重登一次。 +- 体检详情查询:给定 `healthCheck + phrId + idCard + checkDate` 时,能查询 `getHMNIListOfHTML` 和 `getCheckInfoDetail`,且不产生写入副作用。 +- 数据转换:最小体检样例能生成 CHIS 保存请求所需的 `hcData` 和相关数据块。 +- CHIS 提交:能通过通用 request 提交到 CHIS 的目标接口,并返回 CHIS 业务结果。 +- 幂等:相同幂等键重复提交不会重复创建记录。 +- 日志:日志包含 trace_id、接口、耗时、结果,不包含明文密码、Cookie、完整身份证号。 + +## 六、范围边界与决策 + +| 问题 | 决策 | +| --- | --- | +| 第一版平台 | 后端 API 服务 | +| 是否需要账号 | 第三方调用需要鉴权;CHIS 调用需要合法 CHIS 账号会话 | +| 第一版范围 | 单条体检上报闭环 | +| 暂不支持 | 管理后台、批量 UI、直接数据库写入、绕过权限 | + +## 七、待确认 / 风险点 + +- CHIS 登录细节:已有 `D:\hans\chupd\chis\login_client_v2.py` 可参考;该代码依赖 Django,迁移到 Flask 时只复用登录链路和加密算法。 +- 会话有效性接口:已有 `getLanderInfo` 代码可参考,仍需在 Flask 项目中实现并验证。 +- CHIS public key:由配置文件或环境变量提供,不从代码硬编码。 +- 体检详情查询:已有 `reverse_file/20260704_query_health_check.har`;第一版查询需要调用方传 `healthCheck + phrId + idCard + checkDate`。 +- 仅凭体检 id 查询:缺少从 `healthCheck` 反查 `phrId/idCard/checkDate` 的已验证链路,需后续验证。 +- 第三方请求体:字段、字典、幂等键、账号引用方式待定。 +- CHIS 保存接口:最终 `serviceId`、`method`、`schema`、`module` 和请求体需要用真实请求验证。 +- 账号安全:是否允许第三方每次传 CHIS 账号密码需要业务确认;推荐平台配置账号,第三方只传机构或账号引用。 +- 隐私合规:体检数据和身份证号属于敏感信息,日志、存储、传输必须脱敏和受控。 diff --git a/docs/03-tech-stack.md b/docs/03-tech-stack.md new file mode 100644 index 0000000..04b489e --- /dev/null +++ b/docs/03-tech-stack.md @@ -0,0 +1,50 @@ +# 技术栈(Tech Stack) + +> “用什么”的统一速查表。未定项必须标为待定,不让 agent 在代码里自行决定。 + +## 一、技术栈一览 + +| 维度 | 选型 | 状态 | 理由 / 说明 | +| --- | --- | --- | --- | +| 运行时 | Python 3.8 | 已定 | 用户指定 | +| Web 框架 | Flask 3.0.3 | 已定 | 用户指定,适合轻量 API 服务 | +| 数据校验 | 待定,建议 Pydantic v1 或 Marshmallow | 待定 | Python 3.8 下需注意版本兼容 | +| HTTP 客户端 | 待定,建议 `requests.Session` | 待定 | CHIS 会话 cookie 管理简单稳定 | +| Redis 客户端 | 待定,建议 `redis-py` | 待定 | 保存 CHIS 会话、幂等和短期状态 | +| SM2 加密 | 待定,建议 `gmssl` | 待定 | 需兼容 `hans_chis.sm2.sm2_encrypt` 的 `CryptSM2(mode=0)` 行为 | +| 数据库 | 待定 | 待定 | MVP 可先只用 Redis;上报流水可能需要 MySQL / SQLite / PostgreSQL | +| 第三方鉴权 | 待定,建议 app_key + HMAC 或 Bearer Token | 待定 | 不建议第三方直接裸传 CHIS 账号密码 | +| 测试 | pytest | 建议 | 适合 mapper、client、service 单元测试 | +| 部署 | 待定,建议 gunicorn / waitress + systemd / Windows 服务 | 待定 | 取决于部署环境 | + +## 二、决策记录与演进 + +- Flask 3.0.3 + Python 3.8 已定,但 Python 3.8 生命周期已结束;如果部署环境允许,未来建议评估 Python 3.10+。 +- Redis 是会话缓存核心,不建议把 CHIS 会话保存在进程内存。 +- CHIS public key 从配置文件或环境变量读取;当前不依赖 `/chis/logon/publicKey` 动态获取。 +- CHIS 登录代码来自 Django 项目参考实现,迁移到 Flask 时只复用登录链路、SM2 算法和请求形状,不复用 Django model/cache。 +- 当前不引入异步队列,先跑通同步单条上报闭环;批量和重试队列放到 V2。 +- 当前不引入管理后台,先保证 API、会话和转换稳定。 + +## 三、构建与运行命令 + +当前尚未初始化项目代码,命令待 T-001 补齐。 + +| 用途 | 命令 | +| --- | --- | +| 安装依赖 | 待定 | +| 本地开发 | 待定 | +| 测试 | 待定 | +| 格式化 / 静态检查 | 待定 | + +当前可用文档检查: + +```powershell +Get-ChildItem -Recurse -File +``` + +## 四、依赖纪律 + +- 新增依赖前先说明用途、替代方案和 Python 3.8 兼容性。 +- 和 CHIS 登录、SM2/RSA/AES 加密相关的依赖必须由真实登录代码驱动,不要凭 HAR 猜;当前 SM2 参考 `hans_chis.sm2.sm2_encrypt`。 +- 不允许在代码或 `.env.example` 中写真实 CHIS 地址、账号、密码、Cookie。 diff --git a/docs/04-architecture.md b/docs/04-architecture.md new file mode 100644 index 0000000..85722ef --- /dev/null +++ b/docs/04-architecture.md @@ -0,0 +1,219 @@ +# 架构设计 + +> 本文讲系统结构、职责划分、数据模型、技术难点和开发顺序。具体技术选型见 [技术栈](03-tech-stack.md)。 + +## 一、系统结构 + +```text +第三方系统 + | + | HTTPS JSON + v +Flask API / middleware + | + | 参数校验、鉴权、幂等 + v +Application service + | + | 查询编排 / 上报编排 / 标准业务模型 + v +Mapper / transformer + | + | CHIS 保存请求模型 + v +CHIS client + auth manager + | + | cookies / session cache + v +Redis + | + v +基卫 CHIS *.jsonRequest / 登录接口 +``` + +## 二、职责划分 + +**API / view** + +- 接收第三方请求。 +- 完成第三方鉴权、trace_id、基础参数校验。 +- 调用 application service。 +- 返回统一响应。 +- 不写 CHIS 字段映射和登录细节。 + +**middleware** + +- 可以负责第三方鉴权、trace_id、请求体大小限制、日志上下文。 +- 不建议每个请求无脑登录 CHIS。 +- 如果做 CHIS 会话准备,也应调用 `ChisSessionManager.ensure_session()`,由 session manager 决定复用或重登。 + +**application service** + +- 编排单条体检上报流程。 +- 编排 CHIS 只读查询验证流程。 +- 处理幂等查询、业务校验、调用 mapper、调用 CHIS client。 +- 将 CHIS 错误翻译为本项目统一错误。 + +**mapper / transformer** + +- 将第三方输入转换为内部标准模型。 +- 将内部标准模型转换为 CHIS 请求体。 +- 管理字段默认值、字典映射、日期格式、空值策略。 +- 重点参考 `HealthCheckHtmlForm.js` 中 `getSaveRequest` 和 `saveToServer` 的行为。 + +**CHIS auth manager** + +- 负责登录 CHIS、获取角色 / 应用 / 会话上下文。 +- 负责查询当前账号信息或等价接口,判断会话是否有效。 +- 负责 Redis 会话缓存、清理和重登。 +- 登录链路参考 `D:\hans\chupd\chis\login_client_v2.py`,但不能原样依赖 Django model/cache。 +- CHIS public key 从 Flask 配置或环境变量读取,不从代码硬编码。 + +**CHIS client** + +- 封装 `*.jsonRequest` 和其他 CHIS HTTP 请求。 +- 自动携带会话 cookie 和必要 header。 +- 处理超时、重试、登录失效、错误码、日志脱敏。 +- 先用 `getLanderInfo`、`getEncryType`、`getHMNIListOfHTML` 等只读接口验证通道,再接入保存接口。 + +**Redis repository** + +- 保存 CHIS 会话对象。 +- 保存幂等键和处理结果摘要。 +- 可保存短期锁,避免同一账号并发重登。 + +## 三、建议项目结构 + +```text +chisup/ +├── app/ +│ ├── __init__.py +│ ├── api/ +│ │ └── health_check.py +│ ├── middleware/ +│ ├── services/ +│ │ ├── health_check_query.py +│ │ └── health_check_submit.py +│ ├── mappers/ +│ │ └── health_check.py +│ ├── chis/ +│ │ ├── auth.py +│ │ ├── client.py +│ │ ├── crypto.py +│ │ ├── session_store.py +│ │ └── errors.py +│ ├── repositories/ +│ ├── validators/ +│ └── config.py +├── tests/ +├── docs/ +├── reverse_file/ +├── requirements.txt +└── README.md +``` + +## 四、核心数据对象 + +### 4.1 第三方上报请求 + +具体字段待定,建议至少包含: + +| 字段 | 说明 | +| --- | --- | +| `request_id` | 第三方业务流水号,用于幂等 | +| `account_ref` | CHIS 账号或机构配置引用;不推荐直接传明文密码 | +| `person.id_card` | 居民身份证号,日志必须脱敏 | +| `check_date` | 体检日期 | +| `health_check` | 体检主体数据 | +| `source` | 第三方来源系统 | + +### 4.2 Redis CHIS 会话对象 + +建议结构: + +```json +{ + "base_url": "CHIS_BASE_URL_ALIAS", + "uid": "CHIS_USER_ID", + "role_id": "CHIS_ROLE_ID", + "manage_unit": "CHIS_MANAGE_UNIT", + "cookies": {}, + "login_at": "2026-07-04T00:00:00+08:00", + "expires_at": "2026-07-04T02:00:00+08:00", + "last_validated_at": "2026-07-04T00:10:00+08:00" +} +``` + +不要保存明文密码。确需保存账号凭证时,应使用安全配置或密钥管理,并在文档中明确加密和权限边界。 + +### 4.3 CHIS 体检保存请求 + +从逆向脚本可确认体检保存不是单表直传,至少涉及: + +- `hcData` +- 生活方式数据 +- 查体数据 +- 辅助检查数据 +- 健康评价 / 指导数据 +- 用药、住院、非免疫规划接种等列表数据 + +最终字段以真实 CHIS 请求和 schema 验证为准。 + +### 4.4 CHIS 体检详情查询请求 + +已确认 `reverse_file/20260704_query_health_check.har` 中的体检详情查询需要: + +```json +{ + "serviceId": "chis.healthCheckService", + "method": "execute", + "serviceAction": "getHMNIListOfHTML", + "schema": "chis.application.hc.schemas.HC_HealthCheck", + "body": { + "healthCheck": "体检主键", + "phrId": "健康档案号", + "idCard": "身份证号" + } +} +``` + +检查报告信息查询需要: + +```json +{ + "serviceId": "chis.healthCheckService", + "serviceAction": "getCheckInfoDetail", + "method": "execute", + "body": { + "idCard": "身份证号", + "checkDate": "体检日期" + } +} +``` + +注意:当前资料不能证明“只传 `healthCheck` 就能查详情”。若外部 API 要支持只传体检 id,需要先验证如何由 `healthCheck` 反查 `phrId`、`idCard`、`checkDate`、`empiId`、`createUser`。 + +## 五、关键技术难点 + +| 难点 | 说明 | 应对 | +| --- | --- | --- | +| CHIS 登录链路 | 可能涉及公钥、加密、角色、应用、机构上下文 | 等用户提供现有代码后接入,先写 auth 边界 | +| 会话有效性 | cookie 存在不代表 CHIS 会话仍有效 | 用账号信息查询接口确认,失败则清理缓存并重登 | +| 只传体检 id 查询详情 | `getHMNIListOfHTML` 还需要 `phrId` 和 `idCard` | 先要求调用方传全参数,后续验证反查链路 | +| 体检字段转换 | CHIS 前端保存逻辑复杂,数据块多 | 先做最小样例 mapper,逐步补字段测试 | +| 幂等 | 第三方重试可能导致重复体检记录 | 使用 `source + request_id` 或业务唯一键保存结果 | +| 隐私与日志 | 涉及身份证号、体检数据、账号凭证 | 统一脱敏,敏感字段禁止落日志 | +| CHIS 接口变化 | 逆向接口可能因版本变化失效 | client 层集中封装,转换层有测试样例 | + +## 六、推荐开发顺序 + +1. 初始化 Flask 项目骨架和测试命令。 +2. 接入 CHIS 登录代码,验证能获取有效会话。 +3. 实现账号信息查询 / 会话有效性确认。 +4. 实现 Redis 会话缓存、锁和失效重登。 +5. 实现通用 CHIS `*.jsonRequest` client。 +6. 先跑通体检详情只读查询,验证登录、会话、角色/机构、SM2 加密和错误处理。 +7. 定义第三方体检上报 API 和统一响应。 +8. 实现最小体检 mapper。 +9. 通过通用 CHIS request 提交最小样例。 +10. 补幂等、日志脱敏、错误码和测试。 diff --git a/docs/05-coding-rules.md b/docs/05-coding-rules.md new file mode 100644 index 0000000..ec7974b --- /dev/null +++ b/docs/05-coding-rules.md @@ -0,0 +1,67 @@ +# 编码规则(Coding Rules) + +> 每次写代码前先读完本文件。与技术细节冲突时,以 [技术栈](03-tech-stack.md) / [架构设计](04-architecture.md) 的事实为准;与范围冲突时,以 [需求](02-requirements.md) 为准。 + +## 0. 黄金法则 + +1. 不臆造:CHIS 字段、接口、登录参数、错误码,不确定就查证或询问。 +2. 守范围:MVP 只做体检上报闭环。 +3. 照架构:view、service、mapper、CHIS client、auth、repository 分层清楚。 +4. 小步改:一次只解决一个任务,不夹带无关重构。 +5. 可验证:改完必须能运行对应测试或说明无法验证原因。 + +## 1. 安全纪律 + +- 绝不把真实账号、密码、Cookie、token、内网地址写入代码、文档示例或测试快照。 +- 日志必须脱敏:身份证号、姓名、手机号、账号、Cookie、密码、体检明细都要受控。 +- 第三方传来的 CHIS 密码如果无法避免,只能在请求生命周期中使用,不得写日志,不得明文持久化。 +- Redis 中不保存明文密码。 +- 不绕过 CHIS 权限、角色、机构、验证码、风控或审计。 + +## 2. 事实来源纪律 + +- CHIS 登录事实以后续用户提供代码为准。 +- CHIS 体检保存结构以真实 HAR、`HealthCheckHtmlForm.js` 和 schema 验证为准。 +- 不能因为字段名“看起来像”就写入 mapper。 +- 数据结构变化必须同步更新 [04-architecture.md](04-architecture.md)、[api.md](api.md) 和 [current-state.md](current-state.md)。 + +## 3. 分层纪律 + +- API / view 不写字段转换和 HTTP 细节。 +- middleware 不直接拼 CHIS 请求。 +- service 负责流程编排,不负责底层 HTTP。 +- mapper 只做数据转换,不访问 Redis 和 CHIS。 +- CHIS client 不理解第三方业务字段。 +- repository 只负责存取,不写业务判断。 + +## 4. 错误处理 + +- 所有外部请求必须设置 timeout。 +- CHIS 登录失败、会话失效、权限不足、参数错误、网络超时要有不同错误码。 +- CHIS 返回未登录时最多自动重登一次,避免无限递归。 +- 任何失败响应都要带 trace_id。 + +## 5. 测试与验证 + +项目初始化后至少建立: + +- mapper 单元测试:输入第三方样例,输出 CHIS 请求体。 +- auth 测试:登录成功、登录失败、会话有效、会话失效。 +- client 测试:超时、CHIS 错误码、未登录重登。 +- API 测试:鉴权失败、参数失败、幂等重复、成功提交。 + +当前文档阶段可运行: + +```powershell +Get-ChildItem -Recurse -File +``` + +代码阶段的真实命令待 T-001 补齐。 + +## 6. 绝不 + +- 绝不为了跑通而吞掉 CHIS 错误。 +- 绝不把未验证字段标为必然正确。 +- 绝不在没有幂等策略时开放生产上报。 +- 绝不擅自删除 `reverse_file/` 中的逆向资料。 +- 绝不使用破坏性 git 或文件命令清理用户文件。 diff --git a/docs/06-tasks.md b/docs/06-tasks.md new file mode 100644 index 0000000..426cfdb --- /dev/null +++ b/docs/06-tasks.md @@ -0,0 +1,74 @@ +# 任务看板(Tasks) + +> 把 MVP 拆成小步、可独立交付的任务。每轮只做一个任务。 + +## 使用规则 + +1. 每轮只领取第一个状态为 `TODO` 且依赖均为 `DONE` 的任务。 +2. 开始前把任务状态改为 `DOING`。 +3. 完成、自测并记录证据后,把任务状态改为 `DONE`。 +4. 完成后向 [../progress.md](../progress.md) 追加记录,并覆盖更新 [current-state.md](current-state.md)。 +5. 结束前检查 [clean-state-checklist.md](clean-state-checklist.md)。 + +## 状态图例 + +`TODO` 待开始 · `DOING` 进行中 · `DONE` 已完成并验收 · `BLOCKED` 受阻 + +## Phase 0 · 项目地基 + +| ID | 任务 | 依赖 | 验收要点 | 状态 | +| --- | --- | --- | --- | --- | +| T-001 | 初始化 Flask 项目骨架 | - | Python 3.8 可创建虚拟环境;Flask 3.0.3 依赖固定;本地 health check API 可启动;真实命令同步到技术栈和当前状态 | TODO | +| T-002 | 建立基础配置与目录 | T-001 | 目录符合架构文档;配置从环境变量读取;无真实密钥 | TODO | +| T-003 | 建立最小测试框架 | T-001 | pytest 可运行;至少有 health check 或 app factory 测试 | TODO | + +## Phase 1 · CHIS 登录与会话 + +| ID | 任务 | 依赖 | 验收要点 | 状态 | +| --- | --- | --- | --- | --- | +| T-101 | 迁移 CHIS 登录链路 | T-002 | 参考 `D:\hans\chupd\chis\login_client_v2.py`;登录逻辑进入 `app/chis/auth.py` 或等价模块;public key 从配置读取;账号密码不落日志;失败返回明确错误 | TODO | +| T-102 | 接入账号信息查询验证会话 | T-101 | 能用已有 cookie 查询当前账号信息;失败可判断会话无效 | TODO | +| T-103 | 实现 Redis 会话缓存 | T-102 | 会话对象包含 cookies、账号、角色/机构、过期时间;有效会话复用;无效会话清理 | TODO | +| T-104 | 实现失效重登策略 | T-103 | CHIS 返回未登录时清缓存、重登一次、重试一次;不会无限重试 | TODO | + +## Phase 2 · CHIS 只读查询验证 + +> 在保存上报前,先用只读查询验证登录、cookie、角色/机构上下文、SM2 加密和通用 `*.jsonRequest` 是否可用。 + +| ID | 任务 | 依赖 | 验收要点 | 状态 | +| --- | --- | --- | --- | --- | +| T-201 | 实现通用 CHIS jsonRequest client | T-104 | 自动携带会话;处理 timeout、CHIS 错误和未登录;能调用 `getLanderInfo` 与 `getEncryType` | TODO | +| T-202 | 实现体检详情查询 client | T-201 | 参考 `reverse_file/20260704_query_health_check.har`;支持 `healthCheck + phrId + idCard` 调 `getHMNIListOfHTML`;支持 `idCard + checkDate` 调 `getCheckInfoDetail` | TODO | +| T-203 | 跑通只读查询 spike | T-202 | 登录后能查询体检详情;验证结果写入 `progress.md`;不产生 CHIS 写入副作用 | TODO | +| T-204 | 验证仅凭体检 id 查询的前置参数来源 | T-203 | 明确是否能用 `healthCheck` 反查 `phrId/idCard/checkDate/empiId/createUser`;如不能,文档中确认第一版查询 API 需要调用方传全参数 | TODO | + +## Phase 3 · 第三方上报 API + +| ID | 任务 | 依赖 | 验收要点 | 状态 | +| --- | --- | --- | --- | --- | +| T-301 | 定义第三方鉴权方式 | T-003 | 未授权请求返回统一 401/403;密钥通过环境变量或配置加载 | TODO | +| T-302 | 定义体检上报请求模型 | T-301 | 请求字段、必填校验、错误响应写入 `api.md`;测试覆盖参数缺失 | TODO | +| T-303 | 实现幂等键存取 | T-302 | 相同 `source + request_id` 重复提交不会重复执行 CHIS 保存 | TODO | + +## Phase 4 · 体检转换与 CHIS 提交 + +| ID | 任务 | 依赖 | 验收要点 | 状态 | +| --- | --- | --- | --- | --- | +| T-401 | 建立内部体检标准模型 | T-302 | 第三方输入先转换为内部模型;字段不直接耦合 CHIS 请求 | TODO | +| T-402 | 实现最小 CHIS 体检 mapper | T-401 | 参考 `reverse_file/20260702_442525195910165439_create_health_check.har`;生成包含 `hcData` 的最小保存请求;有样例测试 | TODO | +| T-403 | 跑通单条体检上报闭环 | T-303, T-402, T-201 | 第三方请求进入后能转换并提交 CHIS,返回统一结果和 trace_id | TODO | + +## Phase 5 · 稳定性与收尾 + +| ID | 任务 | 依赖 | 验收要点 | 状态 | +| --- | --- | --- | --- | --- | +| T-501 | 补齐错误码和日志脱敏 | T-403 | 常见错误有统一 code;日志不包含明文敏感信息 | TODO | +| T-502 | 完整 MVP 验收 | T-501 | `02-requirements.md` 的 P0 验收全部通过 | TODO | +| T-503 | 部署运行文档 | T-502 | 新环境能按文档安装、配置、启动、验证 | TODO | + +## Backlog + +- 管理后台。 +- 异步队列和失败重试。 +- 更多 CHIS 业务类型。 +- 字典同步和配置化 mapper。 diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..92bfc48 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,33 @@ +# 项目文档导航 + +## 一句话定位 + +`chisup` 是一个面向第三方业务系统的基卫 CHIS 体检数据上报中间服务,第一版先跑通“第三方提交体检数据 -> 校验与幂等 -> 获取有效 CHIS 会话 -> 转换为 CHIS 体检保存格式 -> 提交 CHIS -> 返回统一结果”的闭环。 + +## 文档导航 + +- [../AGENTS.md](../AGENTS.md):Codex / 通用 AI coding agent 的仓库级入口。 +- [../CLAUDE.md](../CLAUDE.md):Claude Code 薄入口,具体规则以 `AGENTS.md` 为准。 +- [../tasks.md](../tasks.md):根目录任务总览。 +- [../progress.md](../progress.md):执行历史流水,只追加记录任务执行、验证、阻塞和决策。 +- [AI 开发入口](00-ai-start-here.md):agent 每次开始工作的入口、阅读顺序和任务领取规则。 +- [项目愿景](01-vision.md):为什么做、为谁做、产品原则、非目标。 +- [需求](02-requirements.md):MVP 要什么、用户故事、验收标准。 +- [技术栈](03-tech-stack.md):Python / Flask / Redis 等选型与命令。 +- [架构设计](04-architecture.md):系统结构、模块职责、数据流和关键风险。 +- [编码规则](05-coding-rules.md):AI 写代码前必须遵守的硬约束。 +- [任务看板](06-tasks.md):按依赖拆分的小任务,agent 每轮只做一个。 +- [API 合约](api.md):第三方接口、错误格式、内部模块合约。 +- [当前实现状态](current-state.md):当前代码现实、可运行命令和下一步。 +- [收尾检查清单](clean-state-checklist.md):会话结束前逐项检查。 + +## 事实来源 + +当前可用事实来源: + +- `reverse_file/20260702_442525195910165439_create_health_check.har`:CHIS 登录、查询、体检相关请求样例。 +- `reverse_file/chis.application.hc.script.HealthCheckHtmlForm.js`:CHIS 前端体检表单保存逻辑。 +- `reverse_file/chis.application.hc.schemas.*.sc`:体检相关 schema 逆向资料。 +- 后续用户提供的其他项目 CHIS 登录代码和账号信息查询代码。 + +不要把未验证的猜测写入实现。 diff --git a/docs/api.md b/docs/api.md new file mode 100644 index 0000000..f7286cc --- /dev/null +++ b/docs/api.md @@ -0,0 +1,222 @@ +# API / 模块合约 + +> 本文定义第三方 API、统一响应和内部模块合约的目标形状。实现前可细化,但不要在代码里另起一套不兼容接口。 + +## 通用约定 + +- 传输:HTTPS JSON。 +- 编码:UTF-8 JSON。 +- 时间格式:`YYYY-MM-DD` 用于业务日期,时间戳使用 ISO 8601。 +- 第三方鉴权:待定,推荐 `Authorization: Bearer ` 或 `X-App-Key` + `X-Signature`。 +- 每个响应包含 `trace_id`。 + +成功响应: + +```json +{ + "ok": true, + "trace_id": "TRACE_ID", + "data": {} +} +``` + +错误响应: + +```json +{ + "ok": false, + "trace_id": "TRACE_ID", + "error": { + "code": "bad_request", + "message": "请求参数不正确" + } +} +``` + +## 第三方 API + +### `POST /api/v1/health-checks/query-detail` + +用途:查询 CHIS 中某次体检详情。第一版用于验证 CHIS 登录、Redis 会话、通用请求和查询链路。 + +第一版请求要求调用方传全参数: + +```json +{ + "account_ref": "chis-account-alias", + "healthCheck": "0000000000481718", + "phrId": "44162511100102877", + "idCard": "440000********1234", + "checkDate": "2014-06-05" +} +``` + +说明: + +- `healthCheck + phrId + idCard` 用于调用 CHIS `getHMNIListOfHTML`。 +- `idCard + checkDate` 用于调用 CHIS `getCheckInfoDetail`。 +- 当前资料不能证明只传 `healthCheck` 就能查完整详情;后续任务会验证反查链路。 + +成功响应: + +```json +{ + "ok": true, + "trace_id": "TRACE_ID", + "data": { + "healthCheck": "0000000000481718", + "detail": {}, + "check_info": {} + } +} +``` + +### `POST /api/v1/health-checks/submit` + +用途:提交单条体检数据到 CHIS。 + +请求示例(字段待后续业务样例细化): + +```json +{ + "request_id": "third-party-unique-id", + "source": "third-party-system", + "account_ref": "chis-account-alias", + "person": { + "id_card": "440000********1234", + "name": "张三" + }, + "check_date": "2026-07-04", + "health_check": { + "height": 170, + "weight": 65 + } +} +``` + +成功响应: + +```json +{ + "ok": true, + "trace_id": "TRACE_ID", + "data": { + "request_id": "third-party-unique-id", + "idempotent": false, + "chis_result": { + "code": 200, + "message": "success" + } + } +} +``` + +重复提交响应: + +```json +{ + "ok": true, + "trace_id": "TRACE_ID", + "data": { + "request_id": "third-party-unique-id", + "idempotent": true, + "chis_result": { + "code": 200, + "message": "success" + } + } +} +``` + +## 错误码 + +| code | HTTP | 说明 | +| --- | --- | --- | +| `unauthorized` | 401 | 第三方鉴权失败 | +| `forbidden` | 403 | 第三方无权限使用该账号或机构 | +| `bad_request` | 400 | 请求体格式错误或必填字段缺失 | +| `invalid_health_check_data` | 400 | 体检字段校验失败 | +| `missing_health_check_query_params` | 400 | 查询体检详情缺少 `healthCheck`、`phrId`、`idCard` 或 `checkDate` | +| `chis_login_failed` | 502 | CHIS 登录失败 | +| `chis_session_invalid` | 502 | CHIS 会话无效且重登失败 | +| `chis_request_failed` | 502 | CHIS 业务接口失败 | +| `chis_timeout` | 504 | CHIS 请求超时 | +| `idempotency_conflict` | 409 | 相同幂等键对应不同请求体 | + +## 内部模块合约 + +### `ChisSessionManager.ensure_session(account_ref)` + +输入: + +```python +account_ref: str +``` + +输出: + +```python +ChisSession( + cookies=dict, + uid=str, + role_id=str | None, + manage_unit=str | None, + expires_at=datetime, +) +``` + +职责: + +- 优先读取 Redis 有效会话。 +- 会话不存在或验证失败时登录 CHIS。 +- 登录成功后缓存会话。 +- 不返回明文密码。 + +### `ChisCrypto.sm2_encrypt(public_key, raw_text)` + +职责: + +- 使用配置中的 CHIS public key 加密密码和时间戳 `d`。 +- 兼容已有 `hans_chis.sm2.sm2_encrypt` 行为:`gmssl.sm2.CryptSM2(mode=0)`,返回带 `04` 前缀的十六进制密文。 +- 不记录明文和密文到普通业务日志。 + +### `HealthCheckQueryClient.get_detail(session, health_check, phr_id, id_card)` + +输出:CHIS `getHMNIListOfHTML` 的标准化结果。 + +职责: + +- 组装 `chis.healthCheckService / getHMNIListOfHTML` 请求。 +- 不做第三方鉴权。 +- 不保存数据。 + +### `HealthCheckQueryClient.get_check_info(session, id_card, check_date)` + +输出:CHIS `getCheckInfoDetail` 的标准化结果。 + +职责: + +- 组装 `chis.healthCheckService / getCheckInfoDetail` 请求。 +- 身份证号日志脱敏。 + +### `HealthCheckMapper.to_chis_payload(input_model, session_context)` + +输入:内部体检标准模型和 CHIS 会话上下文。 + +输出:CHIS `*.jsonRequest` 请求体。 + +职责: + +- 字段映射。 +- 字典值转换。 +- 默认值和空值处理。 +- 不访问网络,不访问 Redis。 + +### `ChisClient.json_request(session, payload)` + +职责: + +- 发送 CHIS `*.jsonRequest`。 +- 携带 cookie 和 header。 +- 处理 timeout、CHIS 错误、未登录。 +- 返回标准化 CHIS 响应对象。 diff --git a/docs/clean-state-checklist.md b/docs/clean-state-checklist.md new file mode 100644 index 0000000..3645d94 --- /dev/null +++ b/docs/clean-state-checklist.md @@ -0,0 +1,15 @@ +# 干净收尾检查清单 + +> 每轮会话结束前逐项过一遍,确保仓库处于“下一轮无需人工修复即可直接开工”的状态。 + +收尾前确认: + +- [ ] 标准启动路径仍可用;如果尚未初始化代码,已如实记录为待建。 +- [ ] 标准验证 / smoke 仍可运行,结果如实。 +- [ ] 本轮执行记录已追加到 [../progress.md](../progress.md)。 +- [ ] [06-tasks.md](06-tasks.md) 任务状态真实反映 `DONE` 与未验证的边界。 +- [ ] [current-state.md](current-state.md) 已覆盖更新到当前快照。 +- [ ] 没有半成品改动处于未记录状态;如有,已写明 `BLOCKED` / `PARTIAL` 和原因。 +- [ ] 没有真实账号、密码、Cookie、token、内网敏感地址进入代码或文档。 + +任意一项不满足,就先补到满足,再结束会话。 diff --git a/docs/current-state.md b/docs/current-state.md new file mode 100644 index 0000000..0ff2f84 --- /dev/null +++ b/docs/current-state.md @@ -0,0 +1,68 @@ +# 当前实现状态 + +> 本文是可覆盖的当前快照,记录代码与任务看板的现实状态。历史执行流水追加到 [../progress.md](../progress.md)。 + +## 当前快照 + +- 日期:2026-07-04 +- 阶段:MVP 起步 / 文档与逆向资料整理 +- 技术栈:目标为 Python 3.8、Flask 3.0.3、Redis;代码尚未初始化 +- 生产代码:暂无 +- 测试:暂无 +- 数据 / 资料:`reverse_file/` 下已有 CHIS HAR、前端脚本和 schema;`D:\hans\chupd\chis\login_client_v2.py` 可作为登录链路参考 +- 标准启动路径:待 T-001 初始化后补齐 +- 标准验证路径:当前仅文档文件检查 +- 当前 blocker:无硬阻塞;后续实现需要把 Django 登录代码迁移为 Flask 版本,并通过配置提供 CHIS public key + +## 当前目录要点 + +| 路径 | 状态 | 说明 | +| --- | --- | --- | +| `docs/` | 已有 | 项目规范化文档 | +| `reverse_file/` | 已有 | CHIS 逆向资料,当前重要事实来源 | +| `reverse_file/20260704_query_health_check.har` | 已有 | 体检详情只读查询 HAR,包含 `getHMNIListOfHTML` 和 `getCheckInfoDetail` | +| `D:\hans\chupd\chis\login_client_v2.py` | 外部参考 | CHIS 登录、SM2 加密、角色选择、cookie 拼接、`getLanderInfo` 会话验证 | +| `app/` | 待建 | Flask 应用代码 | +| `tests/` | 待建 | 测试目录 | +| `requirements.txt` | 待建 | Python 依赖 | + +## 任务看板状态 + +任务状态以 [06-tasks.md](06-tasks.md) 为准。 + +- 已完成:DOC-001 建立 harness coding 项目文档。 +- 正在进行:无。 +- 下一个可领取任务:T-001 初始化 Flask 项目骨架。 + +## 已确认技术事实 + +- CHIS public key 可通过配置文件或环境变量提供。 +- 登录链路参考 `login_client_v2.py`:`myRoles` -> 选择 `责任医生助理` / `责任医生` -> `myApps` -> 拼接 cookie。 +- SM2 加密参考 `hans_chis.sm2.sm2_encrypt`:`gmssl.sm2.CryptSM2(mode=0)`,返回带 `04` 前缀密文。 +- 会话验证可用 `chis.myPageService / getLanderInfo`。 +- 体检详情查询第一版可用 `healthCheck + phrId + idCard` 调 `getHMNIListOfHTML`,用 `idCard + checkDate` 调 `getCheckInfoDetail`。 +- 当前不能证明只传 `healthCheck` 就能查完整详情。 + +## 当前可运行内容 + +```powershell +Get-ChildItem -Recurse -File +``` + +## 开始编码前检查 + +1. 读 [../AGENTS.md](../AGENTS.md)。 +2. 读 [00-ai-start-here.md](00-ai-start-here.md)。 +3. 读 [05-coding-rules.md](05-coding-rules.md)。 +4. 从 [06-tasks.md](06-tasks.md) 领取第一个 `TODO` 且依赖均完成的任务。 +5. 将该任务状态改为 `DOING` 后再改代码。 + +## 维护规则 + +当实际代码状态发生变化时,同步更新本文件: + +- 新增或移动入口文件。 +- 初始化框架或模块。 +- 任务从 `TODO` 进入 `DOING` 或 `DONE`。 +- 新增可运行命令。 +- 发现文档和代码现实不一致。 diff --git a/progress.md b/progress.md new file mode 100644 index 0000000..5cb7f06 --- /dev/null +++ b/progress.md @@ -0,0 +1,45 @@ +# 执行进度记录 + +> 本文件是只追加的历史流水,用来记录任务执行过程、验证命令、阻塞点和关键决策。 +> 当前目录、当前命令、下一个可领取任务等可覆盖快照,写入 [docs/current-state.md](docs/current-state.md)。 + +## 职责边界 + +- `docs/06-tasks.md`:任务看板,维护任务状态、依赖和验收要点。 +- `progress.md`:历史流水,只追加记录每轮执行发生了什么。 +- `docs/current-state.md`:当前快照,可覆盖更新仓库现实、可运行命令和下一步。 + +## 记录格式 + +每完成或中断一轮任务,在文件末尾追加一条记录: + +```markdown +## YYYY-MM-DD T-编号 任务名 + +- 状态:DONE / BLOCKED / PARTIAL +- 变更:修改了哪些文件或模块 +- 验证:运行的真实命令和结果 +- 阻塞:如有,写明原因和需要谁决策 +- 决策:如有,记录本轮确定的关键取舍 +- 下一步:建议下一个任务 ID 或待确认事项 +``` + +## 执行记录 + +## 2026-07-04 DOC-001 建立 harness coding 项目文档 + +- 状态:DONE +- 变更:新增根目录入口文档和 `docs/` 项目文档。 +- 验证:已执行 `Get-ChildItem -Recurse -File | Select-Object FullName,Length | Sort-Object FullName`、`rg` 检查 Markdown 链接和关键占位 / 敏感词;发现并修正根目录任务编号漂移。 +- 阻塞:无。 +- 决策:当前文档只记录已确认事实;CHIS 登录、会话有效性、字段转换细节等待后续代码和样例补充。 +- 下一步:T-001 初始化 Flask 项目骨架。 + +## 2026-07-04 DOC-002 更新 CHIS 登录与只读查询验证路线 + +- 状态:DONE +- 变更:更新 `docs/06-tasks.md`、`docs/04-architecture.md`、`docs/api.md`、`docs/02-requirements.md`、`docs/current-state.md`、`docs/00-ai-start-here.md`、`docs/03-tech-stack.md`、`README.md` 和 `tasks.md`。 +- 验证:已执行 `Get-ChildItem -Recurse -File`、`rg` 检查任务编号、查询 HAR、public key、登录代码引用和 Markdown 链接;发现并修正 `AGENTS.md` 中过时的“后续补充登录代码”描述。 +- 阻塞:无。 +- 决策:public key 由配置提供;`D:\hans\chupd\chis\login_client_v2.py` 作为登录链路参考但不能原样依赖 Django;保存上报前新增只读体检详情查询阶段;第一版详情查询需要 `healthCheck + phrId + idCard + checkDate`,不假设只传体检 id 即可查询。 +- 下一步:T-001 初始化 Flask 项目骨架。 diff --git a/tasks.md b/tasks.md new file mode 100644 index 0000000..a9e83b0 --- /dev/null +++ b/tasks.md @@ -0,0 +1,29 @@ +# chisup 任务总览 + +> 根目录任务总览。详细可执行任务、依赖和验收标准以 [docs/06-tasks.md](docs/06-tasks.md) 为准。 + +## 当前阶段 + +MVP 起步。当前仓库已具备逆向资料和项目文档,尚未初始化 Flask 代码。 + +## 近期任务 + +| ID | 任务 | 状态 | +| --- | --- | --- | +| T-001 | 初始化 Flask 项目骨架 | TODO | +| T-002 | 建立基础配置与目录 | TODO | +| T-003 | 建立最小测试框架 | TODO | +| T-101 | 接入用户提供的 CHIS 登录代码 | TODO | +| T-102 | 接入账号信息查询验证会话 | TODO | +| T-103 | 实现 Redis 会话缓存 | TODO | +| T-201 | 实现通用 CHIS jsonRequest client | TODO | +| T-202 | 实现体检详情查询 client | TODO | +| T-203 | 跑通只读查询 spike | TODO | +| T-301 | 定义第三方鉴权方式 | TODO | +| T-403 | 跑通单条体检上报闭环 | TODO | + +## 使用规则 + +- 每次只领取 `docs/06-tasks.md` 中第一个 `TODO` 且依赖均完成的任务。 +- 完成任务后更新 `docs/06-tasks.md`、`docs/current-state.md`,并向 `progress.md` 追加执行记录。 +- 不把根目录 `tasks.md` 当作唯一任务看板。