Files
hms/docs/superpowers/plans/2026-04-26-performance-optimization.md
iven b410fa9f78
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 份实施计划 — 性能/安全/事件/前端/可观测性
对应 5 份设计规格,共 75 个 Task:

1. 性能优化 (12 Task) — 批量INSERT/N+1内联name/合并COUNT/按需重绘/chunk拆分
2. 安全纵深防御 (8 Task) — RLS/行级数据范围/Redis session_key/审计哈希链
3. 事件驱动架构 (10 Task) — 11个缺失事件补发/LISTEN+NOTIFY/schema版本化
4. 前端工程化 (10 Task) — hook统一/组件拆分/Bundle优化
5. 可观测性运维 (10 Task) — 深度健康检查/Prometheus/OTel/生产Docker/告警
2026-04-27 08:00:50 +08:00

5.4 KiB
Raw Blame History

性能优化实施计划

设计规格: docs/superpowers/specs/2026-04-26-performance-optimization-design.md 日期: 2026-04-26 | 状态: draft | 总周期: 3 周


Phase 1: 后端批量插入优化Week 1, P0

Task 1: device_reading_service batch_insert_readings 改为 SeaORM insert_many

涉及文件: crates/erp-health/src/service/device_reading_service.rs

步骤: 将 batch_insert_readings() 中 for 循环逐条 model.insert(db).await 替换为构建 Vec<ActiveModel> 后调用 insert_many() + on_conflict(columns([...]).do_nothing())。补充 50 条模拟数据的批量插入测试。

验收: cargo test -p erp-health device_reading 通过500 条插入延迟 < 100ms。

Task 2: device_reading_service upsert_hourly_aggregates 批量化

涉及文件: crates/erp-health/src/service/device_reading_service.rs

步骤: 批量查出已存在的聚合记录(按 patient_id + device_type + hour分为"新增"和"更新"两组,分别 insert_many 和批量 update,事务包装。补充同一小时多次 upsert 的聚合精度测试。

验收: 聚合值avg/min/max精度与优化前一致cargo test 通过。


Phase 2: 前端 N+1 根治Week 2, P0

Task 3: 后端 appointment_service list 返回 patient_name/doctor_name

涉及文件: crates/erp-health/src/service/appointment_service.rs, dto/mod.rs, handler/mod.rs

步骤: 列表 DTO 增加 patient_name/doctor_name 字段service 查询中 find_also_related 或子查询关联 users 表获取 display_namehandler 层映射到响应 DTO。保持 Option 类型向后兼容。

验收: GET /api/v1/health/appointments 每条记录含 name 字段。

Task 4: 后端 consultation_service / follow_up_service 同样内联 name

涉及文件: consultation_service.rs, follow_up_service.rs, dto/mod.rs

步骤: consultation list 添加 patient_name/doctor_namefollow_up list 添加 patient_name复用 Task 3 的 JOIN 模式。

验收: 两个列表 API 响应均含 name 字段;cargo test 通过。

Task 5: 前端 AppointmentList 移除 nameCache改用内联字段

涉及文件: apps/web/src/pages/health/AppointmentList.tsx

步骤: 移除 nameCache useState 及逐条请求 name 的 useEffect表格列直接使用后端返回的 patient_name/doctor_name,消除 fetchData 对 nameCache 的依赖。

验收: Network 面板仅 1 个列表 API 请求;首屏 < 500ms20 条记录)。

Task 6: 前端 ConsultationList / FollowUpTaskList 同样改造

涉及文件: ConsultationList.tsx, FollowUpTaskList.tsx

步骤: 两个页面移除 nameCache使用内联 name 字段。验证无 N+1 请求。

验收: 两个页面 Network 面板无 N+1 请求;pnpm build 通过。


Phase 3: 后端查询优化Week 3, P1

Task 7: stats_service 合并多次 COUNT 为 GROUP BY

涉及文件: crates/erp-health/src/service/stats_service.rs

步骤: 6 个统计函数从多次 COUNT 合并为 SELECT status, COUNT(*) GROUP BY status + 应用层 HashMap 聚合。compute_avg_field 用宏生成静态 SQL 常量替代 format! 拼接。编写对比测试确认 GROUP BY 与多次 COUNT 结果一致。

验收: get_follow_up_statistics 查询次数从 4 降为 1compute_avg_field 不再 format! 拼接。

Task 8: patient_service get_health_summary 用 tokio::join! 并行化

涉及文件: crates/erp-health/src/service/patient_service.rs

步骤: get_health_summary() 中 4 次 .await 改为 tokio::join! 并行执行,各查询错误独立处理(未找到返回 None

验收: 并行化后返回数据与串行一致;cargo test 通过。

Task 9: alert_engine 预加载规则批量评估

涉及文件: crates/erp-health/src/service/alert_engine.rs

步骤: 批量查询患者最近 cooldown 期间所有 alerts 构建 HashSet<rule_id>,按 device_type 批量查最新 hourly 记录后在内存匹配规则条件。重构为:批量加载 -> 内存过滤 -> 批量生成告警。

验收: 10 条规则评估查询次数从 ~20 降为 2-3cargo test 通过。


Phase 4: 前端渲染优化Week 3, P2

Task 10: PluginCRUDPage columns useMemo + 拆分子组件

涉及文件: apps/web/src/pages/PluginCRUDPage.tsx

步骤: columns 包裹 useMemo(() => [...], [schema]),搜索栏/分页/表格拆为独立子组件。

验收: 输入搜索时 columns 不重建;pnpm build 通过。

Task 11: PluginGraphPage 按需重绘

涉及文件: apps/web/src/pages/PluginGraphPage.tsx

步骤: 移除持续 requestAnimationFrame 循环,改为数据变更 useEffect 触发单次重绘 + ResizeObserver 监听容器变化。

验收: 静态页面时 CPU 占用 < 1%pnpm build 通过。

Task 12: vite.config.ts manualChunks 拆分 heavy deps

涉及文件: apps/web/vite.config.ts

步骤: manualChunks 配置 vendor-charts(@ant-design/charts) / vendor-flow(@xyflow/react) / vendor-editor(@wangeditor/editor),对应路由改用 React.lazy 动态加载。

验收: 主 bundle gzip 体积降低 200KB+;图表/流程图/编辑器按需加载。


执行原则

  1. 每 Task 完成后立即提交 — 不积压,保持可追溯
  2. Phase 1-2 为 P0 — 批量插入和 N+1 根治直接影响生产性能
  3. cargo test + pnpm build 必须通过 — 每个 Task 完成后验证