Files
hms/docs/superpowers/specs/2026-05-03-project-analysis-brainstorm-design.md
iven d378e154c4
Some checks failed
CI / rust-check (push) Has been cancelled
CI / rust-test (push) Has been cancelled
CI / frontend-build (push) Has been cancelled
CI / security-audit (push) Has been cancelled
docs: 全项目深度分析与多专家组头脑风暴报告
覆盖 5 个专家视角(架构/安全/前端/质量/管理),
数据经实际代码库校正,产出 22 项优先级行动矩阵。
2026-05-03 19:01:27 +08:00

415 lines
18 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.
# HMS 健康管理平台 — 全项目深度分析与多专家组头脑风暴
> 日期: 2026-05-03 | 类型: 分析报告 | 数据截止: commit 554 | 状态: 草稿
**TL;DR:** HMS 项目整体健康度 B+。架构边界满分,安全基础扎实,文档体系完善。核心风险:前端测试 <5%、55% 事件孤立、审计整改率 8%、73 个未提交文件。建议立即止血P0→ 本周补短板P1→ 本月治本P2
---
## 1. 背景与目标
### 为什么做这次分析
HMS 项目经过 3 周密集开发554 次提交41 份设计规格已进入功能基本完整的阶段。2026-04-30 完成的全系统审计发现 25 个问题2 CRITICAL + 3 HIGH + 8 MEDIUM + 12 LOW但审计后 3 天整改率仅 8%。此时需要一个全面的「体检」来:
1. 识别系统性风险而非单点问题
2. 从多维度(架构/安全/前端/质量/管理)交叉验证
3. 建立清晰的优先级行动矩阵
### 分析范围
| 维度 | 覆盖范围 |
|------|---------|
| 后端架构 | 17 Rust crates / ~87k 行 / 484 源文件 |
| 前端 Web | 199 文件113 TSX + 86 TS |
| 微信小程序 | 113 文件 / 40 页面 / 5 TabBar |
| 数据库 | 103 迁移 / 77+ 表 |
| 文档体系 | 12 页 wiki + 41 specs + 38 plans + 18 discussions |
### 方法论
- **静态分析:** 文件大小、代码模式搜索、依赖图梳理
- **模式识别:** 重复代码、缺失测试、不一致的命名
- **多专家视角:** 5 个虚拟专家组从不同角度审查同一代码库
- **数据来源:** Cargo.toml / git log / Grep 搜索 / Wiki 内容 / 审计报告
---
## 2. 项目全景扫描
### 2.1 规模与复杂度
| 维度 | 数据 | 评估 |
|------|------|------|
| Rust 代码 | ~87k 行 / 17 crates / 484 源文件 | 中大型单体,模块边界清晰 |
| Web 前端 | 199 文件 (113 TSX + 86 TS) | 中等规模API 层完整 |
| 微信小程序 | 113 文件 / 40 页面 / 5 TabBar | 功能丰富,分包合理 |
| 数据库 | 103 迁移 / 77+ 表 | 高频 schema 迭代 |
| API 路由 | 328 (8 公开 + 320 受保护) | 全面的业务覆盖 |
| 测试 | 772 后端 + 11 前端 | 后端尚可,前端极低 |
| 事件系统 | 25 类型 / 44 发布 / 14 消费者 | 设计精良但有孤立事件 |
| 设计文档 | 41 specs / 38 plans | 文档驱动,管理有序 |
| Git 历史 | 554 次提交 | AI 辅助密集开发 |
### 2.2 架构评分矩阵
| 评估维度 | 得分 (1-5) | 说明 |
|----------|:---------:|------|
| 模块边界 | ⭐⭐⭐⭐⭐ | 零循环依赖crates 间仅依赖 erp-core |
| 安全姿态 | ⭐⭐⭐⭐☆ | Argon2 + AES-256-GCM + RLS + 审计哈希链,限流失败模式待改进 |
| 错误处理 | ⭐⭐⭐⭐⭐ | 统一 AppError + 跨 crate 转换 + HTTP 映射 |
| 事件系统 | ⭐⭐⭐⭐☆ | Outbox + 死信 + 幂等,但 14 个孤立事件无消费者 |
| 前端架构 | ⭐⭐⭐⭐☆ | API/Store/Hook 三层分离,但零 i18n、低测试覆盖 |
| 代码质量 | ⭐⭐⭐⭐☆ | 4 个 TODO、无 FIXME/HACK但存在 6 个千行文件 |
| 测试覆盖 | ⭐⭐⭐☆☆ | 后端 772 测试尚可,前端 <5%、小程序 0% |
| 文档完整性 | ⭐⭐⭐⭐☆ | 12 页 wiki + 41 specs但 wiki 数据存在不一致 |
| 运维成熟度 | ⭐⭐⭐☆☆ | Docker + 原生双轨但不同步,单分支开发,大量未提交文件 |
---
## 3. 专家组 1架构与基础设施
**成员画像:** Rust 系统架构师 + 数据库工程师 + DevOps 工程师
### 3.1 模块依赖分析
**依赖结构:** 所有 16 个 crate 形成以 `erp-core` 为底座的星型依赖图。`erp-server` 是唯一的组合根,依赖所有业务 crate。每个业务 crateauth / config / workflow / message / health / ai / dialysis / plugin**只依赖 erp-core**,不存在横向依赖。
**结论:** 依赖图干净,零循环依赖,具备未来拆分为微服务的前置条件。当前单体架构合理,无需急于拆分。
**关注点:** `erp-server` 依赖全部 crate任何变更都触发完整重编译。`erp-health/module.rs`1130 行路由注册)和 `erp-message/module.rs`1054 行)是路由注册的单文件瓶颈。
### 3.2 数据库迁移治理
**现状:** 21 天内产生 100 个迁移(日均 5 个),其中单次健康表迁移达 1532 行(`m20260423_000042`)。
**风险:**
- 超大迁移在生产环境执行失败时,回滚成本极高
- 高频迭代表明 schema 尚未稳定
- `testing.md` 仍写着"迁移记录应为 50 条"(实际已 100 条)
**建议:**
1. 建立迁移文件大小上限(单文件 < 500 行)
2. 每个 Phase 结束后冻结 schema后续走 ALTER 而非重建
3. 生产环境迁移前必须 dry-run 验证
**优先级:** P2
### 3.3 事件系统补全
**现状:** 25 个事件类型中 14 个无消费者(**55% 孤立率**)。`erp-health/event.rs` 828 行集中了所有事件处理器注册逻辑,且零测试覆盖。
**核心风险:** 事件孤立率超过 50% 意味着大量事件发布是无效操作 — 写入数据库、消耗存储、但无人消费。更危险的是可能掩盖业务流程断裂。
**建议:**
1. 对 14 个孤立事件逐一评估:删除无效事件 / 实现缺失消费者
2.`erp-health/event.rs` 补充单元测试(至少覆盖每个消费者的核心路径)
3. 建立事件注册表每个事件必须关联至少一个消费者CLAUDE.md 铁律已在但未执行)
**优先级:** P1 — 事件是模块间通信的核心,孤立事件 = 功能缺失
## 4. 专家组 2安全与合规
**成员画像:** 安全工程师 + 医疗合规专家 + 隐私保护专家
### 4.1 生产安全配置审计
| 项目 | 状态 | 风险 |
|------|------|------|
| JWT 密钥 | 启动时强制检查 `__MUST_SET_VIA_ENV__` | ✅ 安全 |
| PII 加密 | AES-256-GCM + KEK 层级 + 开发模式拒绝生产 | ✅ 安全 |
| 密码哈希 | Argon2 + 随机 salt | ✅ 安全 |
| PostgreSQL RLS | 所有表启用 + 严格策略 | ✅ 安全 |
| 审计日志 | 哈希链防篡改 | ✅ 安全 |
| 限流失败模式 | Redis 不可用时默认 **fail-open** | ⚠️ 高风险 |
| SSE Token | 通过 query parameter 传递 JWT | ⚠️ 中风险 |
| AI API 密钥 | `api_key = ""` 空字符串(非强制占位符) | ⚠️ 中风险 |
| SQL 注入 | `sanitize_identifier()` + 参数化查询 | ✅ 安全 |
**关键建议:**
1. **P0 — 限流 fail-close** 生产环境必须设置 `ERP__RATE_LIMIT__FAIL_CLOSE=true`,否则 Redis 宕机 = 无限流
2. **P1 — SSE Token 安全:** 改用短期一次性 ticket 替代 JWT query param避免 token 出现在日志/历史记录
3. **P1 — AI 密钥统一:** 与 JWT 密钥一样使用 `__MUST_SET_VIA_ENV__` 占位符模式
4. **P2 — 审计日志写入:** fire-and-forget 模式可能导致静默丢失,改为带重试队列
### 4.2 医疗数据合规性
**已有能力:**
- PII 加密体系完善KEK → DEK → 数据加密 + HMAC 盲索引)
- PostgreSQL RLS 已在所有表启用
- 审计日志实现哈希链防篡改
- 多租户隔离通过 JWT 中间件 + `tenant_id` 列过滤
**缺口:**
| 缺口 | 影响 | 优先级 |
|------|------|--------|
| 小程序知情同意页面缺失 | 医疗合规底线,后端 consent 实体存在但前端完全空白 | P1 |
| 数据保留策略缺失 | 无自动化数据过期/匿名化机制 | P2 |
| 访问日志粒度不足 | `audit_logs` 记录 API 调用但不记录具体访问了哪些患者数据 | P3 |
## 5. 专家组 3前端工程与用户体验
**成员画像:** 前端架构师 + UX 研究员 + 测试工程师
### 5.1 测试覆盖率分析
**前端测试现状Web + 小程序):**
| 层面 | 文件数 | 测试文件数 | 覆盖率 |
|------|--------|-----------|--------|
| Web 页面 | 40+ | 0 | 0% |
| Web Store | 6 | 0 | 0% |
| Web Hook | 9 | 2 | ~22% |
| Web API | 30+ | 1 | ~3% |
| Web 组件 | 10 | 1 | ~10% |
| 小程序页面 | 40 | 0 | 0% |
| 小程序服务 | 25+ | 0 | 0% |
**已有的 E2E 覆盖:**
- Web13 个 Playwright spec患者旅程、预约、随访、体征、告警等核心流程
- 小程序4 个 automator spec商城、健康查看、积分、体征录入
**核心判断:** 前端测试覆盖率 <5% 是项目最大的质量风险。后端有 772 个测试保障,但前端 163 个文件几乎裸跑。E2E 测试慢且脆弱,不能替代单元测试 — 任何重构都可能引入不可检测的回归。
**建议:**
1. **P1 — Store 测试:** 6 个 Zustand Store 是状态管理核心,每个至少 10 个测试
2. **P1 — API 契约测试:** 30+ API 模块验证 URL / Method / 参数序列化
3. **P2 — 关键 Hook 测试:** `usePaginatedData``usePermission``useApiRequest`
4. **P3 — 小程序测试:** 从 BLE 管理器和安全存储工具开始
### 5.2 国际化评估
**现状:** 整个项目零 i18n — 所有 UI 字符串硬编码中文,无 i18n 框架。
**影响评估:**
- 短期:不影响 — 目标用户就是中文用户
- 中期:如有国际医疗机构客户,改造成本巨大
- 长期:取决于商业策略
**建议:** 不急于实施,但提取 `antd.locale(zhCN)``dayjs.locale('zh-cn')` 为可配置入口,建立防腐层。优先级 P4。
### 5.3 组件质量与大文件
**Web 前端大文件(>500 行):**
| 文件 | 行数 | 问题 | 建议 |
|------|------|------|------|
| Organizations.tsx | 622 | 组织树+部门树+岗位三合一 | 拆为 OrgTree + DeptTree + PositionPanel |
| ArticleEditor.tsx | 554 | 富文本+图片上传+表单 | 拆为 ArticleForm + ImageUploader |
| MainLayout.tsx | 554 | 菜单+侧边栏+头部+面包屑 | 拆为 Sidebar + Header + Breadcrumb |
| AppointmentList.tsx | 518 | 列表+筛选+创建弹窗 | 拆为 AppointmentFilter + AppointmentForm |
| VitalSignsChart.tsx | 485 | 多系列图表 | 拆为 ChartConfig + DataTransformer |
**正面发现:**
-`console.log` 残留
- 零硬编码 mock 数据
- API 层与页面层分离良好
- Zustand Store 职责清晰,无 god store
## 6. 专家组 4代码质量与技术债
**成员画像:** 资深工程师 + 代码审查专家
### 6.1 后端热点文件治理
**千行以上文件(按风险排序):**
| 文件 | 行数 | 风险 | 说明 |
|------|------|------|------|
| `erp-health/service/points_service.rs` | 1863 | 🔴 | 积分业务核心,所有积分逻辑集中 |
| `erp-plugin/manifest.rs` | 1781 | 🟡 | 插件清单解析,变更频率低 |
| `erp-plugin/dynamic_table.rs` | 1768 | 🟡 | DDL 生成,含安全防护 |
| `erp-plugin/data_service.rs` | 1693 | 🟡 | 插件通用 CRUD |
| `erp-health/module.rs` | 1130 | 🟠 | 路由注册瓶颈 |
| `erp-health/service/stats_service.rs` | 1117 | 🟡 | 统计服务 |
| `erp-health/service/patient_service.rs` | 1111 | 🟠 | 患者核心业务tracing 已补全20 条) |
| `erp-health/service/health_data_service.rs` | 986 | 🟠 | 健康数据核心 |
| `erp-health/service/action_inbox_service.rs` | 930 | 🟡 | Action inbox |
**建议拆分策略:**
- `points_service.rs``points_account` + `points_rule` + `points_exchange` + `points_checkin`
- `patient_service.rs``patient_crud` + `patient_family` + `patient_tag` + `patient_export`
- `module.rs` (health) → 按子域拆路由组
**优先级:** P2 — 在下一次大改动时顺带重构
### 6.2 前端错误处理统一化
**重复模式18+ 文件):**
```typescript
// 被 18+ 个页面文件重复的内联错误提取
(err as { response?: { data?: { message?: string } } })?.response?.data?.message
```
**已有的正确方案:** `api/client.ts` 中的 `handleApiError()` 函数 — 但多数页面未使用。
**建议:**
1. 统一使用 `handleApiError()``useApiRequest` hook
2. 批量替换 18 个文件中的内联模式
3. 建立 ESLint 规则禁止该模式
**优先级:** P2
### 6.3 TypeScript 类型安全
**`any` 使用统计:**
- Web10 处3 个文件)— 集中在 `usePaginatedData`5 处和插件看板4 处)
- 小程序28 处12 个文件)— 集中在 BLE API 类型缺失11 处和微信登录响应5 处)
**根因分析:**
- `usePaginatedData`Hook 重载签名问题,可通过泛型收窄解决
- 小程序 BLETaro 的 BLE 类型定义不完整,需补充类型声明文件
**优先级:** P3 — 不影响运行时,但影响类型安全性
**其他技术债:**
| 项目 | 数量 | 优先级 |
|------|------|--------|
| 编译器警告 | 40 个 | P3 |
| `unwrap()` 调用service 层生产风险) | 2 处PluginHost::db / semaphore acquire | P2 |
| TODO 注释 | 4 个(全部合理) | P4 |
| 过时迁移注释("应为 50 条" | 1 处 | P2 |
## 7. 专家组 5项目管理与交付效率
**成员画像:** 项目经理 + 产品负责人
### 7.1 未提交工作积压
**严重程度:** 🔴 CRITICAL
**现状:** 工作树中存在 24 个已修改未提交文件 + 48 个未跟踪新文件(共 73 个),包括:
- 8 个 wiki 文件(文档更新)
- 4 个小程序源文件
- 2 个 Web 前端文件
- 8 个 Rust 业务代码文件(跨 5 个 crate
- 7 个新的小程序医生端服务文件
- 8 个审计报告文档
- 5 个讨论记录
- 临时文件(`_temp/``mp_error.png``tmp_chart.png` 等)
**风险:** 本地故障 = 大量工作丢失 + 无法回溯变更历史 + 违反 CLAUDE.md 闭环工作法。
**建议:** 立即执行分类提交 — 按功能 / 文档 / 配置分组,并清理临时文件。
### 7.2 审计整改进度
**整改率:** 25 个审计发现中仅 1-2 个已处理(~8%3 天后)
**CRITICAL 项状态:**
| ID | 问题 | 天数 | 状态 |
|----|------|------|------|
| C1 | 晚间血压数据丢失 | 3 | 已修复但 wiki 文档未更新 |
| C2 | 告警权限码拼写错误 (`alert``alerts`) | 3 | **未修复**5 分钟改动) |
**HIGH 项状态:**
| ID | 问题 | 状态 |
|----|------|------|
| H1 | 小程序透析模块完全缺失 | 未开始 |
| H2 | 小程序知情同意页面完全缺失 | 未开始 |
| H3 | 健康服务运行时日志严重不足 | 部分修复patient_service tracing 已补全,其他大文件待跟进) |
**建议:**
1. C2 立即修复 — 改 `health.alert.manage``health.alerts.manage`
2. 建立审计整改看板 — 每个 finding 分配责任人和截止日期
3. 严格按 CRITICAL → HIGH → MEDIUM 顺序处理
### 7.3 Wiki 一致性
**发现的不一致:**
| 位置 | 问题 |
|------|------|
| `architecture.md:28-29` | 重复的插件列表行(一行有 assessment一行没有 |
| `architecture.md:25` | 权限码数量 22实际 erp-health 有 39 个) |
| `testing.md:124` | 迁移数 "应为 50 条"(实际已 96 条) |
| `database.md` | 迁移文档仅覆盖到 m000091实际 m000100 |
| `infrastructure.md` | 更新日期停留在 2026-04-23 |
| Docker compose | PostgreSQL 16 vs wiki 声称的 18 |
| entity 计数 | architecture.md 说 44实际列表有 45 个 |
**建议:** 安排 wiki 刷新会话,逐一校对数据。优先级 P2。
## 8. 优先级行动矩阵
### 🔴 P0 — 立即处理(今天)
| # | 行动 | 工作量 | 影响 |
|---|------|--------|------|
| 1 | 提交并推送 73 个未提交文件 | 30 min | 防止工作丢失 |
| 2 | 修复 C2 告警权限码拼写 | 5 min | 消除最后一个 CRITICAL |
| 3 | 确认 C1 晚间血压修复并更新 wiki | 15 min | 关闭审计 CRITICAL |
### 🟠 P1 — 本周内
| # | 行动 | 工作量 | 影响 |
|---|------|--------|------|
| 4 | 生产限流 fail-close 配置 | 1h | 生产安全 |
| 5 | 补全 erp-health/event.rs 测试 | 4h | 事件系统可靠性 |
| 6 | 孤立事件清理14 个) | 8h | 消除功能断裂风险 |
| 7 | 前端 Store 单元测试6 个 store | 8h | 前端回归安全网 |
| 8 | 小程序透析模块(审计 HIGH H1 | 16h | 医疗完整性 |
| 9 | 小程序知情同意模块(审计 HIGH H2 | 8h | 合规底线 |
| 10 | health_data_service / action_inbox 补充 tracing | 4h | 可观测性 |
### 🟡 P2 — 本月内
| # | 行动 | 工作量 | 影响 |
|---|------|--------|------|
| 11 | 前端错误处理统一化18 个文件) | 4h | 代码一致性 |
| 12 | 大文件拆分(后端 6 个千行文件) | 16h | 可维护性 |
| 13 | 前端 API 契约测试 | 8h | 集成可靠性 |
| 14 | Wiki 数据一致性刷新 | 4h | 文档可信度 |
| 15 | 数据库迁移治理策略 | 8h | 运维安全 |
| 16 | unwrap() 调用替换2 处) | 2h | 生产稳定性 |
### 🟢 P3 — 季度规划
| # | 行动 | 工作量 | 影响 |
|---|------|--------|------|
| 17 | 编译器警告清理40 个) | 8h | 代码清洁度 |
| 18 | 前端大组件拆分20 个文件) | 16h | 可维护性 |
| 19 | TypeScript any 消除 | 8h | 类型安全 |
| 20 | 小程序测试基础设施 | 16h | 小程序质量保障 |
| 21 | Docker 配置与文档对齐 | 4h | 部署一致性 |
| 22 | 数据保留策略设计 | 16h | 合规准备 |
---
## 9. 总结与建议
### 整体评分B+(良好,有明确的提升空间)
### 核心优势
1. **架构设计出色** — 分层清晰、模块边界严格、事件驱动解耦、零循环依赖
2. **安全基础扎实** — Argon2 + AES-256-GCM + PostgreSQL RLS + 审计哈希链
3. **文档驱动开发** — 41 份设计规格、18 份讨论记录、12 页 wiki决策有据可查
4. **API 层完整** — 328 路由覆盖所有业务,前端 API 层与后端 1:1 对应
5. **前端架构清晰** — API / Store / Hook 三层分离,无 god store、无硬编码数据、无 console.log 残留
### 核心风险
1. **前端测试空白** — <5% 覆盖率,任何重构都是冒险
2. **审计整改缓慢** — 3 天仅处理 8% 的审计发现CRITICAL C25 分钟改动)仍未修复
3. **工作积压** — 55+ 文件未提交,违反闭环工作法
4. **孤立事件** — 55% 的事件无消费者,可能是功能断裂的信号
5. **可观测性不足** — 多个核心 service 文件仍缺 tracing 日志patient_service 已补全)
### 下一步方向
当前阶段应遵循 **「止血 → 补短板 → 治本」** 路径:
1. **止血P0今天** 提交积压文件 + 关闭审计 CRITICAL
2. **补短板P1本周** 事件系统 + 前端测试 + 小程序透析/知情同意 + 安全配置
3. **治本P2本月** 代码重构 + 文档刷新 + 迁移治理
4. **持续改善P3季度** 类型安全 + 警告清理 + 测试扩展
**一句话总结:** 架构扎实、文档丰富的项目,当前需要暂停新功能开发,用 1-2 周集中补强测试和运维纪律,为下一阶段的功能扩展建立可靠的基础。