diff --git a/docs/superpowers/specs/2026-05-03-q2-roadmap-design.md b/docs/superpowers/specs/2026-05-03-q2-roadmap-design.md new file mode 100644 index 0000000..c1c59a6 --- /dev/null +++ b/docs/superpowers/specs/2026-05-03-q2-roadmap-design.md @@ -0,0 +1,131 @@ +# HMS Q2 路线图 — 技术债清理 + 新功能并行推进 + +> 日期: 2026-05-03 | 类型: 设计规格 | 状态: 定稿 +> +> **目标:** 在 8 周内(2026-05 ~ 2026-06),以 60% 技术债 + 40% 新功能的节奏,将项目健康度从 B+ 提升到 A-。 + +## 1. 背景 + +### 当前状态 + +止血(P0)和补短板(P1)阶段已基本完成: +- ✅ 编译器警告清零(22 → 0) +- ✅ 孤立事件清理(36% → 0%) +- ✅ Store 单元测试(52 个)+ API 契约测试(244 个) +- ✅ 前端错误处理统一(9 文件) +- ✅ Tracing 补全(health_data + action_inbox) +- ✅ 限流 fail-close(默认 true) +- ✅ Wiki 数据一致性刷新 +- ✅ 小程序透析模块 + 知情同意页面 + +### 剩余技术债 + +| 项 | 现状 | 目标 | +|----|------|------| +| 页面/组件测试 | 1/99 (~3%) | 85/99 (85%) | +| 千行 service 文件 | 4 个 | 0 个 | +| 前端大组件 | 5 个 500+ 行 | 0 个 | +| TypeScript any | Web 10 / 小程序 28 | Web 0 / 小程序 <5 | + +### 新功能需求 + +| 方向 | 设计规格 | 实施状态 | +|------|---------|---------| +| AI 功能前端补全 | 已有 SSE 后端 | 前端无 UI 入口 | +| 工作台深度优化 | 已有设计规格 | Phase 1 完成,v2 待开始 | +| 实时体征 + BLE | 已有设计规格 | 未实施 | +| 小程序体验优化 | 已有设计规格 | 部分完成 | + +## 2. 时间线与里程碑 + +### W1-2:AI 前端补全 + 测试工厂基础 + +**技术债 (60%)** +- 开发页面测试工厂(renderWithProviders + createListPageTests) +- 第一批页面测试(20 个健康管理核心页面) + +**新功能 (40%)** +- AI 分析列表页 — 展示历史分析记录 +- AI 分析详情页 — SSE 流式响应 UI +- AI Prompt 管理页 — CRUD + 激活/回滚 +- AI 用量仪表盘 — 用量统计图表 + +**里程碑 M1:** AI 分析页面可用 + 20 页面测试通过 + +### W3-4:工作台优化 + 测试扩展 + +**技术债 (60%)** +- createDetailPageTests + createFormPageTests 工厂 +- 第二批页面测试(30 个) + +**新功能 (40%)** +- 医生操作台 v2 — AI 洞察面板集成 + 行动收件箱增强 +- 健康管理师工作台 v2 — 团队概览 + 任务分配优化 + +**里程碑 M2:** 工作台 v2 上线 + 50 页面测试通过 + +### W5-6:实时体征 + 大文件拆分 + +**技术债 (60%)** +- points_service.rs (1863 行) → 拆为 4 个模块 +- stats_service.rs (1117 行) → 拆为 3 个模块 +- patient_service.rs (1118 行) → 拆为 4 个模块 +- health_data_service.rs (1056 行) → 拆为 3 个模块 + +**新功能 (40%)** +- 实时体征管线 MVP — SSE 推送 + 前端图表实时更新 +- BLE 设备适配器增强 — 小米手环数据同步优化 + +**里程碑 M3:** 实时体征管线 MVP + 4 个千行文件拆分完成 + +### W7-8:小程序优化 + 测试收尾 + +**技术债 (60%)** +- createDashboardPageTests 工厂 +- 第三批页面测试(20 个)+ 手写测试(14 个复杂页面) +- TypeScript any 消除(Web 10 → 0) + +**新功能 (40%)** +- 小程序医生端体验优化 — 告警处理流程 + 患者快速查看 +- 小程序患者端优化 — 适老化改进 + 健康数据可视化增强 + +**里程碑 M4:** 小程序优化完成 + 页面覆盖率 85% + +## 3. 新功能依赖关系 + +``` +AI 前端补全(W1-2) + └→ 工作台优化(W3-4)— AI 洞察面板是工作台组件 + └→ 实时体征管线(W5-6)— 体征数据在工作台展示 + +小程序优化(W7-8)— 独立模块,可任意时序 +``` + +## 4. 成功度量 + +| 指标 | 当前 | W2 | W4 | W6 | W8 | +|------|------|----|----|----|-----| +| 页面测试覆盖率 | 3% | 21% | 51% | 51% | 85% | +| 千行 service 文件 | 4 | 4 | 4 | 0 | 0 | +| AI 端点有 UI 入口 | 0/4 | 4/4 | 4/4 | 4/4 | 4/4 | +| 工作台功能完整度 | Phase 1 | Phase 1 | Phase 2 | Phase 2 | Phase 2 | +| TypeScript any (Web) | 10 | 10 | 10 | 10 | 0 | +| 项目健康度评分 | B+ | — | — | — | A- | + +## 5. 风险 + +| 风险 | 影响 | 缓解 | +|------|------|------| +| 新功能范围蔓延 | 技术债推迟 | 每周严格 60/40 比例 | +| 测试工厂不支持页面变体 | 覆盖率虚高 | 工厂先验证 3 个差异最大页面 | +| 实时体征管线技术复杂 | W5-6 延期 | 先做 SSE 推送 MVP,不做 WebSocket | +| 单人开发瓶颈 | 所有任务串行 | 技术债和新功能交替进行,避免上下文切换 | + +## 6. 与其他规格的关系 + +本路线图引用以下已有规格作为实施输入: +- `2026-05-03-web-page-component-testing-design.md` — 页面测试工厂 +- `2026-04-26-realtime-vital-signs-pipeline-design.md` — 实时体征管线 +- `2026-04-28-ui-ux-overhaul-design.md` — 工作台/UI 重构 +- `2026-04-25-erp-ai-module-design.md` — AI 模块设计 +- `2026-04-26-BLE-device-adaptation-design.md` — BLE 设备适配 diff --git a/docs/superpowers/specs/2026-05-03-web-page-component-testing-design.md b/docs/superpowers/specs/2026-05-03-web-page-component-testing-design.md new file mode 100644 index 0000000..7b298b8 --- /dev/null +++ b/docs/superpowers/specs/2026-05-03-web-page-component-testing-design.md @@ -0,0 +1,446 @@ +# Web 前端页面/组件全面测试设计规格 + +> 日期: 2026-05-03 | 类型: 设计规格 | 状态: 定稿 +> +> **目标:** 为 HMS Web 前端页面/组件建立全面测试覆盖,从当前 ~3% 页面覆盖率提升到 85%(约 85/99 个页面有测试文件)。 + +## 1. 背景与动机 + +### 为什么做 + +2026-05-03 深度分析报告中,4 个专家组独立将「前端测试空白」标记为最大质量风险。虽然此后的工作已完成 Store 测试(6 个)和 API 契约测试(25 个),但 **99 个页面/组件中仅有 1 个(StatusTag)有测试**。 + +页面级测试的缺失意味着: +- 任何重构都无法验证不引入回归 +- 错误处理统一化(18 文件)已执行但无测试保障 +- 大组件拆分(5 个 500+ 行文件)因无安全网而风险过高 + +### 范围 + +- **覆盖:** Web 前端 99 个页面/组件 TSX 文件 +- **不含:** Store 测试(已完成)、API 契约测试(已完成)、E2E 测试(独立维护) +- **工具:** Vitest + @testing-library/react + msw + +## 2. 页面模式分类 + +分析 99 个页面组件后识别出 4 种核心交互模式: + +### 模式 1:列表页(ListPage)— ~50 个页面 + +**特征:** Ant Design Table + FilterBar + 分页 + 新建/编辑弹窗 + +**示例:** PatientList, AppointmentList, AlertList, DoctorList, Users, Roles, Organizations, Messages, ArticleManageList, PointsProductList, PointsOrderList, PointsRuleList, AlertRuleList, FollowUpTaskList, FollowUpRecordList, FollowUpTemplateList, ConsultationList, DeviceManage, DialysisManageList, OfflineEventList, DictionaryManager, MenuConfig, NumberingRules, PluginAdmin, PluginMarket, AuditLogViewer, PendingTasks, CompletedTasks, ProcessDefinitions, InstanceMonitor + +**测试要点:** +1. 初始渲染调用列表 API +2. 表格渲染正确的列名 +3. 分页翻页传递正确参数 +4. 筛选器传递正确参数 +5. 新建按钮可点击 +6. 编辑按钮可点击 + +### 模式 2:详情页(DetailPage)— ~15 个页面 + +**特征:** 多 Tab 切换 + 子组件按 Tab 加载 + +**示例:** PatientDetail, ConsultationDetail, PatientDetail 内的 Tab 组件(VitalSignsTab, LabReportsTab, FollowUpTab, FamilyMembersTab, HealthRecordsTab, DeviceReadingsTab, PointsAccountTab, DailyMonitoringTab, AiSuggestionTab) + +**测试要点:** +1. URL 参数正确传递 +2. Tab 切换加载对应数据 +3. 返回导航正常 + +### 模式 3:表单页(FormPage)— ~10 个页面 + +**特征:** 独立表单页面 + 提交/保存 + +**示例:** ArticleEditor, Login, ArticleCategoryManage, ArticleTagManage, PatientTagManage, ChangePassword, ThemeSettings, LanguageManager, SystemSettings + +**测试要点:** +1. 表单字段正确渲染 +2. 必填校验触发 +3. 提交调用正确 API +4. 成功后正确跳转或提示 + +### 模式 4:仪表盘页(DashboardPage)— ~10 个页面 + +**特征:** 统计卡片 + 图表 + 数据聚合 + +**示例:** Home, StatisticsDashboard, AlertDashboard, AiUsageDashboard, AiAnalysisList, AiPromptList, AiUsageDashboard, DashboardWidgets + +**测试要点:** +1. 统计 API 正确调用 +2. 数据渲染到卡片 +3. 时间范围切换传参正确 + +### 不归类 — ~14 个复杂页面 + +PluginCRUDPage, PluginDashboardPage, PluginGraphPage, PluginKanbanPage, PluginTabsPage, PluginTreePage, ProcessDesigner, ProcessViewer, Settings(容器页), Workflow(容器页), CalendarView, VitalSignsChart, ImagePreview, AlertDetailPanel + +这些页面需要独立手写测试。 + +## 3. 技术架构 + +### 3.1 工具链 + +``` +vitest 4 + @testing-library/react 16 + msw 2 +``` + +**选择 msw 的理由:** +- 拦截层在网络层,与 axios/fetch 解耦 +- API mock handlers 可与已有 API 契约测试共享 +- 支持真实 HTTP 状态码和错误场景模拟 +- 不需要在每个测试文件中手动 jest.fn() + +### 3.2 文件结构 + +``` +apps/web/src/test/ +├── setup.ts # 已有:jsdom setup + @testing-library/jest-dom +├── factories/ +│ ├── listPageTests.ts # createListPageTests() — 列表页测试工厂 +│ ├── detailPageTests.ts # createDetailPageTests() — 详情页测试工厂 +│ ├── formPageTests.ts # createFormPageTests() — 表单页测试工厂 +│ └── dashboardPageTests.ts # createDashboardPageTests() — 仪表盘测试工厂 +├── helpers/ +│ ├── renderWithProviders.tsx # Router + Zustand Store + AntD ConfigProvider 包裹 +│ ├── mswServer.ts # msw server setup/teardown +│ ├── apiHandlers.ts # 通用 API mock handlers(与契约测试共享) +│ └── testFixtures.ts # 测试数据工厂(患者、医生、预约等) +``` + +### 3.3 工厂函数接口 + +```typescript +// 列表页测试工厂 +interface ListPageTestConfig { + component: React.ComponentType; + apiUrl: string; + columns: string[]; + filters?: Array<{ name: string; type: 'select' | 'input' | 'date' }>; + hasCreate?: boolean; + hasEdit?: boolean; + hasDelete?: boolean; + mockData: Record[]; +} + +function createListPageTests(config: ListPageTestConfig): void; + +// 详情页测试工厂 +interface DetailPageTestConfig { + component: React.ComponentType; + detailApiUrl: string; + tabs: Array<{ label: string; apiUrl: string }>; + mockDetail: Record; +} + +function createDetailPageTests(config: DetailPageTestConfig): void; + +// 表单页测试工厂 +interface FormPageTestConfig { + component: React.ComponentType; + submitApiUrl: string; + submitMethod: 'POST' | 'PUT'; + requiredFields: string[]; + mockInitialValues?: Record; +} + +function createFormPageTests(config: FormPageTestConfig): void; + +// 仪表盘测试工厂 +interface DashboardTestConfig { + component: React.ComponentType; + statsApis: Array<{ url: string; responseKey: string }>; + hasDateRangePicker?: boolean; +} + +function createDashboardPageTests(config: DashboardTestConfig): void; +``` + +### 3.4 renderWithProviders + +```typescript +// 统一包裹组件,模拟真实运行环境 +function renderWithProviders( + ui: React.ReactElement, + options?: { + initialRoute?: string; + preloadedState?: Record; + userRole?: 'admin' | 'doctor' | 'nurse'; + } +): { + ...RenderResult; + store: ReturnType; +}; +``` + +包裹内容: +- `` — 模拟路由 +- Zustand store 重置 + 预填充 — Zustand v5 不使用 Provider,通过 `zustand/testing` 或直接 store.setState 注入测试状态 +- Ant Design `` — 中文 locale + 主题(注意 antd v6 的 Modal 默认渲染到 document.body,需设置 `getContainer` 或使用 `container.baseElement`) + +## 4. 执行策略 + +### 4.1 分批计划 + +#### 第一批(~20 个测试文件):健康管理核心流程 + +优先覆盖患者和预约管理,这是所有业务的基础。 + +**工厂开发 + 核心页面:** + +| 页面 | 模式 | 说明 | +|------|------|------| +| PatientList | ListPage | 患者列表 — 验证工厂 | +| PatientDetail | DetailPage | 患者详情 — 验证工厂 | +| AppointmentList | ListPage | 预约列表 | +| FollowUpTaskList | ListPage | 随访任务 | +| FollowUpRecordList | ListPage | 随访记录 | +| AlertList | ListPage | 告警列表 | +| AlertDashboard | DashboardPage | 告警仪表盘 | +| ConsultationList | ListPage | 咨询列表 | +| ConsultationDetail | DetailPage | 咨询详情 | +| DoctorList | ListPage | 医生列表 | +| DoctorSchedule | FormPage | 医生排班 | +| VitalSignsTab | DetailPage(sub) | 体征 Tab | +| LabReportsTab | DetailPage(sub) | 化验 Tab | +| StatusTag | 已有 | 补充更多场景 | +| PatientSelect | FormPage(sub) | 患者选择器 | +| DoctorSelect | FormPage(sub) | 医生选择器 | +| FilterBar | 组件测试 | 筛选栏 | +| ExportButton | 组件测试 | 导出按钮 | +| AiSuggestionTab | DetailPage(sub) | AI 建议 Tab | +| HealthRecordsTab | DetailPage(sub) | 健康记录 Tab | + +#### 第二批(~30 个测试文件):其余健康管理 + 基础模块 + +| 域 | 页面数 | 模式 | +|----|--------|------| +| 积分系统 | 3 (PointsProductList, PointsOrderList, PointsRuleList) | ListPage | +| 内容管理 | 4 (ArticleManageList, ArticleEditor, ArticleCategoryManage, ArticleTagManage) | ListPage + FormPage | +| 设备 + 透析 + 线下活动 | 3 | ListPage | +| 基础:Users, Roles, Organizations, Messages | 4 | ListPage | +| Login | 1 | FormPage | +| 健康管理剩余 | ~14 | 混合 | + +#### 第三批(~20 个测试文件):设置 + 工作流 + 插件 + 复杂页面 + +| 域 | 页面数 | 说明 | +|----|--------|------| +| 设置页面 | 8 | ListPage + FormPage | +| 工作流 | 6 | 混合(ProcessDesigner 手写) | +| 插件 | 7 | 混合(多个需手写) | +| 仪表盘 | 3 | DashboardPage | +| 复杂页面手写 | ~14 | 独立测试 | + +### 4.2 覆盖率目标 + +| 阶段 | 新增测试文件 | 累计测试文件 | 页面覆盖率 | +|------|------------|------------|-----------| +| 当前 | 0 | 36 | ~3% (1/99) | +| 第一批完成 | +20 | 56 | ~21% | +| 第二批完成 | +30 | 86 | ~51% | +| 第三批完成 | +20 | 106 | ~85%(含手写 14) | + +> **页面覆盖率 = 有测试文件的页面数 / 总页面数(99)。** 目标 85/99 = 85%。 + +### 4.3 工厂优先开发顺序 + +1. `createListPageTests` — 覆盖最多页面(~50 个),第一个开发 +2. `renderWithProviders` + `mswServer` — 所有工厂的基础 +3. `createDetailPageTests` — 覆盖 ~15 个页面 +4. `createFormPageTests` — 覆盖 ~10 个页面 +5. `createDashboardPageTests` — 覆盖 ~10 个页面 + +每个工厂开发后,用第一批中的 2-3 个页面验证设计,确认可行后再推广。 + +## 5. 验证标准 + +### 工厂验证 + +- [ ] 每个工厂至少用 3 个不同页面验证 +- [ ] 工厂生成的测试在 CI 中通过 +- [ ] `pnpm test:coverage` 输出可查看覆盖率 + +### 阶段验收 + +- [ ] 第一批:20 个测试文件通过,PatientList + AppointmentList 完整覆盖 +- [ ] 第二批:累计 86 个测试文件通过 +- [ ] 第三批:累计 106 个测试文件通过,页面覆盖率 85% + +### 不做 + +- 不追求 100% 行覆盖率 — 目标是页面覆盖率 85% +- 不测 Ant Design 组件内部行为 — 只测我们的业务逻辑 +- 不建立快照测试 — 价值低 +- 不测 CSS 样式 — 由视觉回归测试覆盖 + +## 6. 风险与缓解措施 + +### 风险 1:工厂函数无法覆盖同模式内的变异性 + +50 个列表页虽然共享 Table + FilterBar 模式,但 API 调用方式、筛选器类型、自定义操作按钮差异较大。如果工厂配置接口不足,会退化为逐个手写。 + +**缓解:** 开发 ListPage 工厂后,立即用差异最大的 3 个页面(PatientList 复杂筛选、AlertList 自定义操作、Users 简单列表)验证。如果配置接口不足,先调整工厂接口再推广。 + +### 风险 2:Ant Design v6 在 jsdom 下的兼容性 + +antd 的 Modal/Drawer 默认渲染到 `document.body`,超出 testing-library 的默认查询范围。Select/DatePicker 等组件的弹出层在 jsdom 中行为可能不同。 + +**缓解:** 在 `renderWithProviders` 中设置 `container.baseElement: document.body`;对 Modal 组件使用 `attachTo` 配置;必要时为 antd 弹窗组件编写自定义查询函数。 + +### 风险 3:Zustand v5 测试隔离 + +Zustand v5 移除了 ``,store 隔离方式变化。`renderWithProviders` 需要使用 `store.setState()` 直接注入状态而非 Provider 包裹。 + +**缓解:** 项目已有 Store 测试(6 个)验证了 Zustand v5 的测试模式,沿用相同方法。 + +### 风险 4:测试运行时间增长 + +99 个页面测试 + msw 拦截会显著增加 CI 运行时间。 + +**缓解:** Vitest 默认并行运行;对慢测试标记 `@slow` 隔离运行;CI 中使用 `vitest --reporter=verbose` 配合覆盖率阈值门控(不达标则失败)。 + +## 附录:99 个页面/组件完整分类 + +### 列表页模式(ListPage)— 42 个 + +| # | 页面文件 | 域 | +|---|---------|-----| +| 1 | PatientList | health | +| 2 | AppointmentList | health | +| 3 | DoctorList | health | +| 4 | AlertList | health | +| 5 | AlertRuleList | health | +| 6 | FollowUpTaskList | health | +| 7 | FollowUpRecordList | health | +| 8 | FollowUpTemplateList | health | +| 9 | ConsultationList | health | +| 10 | ArticleManageList | health | +| 11 | PointsProductList | health | +| 12 | PointsOrderList | health | +| 13 | PointsRuleList | health | +| 14 | DeviceManage | health | +| 15 | DialysisManageList | health | +| 16 | OfflineEventList | health | +| 17 | Users | auth | +| 18 | Roles | auth | +| 19 | Organizations | auth | +| 20 | Messages | message | +| 21 | DictionaryManager | config | +| 22 | MenuConfig | config | +| 23 | NumberingRules | config | +| 24 | AuditLogViewer | config | +| 25 | PluginAdmin | plugin | +| 26 | PluginMarket | plugin | +| 27 | PendingTasks | workflow | +| 28 | CompletedTasks | workflow | +| 29 | ProcessDefinitions | workflow | +| 30 | InstanceMonitor | workflow | +| 31 | AiAnalysisList | ai | +| 32 | AiPromptList | ai | +| 33 | ActionInbox | health | +| 34 | StatisticsDashboard | health | +| 35 | ArticleCategoryManage | health | +| 36 | ArticleTagManage | health | +| 37 | PatientTagManage | health | +| 38 | ThemeSettings | config | +| 39 | LanguageManager | config | +| 40 | SystemSettings | config | +| 41 | ChangePassword | auth | +| 42 | MessageTemplates | message | + +### 详情页模式(DetailPage)— 17 个 + +| # | 页面/组件文件 | 域 | +|---|--------------|-----| +| 1 | PatientDetail | health | +| 2 | ConsultationDetail | health | +| 3 | VitalSignsTab | health/component | +| 4 | LabReportsTab | health/component | +| 5 | FollowUpTab | health/component | +| 6 | FamilyMembersTab | health/component | +| 7 | HealthRecordsTab | health/component | +| 8 | DeviceReadingsTab | health/component | +| 9 | PointsAccountTab | health/component | +| 10 | DailyMonitoringTab | health/component | +| 11 | AiSuggestionTab | health/component | +| 12 | AlertDetailPanel | health/component | +| 13 | ActionDetailDrawer | health/workbench | +| 14 | TaskDetail | health/workbench | +| 15 | TaskQueue | health/workbench | +| 16 | TodoList | health/workbench | +| 17 | TeamOverviewPanel | health/workbench | + +### 表单页模式(FormPage)— 10 个 + +| # | 页面文件 | 域 | +|---|---------|-----| +| 1 | ArticleEditor | health | +| 2 | Login | auth | +| 3 | DoctorSchedule | health | +| 4 | NotificationPreferences | message | +| 5 | NotificationList | message | +| 6 | DashboardWidgets | dashboard | +| 7 | ProcessViewer | workflow | +| 8 | DoctorWorkbench | health/workbench | +| 9 | OperatorWorkbench | health/workbench | +| 10 | AdminDashboard | health/workbench | + +### 仪表盘模式(DashboardPage)— 10 个 + +| # | 页面文件 | 域 | +|---|---------|-----| +| 1 | Home | core | +| 2 | AlertDashboard | health | +| 3 | AiUsageDashboard | ai | +| 4 | AiInsightPanel | health/workbench | +| 5 | AdminDashboard (StatisticsDashboard) | health/stats | +| 6 | DoctorDashboard (StatisticsDashboard) | health/stats | +| 7 | HealthDataCenter (StatisticsDashboard) | health/stats | +| 8 | NurseDashboard (StatisticsDashboard) | health/stats | +| 9 | OperatorDashboard (StatisticsDashboard) | health/stats | +| 10 | DashboardWidgets | dashboard | + +### 手写测试 — 20 个复杂页面 + +| # | 页面文件 | 域 | 复杂度原因 | +|---|---------|-----|-----------| +| 1 | PluginCRUDPage | plugin | 动态表单 + 插件数据 | +| 2 | PluginDashboardPage | plugin | 动态图表 | +| 3 | PluginGraphPage | plugin | @xyflow/react 图编辑 | +| 4 | PluginKanbanPage | plugin | 拖拽看板 | +| 5 | PluginTabsPage | plugin | 动态 Tab | +| 6 | PluginTreePage | plugin | 树形结构 | +| 7 | ProcessDesigner | workflow | BPMN 设计器 | +| 8 | CalendarView | health/component | 日历交互 | +| 9 | VitalSignsChart | health/component | ECharts 图表 | +| 10 | ImagePreview | health/component | 图片预览 | +| 11 | PatientSelect | health/component | 异步搜索选择器 | +| 12 | DoctorSelect | health/component | 异步搜索选择器 | +| 13 | FilterBar | component | 通用筛选组件 | +| 14 | ExportButton | component | 文件导出 | +| 15 | StatusTag | health/component | 已有,需补充 | +| 16 | Settings | core | 容器页面 | +| 17 | Workflow | core | 容器页面 | +| 18 | PluginCRUDPageInner | plugin | CRUD 内部逻辑 | +| 19 | DetailDrawer | plugin | 抽屉详情 | +| 20 | ImportModal | plugin | 导入弹窗 | + +### 排除(非页面组件) + +- `dashboardConstants.tsx` — 常量定义文件,不含 React 组件 + +> **分类合计:** 42 列表 + 17 详情 + 10 表单 + 10 仪表盘 + 20 手写 = 99。页面覆盖率目标 = (99 - 14 未覆盖) / 99 ≈ 85%。 + +## 预估工时 + +| 阶段 | 内容 | 预估人时 | 说明 | +|------|------|---------|------| +| 基础设施 | renderWithProviders + mswServer + testFixtures | 4h | 一次性投入 | +| 工厂开发 | 4 个工厂函数 | 12h | 每个工厂 3h | +| 第一批 | 20 个页面测试 | 12h | 工厂模式,每个 ~0.6h | +| 第二批 | 30 个页面测试 | 18h | 工厂模式 | +| 第三批 | 20 个手写 + 17 个工厂 | 24h | 手写页面耗时较高 | +| **总计** | | **~70h** | 约 2 周全职工作 | diff --git a/wiki/architecture.md b/wiki/architecture.md index 6bcac09..00f9eeb 100644 --- a/wiki/architecture.md +++ b/wiki/architecture.md @@ -22,15 +22,15 @@ HMS 继承 ERP 底座的所有基础模块,`erp-health` 作为原生 Rust 模 ``` HMS 平台 ├── 基础模块(继承 ERP): auth, config, workflow, message, plugin -├── 核心业务模块: erp-health(原生 Rust,45 实体/39 权限/25+ 页面)★ 已实现 -├── AI 模块: erp-ai(3 实体,SSE 流式分析,Phase 1 MVP) +├── 核心业务模块: erp-health(原生 Rust,46 实体/39 权限/25+ 页面)★ 已实现 +├── AI 模块: erp-ai(6 实体,SSE 流式分析,Phase 1 MVP) ├── 透析模块: erp-dialysis(已拆分为独立 crate) └── 可选插件: crm, inventory, freelance, itops, assessment(WASM) ``` ### 为什么 erp-health 用原生模块? -医疗业务需要 44 强类型实体、自定义 API(趋势分析/统计报表)、PII 数据加密(AES-256-GCM + KEK/DEK 分层)、文件上传、未来 AI 集成。WASM 插件的 JSONB 动态存储和 20 实体上限无法满足。详见 [[erp-health]]。 +医疗业务需要 46 强类型实体、自定义 API(趋势分析/统计报表)、PII 数据加密(AES-256-GCM + KEK/DEK 分层)、文件上传、未来 AI 集成。WASM 插件的 JSONB 动态存储和 20 实体上限无法满足。详见 [[erp-health]]。 ### 为什么用 UUIDv7? @@ -105,8 +105,8 @@ hms/ | erp-workflow | ✅ 完成 | 5 表 | 8(种子数据) | 工作流管理 | 63 单元 + 4 集成 | | erp-message | ✅ 完成 | 3 表 | 5(种子数据) | 消息中心 | 72 单元 | | erp-plugin | ✅ 完成 | 4 表 | 2(种子数据) | 插件管理/市场 | 78 单元 + 2 集成 | -| erp-health | ✅ 完成 | 45 表 | 39 | 25+ 页面 + 11 组件 | 159 单元 + 144 集成 | -| erp-ai | 🔄 Phase 1 | 3 表 | 6 | AI 分析/Prompt/用量 | 36 单元 | +| erp-health | ✅ 完成 | 46 表 | 39 | 25+ 页面 + 工作台 | 159 单元 + 144 集成 | +| erp-ai | 🔄 Phase 1 | 6 表 | 6 | AI 分析/Prompt/建议/风险/用量 | 36 单元 | | erp-dialysis | 🔄 已拆分 | - | 5 | - | 10 单元 + 15 集成 | ### 技术选型 @@ -115,7 +115,7 @@ hms/ |------|------| | Axum 0.8 | Tokio 团队维护,tower 生态,类型安全路由 | | SeaORM 1.1 | 异步、类型安全、迁移工具完善 | -| PostgreSQL 18 | 企业级,JSON 支持,扩展丰富 | +| PostgreSQL 16 | 企业级,JSON 支持,扩展丰富 | | Redis 7 | 缓存 + 限流 token bucket | | React 19 + Ant Design 6 | 企业后台 UI 标配 | | Zustand 5 | 极简状态管理 | diff --git a/wiki/database.md b/wiki/database.md index 23a652a..edea468 100644 --- a/wiki/database.md +++ b/wiki/database.md @@ -24,7 +24,7 @@ tags: [database, seaorm, migration, multi-tenant] | 文件 | 职责 | |------|------| | `crates/erp-server/migration/src/lib.rs` | Migrator 注册所有迁移 | -| `crates/erp-server/migration/src/m*.rs` | 96 个迁移文件 | +| `crates/erp-server/migration/src/m*.rs` | 103 个迁移文件 | | `crates/erp-core/src/types.rs` | BaseFields 标准字段定义 | ### 迁移命名规则 diff --git a/wiki/erp-ai.md b/wiki/erp-ai.md index b09cbb0..33f758f 100644 --- a/wiki/erp-ai.md +++ b/wiki/erp-ai.md @@ -1,6 +1,6 @@ --- title: erp-ai AI 分析模块 -updated: 2026-04-25 +updated: 2026-05-03 status: in-development tags: [ai, llm, sse, health-analysis, claude] --- @@ -54,13 +54,16 @@ crates/erp-ai/ │ └── ai_usage.rs ← 用量日志 Entity ``` -### 实体模型(3 个实体) +### 实体模型(6 个实体) | 实体 | 用途 | |------|------| | ai_prompt | Prompt 模板(版本管理、激活/回滚) | | ai_analysis | 分析结果记录(输入参数、输出摘要、token 用量) | | ai_usage | 用量追踪(按租户/用户聚合) | +| ai_suggestion | AI 建议记录(风险分级、建议内容、状态跟踪) | +| ai_risk_threshold | 风险阈值配置(按指标定义临界值) | +| ai_action | AI 行动分发(从建议到行动的闭环跟踪) | ### 权限码(6 个) diff --git a/wiki/erp-health.md b/wiki/erp-health.md index a6ed71c..99edc70 100644 --- a/wiki/erp-health.md +++ b/wiki/erp-health.md @@ -1,6 +1,6 @@ --- title: erp-health 健康管理模块 -updated: 2026-04-28 +updated: 2026-05-03 status: implemented tags: [health, patient, appointment, follow-up, consultation, content, points, dialysis, offline-events] --- @@ -47,7 +47,7 @@ crates/erp-health/ │ ├── state.rs ← HealthState { db, event_bus, crypto } │ ├── crypto.rs ← AES-256-GCM 加密 + HMAC-SHA256 (PII 保护) │ ├── event.rs ← 事件处理器 (订阅 workflow/message 事件) -│ ├── entity/ ← 45 个 SeaORM Entity +│ ├── entity/ ← 46 个 SeaORM Entity │ ├── service/ ← 25 个业务 service + validation + masking + trend │ ├── handler/ ← 21 个路由 handler │ ├── dto/ ← 15 个请求/响应 DTO @@ -57,7 +57,7 @@ crates/erp-health/ │ └── seed.rs ← 租户种子数据 + 软删除清理 ``` -### 实体模型(45 个实体) +### 实体模型(46 个实体) | 域 | 实体 | |----|------| @@ -223,7 +223,7 @@ draft → pending_review → published → draft (撤回) ### 当前状态: ✅ 已完成 -45 实体、21 个 handler(~160 个 pub fn)、39 权限、25+ Web 路由页面 + 11 组件,~21k 行 Rust 代码。状态转换验证统一到 validation 模块(104 纯函数测试)。18 个集成测试文件覆盖所有子域。 +46 实体、26 个 handler(~160 个 pub fn)、39 权限、25+ Web 路由页面 + 工作台组件,~27k 行 Rust 代码。状态转换验证统一到 validation 模块(104 纯函数测试)。24 个集成测试文件覆盖所有子域。 ### 待优化 diff --git a/wiki/frontend.md b/wiki/frontend.md index 5a9b31d..2b0d351 100644 --- a/wiki/frontend.md +++ b/wiki/frontend.md @@ -211,17 +211,16 @@ React 19.2.4 / Ant Design 6.3.5 / React Router 7.14.0 / Zustand 5.0.12 / Vite 8. | `deviceReadings.ts` | 设备数据采集 | | `alerts.ts` | 健康预警 | -### 前端单元测试(5 个) +### 前端单元测试(36 个测试文件) -| 文件 | 测试内容 | +| 类别 | 覆盖范围 | |------|---------| -| `constants/health.test.ts` | 健康常量定义验证 | -| `hooks/useThemeMode.test.ts` | 暗色模式 hook | -| `hooks/useDebouncedValue.test.ts` | 防抖 hook | -| `pages/health/components/StatusTag.test.tsx` | 状态标签渲染 | -| `utils/exprEvaluator.test.ts` | 表达式求值 | +| Store 测试 | auth, health, plugin, workbench, app, message | +| Hook 测试 | useThemeMode, useDebouncedValue, useCountUp 等 | +| API 契约测试 | 25+ API 模块 URL/Method/参数验证 | +| 组件测试 | StatusTag, 健康常量, 表达式求值 | -> ⚠️ **审计发现**:Web 前端 163 个文件仅 10 个测试(5 单元 + 5 E2E),测试覆盖率约 5%。小程序完全无测试。详见 `docs/audits/07-test-coverage.md`。 +> ⚠️ **审计发现**:Web 前端 225 个文件有 36 个测试文件 + 5 E2E spec,测试覆盖率仍需持续提升。小程序完全无测试。详见 `docs/audits/07-test-coverage.md`。 ### 2026-04-30 审计发现 diff --git a/wiki/index.md b/wiki/index.md index e4bb0cb..112ac51 100644 --- a/wiki/index.md +++ b/wiki/index.md @@ -8,21 +8,21 @@ |------|-----| | Rust crate | 18 个(erp-core + 5 基础业务 + erp-health + erp-ai + erp-dialysis + erp-plugin + 5 插件 + erp-plugin-prototype) | | 数据库表 | 30 基础表 + 44 健康业务表 + 3 AI 表(已实现) | -| 数据库迁移 | 96 个 | +| 数据库迁移 | 103 个 | | 后端路由 | 328 个(8 公开 + 320 受保护) | | 核心模块 | 5 基础 (auth/config/workflow/message/plugin) + 3 业务 (health + ai + dialysis) | -| erp-health 实体 | 45 个 Entity(~21k 行 Rust) | -| erp-ai 实体 | 3 个 Entity(1.7k 行 Rust) | -| Web 前端 | 92 TSX + 71 TS = 163 个源文件(含 25+ 健康路由页面 + 11 健康组件) | -| 微信小程序 | Taro 4.2 + React 18,40 个页面(31 患者端 + 9 医护端),5 个 TabBar | -| 前端单元测试 | 5 个(vitest)+ 5 E2E spec(playwright) | +| erp-health 实体 | 46 个 Entity(~27k 行 Rust) | +| erp-ai 实体 | 6 个 Entity(~3.6k 行 Rust) | +| Web 前端 | 225 个 TS/TSX 文件(含 25+ 健康路由页面 + 工作台组件) | +| 微信小程序 | Taro 4.2 + React 18,182 个源文件 / 40+ 页面 / 5 TabBar + 医生端 | +| 前端单元测试 | 36 个测试文件(vitest)+ 5 E2E spec(playwright) | | 后端测试 | 611 单元 + 153 集成 = 772 个函数(97.5% 通过率) | -| 总代码量 | Rust ~77k 行(462 源文件)+ Web 前端 163 文件 + 小程序 125 文件 | +| 总代码量 | Rust ~87k 行(484 源文件)+ Web 前端 225 文件 + 小程序 182 文件 | | 事件系统 | 25 事件类型 / 44 发布处 / 14 消费者 | -| DTO | 105 个结构体(17 文件) | +| DTO | 105+ 个结构体(23 文件) | | 权限码 | 50 声明(health 39 + ai 6 + dialysis 5)+ 56 基础模块手动注册 | | API 文档 | `http://localhost:3000/api/docs/openapi.json` | -| Git 提交 | 409 次 | +| Git 提交 | 574 次 | | 审计状态 | 2026-04-30 全系统审计完成(83% 总体完成度) | | UI/UX 重构 | Phase 1-5 完成(6 共享组件 + 4 角色仪表盘 + 个人统计数据 + 表单抽屉 + 小程序优化) | @@ -68,8 +68,8 @@ - erp-plugin — WASM 运行时 · 动态表 · 热更新(HMS 保留但非主要扩展方式) ### 核心业务层(HMS 专属) -- [[erp-health]] — **患者管理 · 健康数据 · 预约排班 · 随访管理 · 咨询管理 · 内容管理 · 积分商城 · 透析管理 · 线下活动 · 日常监测 · 告警系统**(原生 Rust 模块,44 实体,已实现) -- [[erp-ai]] — **AI 智能分析 · 化验单解读 · 趋势分析 · 报告摘要**(原生 Rust 模块,3 实体,Phase 1 MVP) +- [[erp-health]] — **患者管理 · 健康数据 · 预约排班 · 随访管理 · 咨询管理 · 内容管理 · 积分商城 · 透析管理 · 线下活动 · 日常监测 · 告警系统**(原生 Rust 模块,46 实体,已实现) +- [[erp-ai]] — **AI 智能分析 · 化验单解读 · 趋势分析 · 报告摘要**(原生 Rust 模块,6 实体,Phase 1 MVP) ### 组装层 - [[erp-server]] — Axum 入口 · AppState · 7+ 模块注册 · 后台任务 · 优雅关闭 @@ -79,8 +79,8 @@ ### 基础设施 - [[infrastructure]] — 连接信息 · 环境变量 · 一键启动 (**单一真相源**) -- [[database]] — SeaORM 迁移 · 多租户表结构(96 迁移) -- [[frontend]] — React 19 SPA · 健康管理页面(25+ 路由 + 11 组件) +- [[database]] — SeaORM 迁移 · 多租户表结构(103 迁移) +- [[frontend]] — React 19 SPA · 健康管理页面(25+ 路由 + 工作台组件) - [[testing]] — 验证清单 · 测试分布 · 性能基准 ## 核心架构问答 @@ -103,10 +103,10 @@ | PII 加密扩展规格 | `docs/superpowers/specs/2026-04-26-pii-encryption-expansion-design.md` | | 实时体征管线探讨 | `docs/superpowers/specs/2026-04-26-realtime-vital-signs-pipeline-design.md` | | 平台复盘与演进 | `docs/superpowers/specs/2026-04-26-platform-retrospective-and-evolution-design.md` | -| 设计规格(全量) | `docs/superpowers/specs/` (31 份) | +| 设计规格(全量) | `docs/superpowers/specs/` (41 份) | | UI/UX 重构设计规格 | `docs/superpowers/specs/2026-04-28-ui-ux-overhaul-design.md` | | UI/UX 重构实施计划 | `docs/superpowers/plans/2026-04-28-ui-ux-overhaul-plan.md` | -| 实施计划(全量) | `docs/superpowers/plans/` (27 份) | +| 实施计划(全量) | `docs/superpowers/plans/` (38 份) | | 全系统审计报告 | `docs/audits/08-audit-report-2026-04-30.md`(83% 总体完成度,2 CRITICAL + 3 HIGH) | | 审计基线快照 | `docs/audits/00-baseline-snapshot.md` | | 审计功能清单 | `docs/audits/01-feature-inventory.md`(328 路由三端映射矩阵) | @@ -116,6 +116,9 @@ | 审计差距模式 | `docs/audits/05-gap-patterns.md`(5 种模式,透析/知情同意 MP 缺失) | | 审计错误处理 | `docs/audits/06-error-handling.md`(SSE 不挂起 / 日志 30% 覆盖) | | 审计测试覆盖 | `docs/audits/07-test-coverage.md`(772 测试 / 前端极低 / AI 无集成测试) | -| 讨论记录 | `docs/discussions/` (10 份) | +| 讨论记录 | `docs/discussions/` (18 份) | +| 事件注册表 | `docs/event-registry.md` | +| Wiki 方法论 | `docs/wiki-methodology.md` | +| 项目深度分析 | `docs/superpowers/specs/2026-05-03-project-analysis-brainstorm-design.md`(5 专家组分析,B+ 评分) | | 协作规则 | `CLAUDE.md` | | 插件制作指南 | `.claude/skills/plugin-development/SKILL.md` | diff --git a/wiki/testing.md b/wiki/testing.md index da6c130..ea524f3 100644 --- a/wiki/testing.md +++ b/wiki/testing.md @@ -32,7 +32,7 @@ tags: [testing, verification] | erp-plugin | 78 | 2 | 80 | 100% | 良好 | | erp-server | - | 153 | 153 | 94% | 良好(API 集成测试) | | **后端总计** | **611** | **153** | **772** | **97.5%** | | -| 前端 (vitest) | 5 | - | - | - | 健康常量/useThemeMode/useDebouncedValue/StatusTag/exprEvaluator | +| 前端 (vitest) | 36 | - | - | - | Store/Hook/API 契约/组件测试 | | E2E (playwright) | - | 5 spec | - | - | 登录/用户管理/插件/租户隔离 | | 小程序 | 0 | 0 | 0 | N/A | ⚠️ 完全无测试 |