Files
hms/wiki/erp-health.md
iven 1602b7bbad
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(wiki): Wiki 全面刷新 + Q2 路线图 + 测试补强设计规格
- Wiki 7 文件关键数字刷新:迁移 96→103、实体 45→46、前端 163→225、测试 5→36
- 修复 architecture.md PostgreSQL 版本不一致(18→16)
- 修复 erp-ai.md 实体数 3→6、erp-health.md 实体数 45→46
- 更新 index.md 文档索引:specs 41、plans 38、discussions 18
- 新增事件注册表/方法论/分析报告引用
- 新增页面/组件测试设计规格(模式化工厂方案)
- 新增 Q2 路线图规格(技术债 + 新功能并行 8 周)
2026-05-03 22:33:08 +08:00

286 lines
14 KiB
Markdown
Raw Permalink 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.
---
title: erp-health 健康管理模块
updated: 2026-05-03
status: implemented
tags: [health, patient, appointment, follow-up, consultation, content, points, dialysis, offline-events]
---
# erp-health 健康管理模块
> 从 [[index]] 导航。关联: [[erp-core]] [[erp-server]] [[database]] [[frontend]]
>
> 设计规格: `docs/superpowers/specs/2026-04-23-health-management-module-design.md`
## 1. 设计决策
### 为什么用原生模块而非 WASM 插件?
| WASM 插件限制 | 健康模块需求 |
|---------------|-------------|
| 实体上限 20 个 | 18 强类型医疗实体 |
| JSONB 动态存储 | 医疗数据需要强类型、索引、关联 |
| 无自定义 API | 趋势分析、统计报表需专用端点 |
| 无文件上传 | 化验单、体检报告需存储 |
| 沙箱限制 | 无法引入加密、AI、外部 API |
### 为什么患者/医护账号走 erp-auth
复用现有用户体系认证、JWT、权限erp-health 只存医疗扩展字段。患者可先建档(体检中心导入),后续再绑定账号。
### 核心架构选择
- **原生 Rust crate** — 与 erp-auth、erp-workflow 同等地位,直接访问数据库
- **ErpModule trait 实现** — `HealthModule` 在 erp-server 注册,路由挂载到 `/api/v1/health`
- **EventBus 通信** — 发布 `patient.created``appointment.confirmed` 等,订阅 `workflow.task.completed`
- **HealthCrypto** — 已迁移到 `erp_core::crypto::PiiCrypto`AES-256-GCM + KEK/DEK 分层 + HMAC 盲索引),`crypto.rs` 保留兼容层
## 2. 关键文件 + 数据流
### 目录结构
```
crates/erp-health/
├── src/
│ ├── lib.rs ← 模块导出 (HealthCrypto, HealthModule, HealthState)
│ ├── module.rs ← ErpModule trait 实现, 14 权限码, 全部路由定义
│ ├── error.rs ← HealthError (17 变体) → AppError
│ ├── state.rs ← HealthState { db, event_bus, crypto }
│ ├── crypto.rs ← AES-256-GCM 加密 + HMAC-SHA256 (PII 保护)
│ ├── event.rs ← 事件处理器 (订阅 workflow/message 事件)
│ ├── entity/ ← 46 个 SeaORM Entity
│ ├── service/ ← 25 个业务 service + validation + masking + trend
│ ├── handler/ ← 21 个路由 handler
│ ├── dto/ ← 15 个请求/响应 DTO
│ ├── validation.rs ← 输入验证逻辑 (302 行, 104 纯函数测试)
│ ├── masking.rs ← PII 数据脱敏 (手机号/身份证)
│ ├── health_provider_impl.rs ← AI 数据桥接(当前 stub
│ └── seed.rs ← 租户种子数据 + 软删除清理
```
### 实体模型46 个实体)
| 域 | 实体 |
|----|------|
| 患者管理 | patient, patient_family_member, patient_tag, patient_tag_relation, patient_doctor_relation, patient_devices, blind_index, consent |
| 医护管理 | doctor_profile, doctor_schedule |
| 健康数据 | health_record, vital_signs, vital_signs_hourly, daily_monitoring, lab_report, health_trend, diagnosis, medication_record, device_readings |
| 透析管理 | dialysis_record |
| 预约排班 | appointment |
| 随访管理 | follow_up_task, follow_up_record, follow_up_template, follow_up_template_field |
| 咨询管理 | consultation_session, consultation_message |
| 内容管理 | article, article_category, article_tag, article_article_tag, article_revision |
| 告警系统 | alerts, alert_rules, critical_alert, critical_alert_response, critical_value_threshold |
| 积分商城 | points_account, points_rule, points_product, points_order, points_transaction, points_checkin |
| 线下活动 | offline_event, offline_event_registration |
### 权限码39 个)
| 权限码 | 说明 |
|--------|------|
| `health.patient.list` / `health.patient.manage` | 患者查看/管理 |
| `health.health-data.list` / `health.health-data.manage` | 健康数据查看/管理 |
| `health.appointment.list` / `health.appointment.manage` | 预约查看/管理 |
| `health.follow-up.list` / `health.follow-up.manage` | 随访查看/管理 |
| `health.consultation.list` / `health.consultation.manage` | 咨询查看/管理 |
| `health.doctor.list` / `health.doctor.manage` | 医护查看/管理 |
| `health.articles.list` / `health.articles.manage` | 文章查看/管理 |
| `health.articles.review` | 文章审核 |
| `health.points.list` / `health.points.manage` | 积分查看/管理 |
| `health.device-readings.list` / `health.device-readings.manage` | 设备数据查看/管理 |
| `health.devices.list` / `health.devices.manage` | 设备查看/管理 |
| `health.alerts.list` / `health.alerts.manage` | 告警查看/管理 |
| `health.alert-rules.list` / `health.alert-rules.manage` | 告警规则查看/管理 |
| `health.critical-alerts.list` / `health.critical-alerts.manage` | 危急值告警查看/管理 |
| `health.critical-value-thresholds.list` / `health.critical-value-thresholds.manage` | 危急值阈值查看/管理 |
| `health.follow-up-templates.list` / `health.follow-up-templates.manage` | 随访模板查看/管理 |
| `health.daily-monitoring.list` / `health.daily-monitoring.manage` | 日常监测查看/管理 |
| `health.consent.list` / `health.consent.manage` | 知情同意查看/管理 |
| `health.medication-records.list` / `health.medication-records.manage` | 用药记录查看/管理 |
| `health.medication-reminders.list` / `health.medication-reminders.manage` | 用药提醒查看/管理 |
### 集成契约
| 方向 | 模块 | 接口 | 触发时机 |
|------|------|------|---------|
| 提供 → | [[erp-server]] | `HealthModule` | 启动时注册 `/api/v1/health/*` |
| 调用 → | [[erp-core]] | EventBus | 发布/订阅领域事件 |
| 关联 → | erp-auth | `users` 表 (user_id FK) | 患者/医护关联账号 |
| 订阅 ← | erp-workflow | `workflow.task.completed` | 随访任务状态更新 |
| 订阅 ← | erp-message | `message.sent` | 消息通知(预留) |
| 订阅 ← | 设备同步 | `device.readings.synced` | 触发告警引擎评估 |
| 订阅 ← | 事件总线 | `patient.*` | 发送欢迎消息 |
| 订阅 ← | 事件总线 | `appointment.*` | 通知 + 号源释放 |
| 订阅 ← | 事件总线 | `follow_up.overdue` | 升级通知 |
| 订阅 ← | 事件总线 | `health_data.critical_alert` | 创建危急值告警 |
## 3. 代码逻辑
### API 前缀: `/api/v1/health/`
关键端点分组:
- `/patients` — 患者列表/详情/标签管理/健康摘要/家庭成员/医生关联/知情同意
- `/patients/{id}/vital-signs` — 日常监测数据(血压/心率/体重/血糖)
- `/patients/{id}/lab-reports` — 化验报告JSONB 指标数据)
- `/patients/{id}/health-records` — 健康档案
- `/patients/{id}/trends` — 健康趋势报告(自动/手动生成,时间序列查询)
- `/patients/{id}/diagnoses` — 诊断记录
- `/patients/{id}/dialysis-records` — 透析记录
- `/patients/{id}/daily-monitoring` — 日常监测记录
- `/vital-signs/trend` — 小程序趋势JWT user → patient
- `/vital-signs/today` — 小程序当日体征摘要
- `/appointments` — 预约管理 + 状态变更pending→confirmed→completed/cancelled/no_show
- `/appointments/{id}/status` — 预约状态流转(乐观锁)
- `/doctor-schedules` — 排班管理 CRUD + 日历视图
- `/doctor-schedules/calendar` — 月度排班日历
- `/follow-up-tasks` — 随访任务 CRUD + 逾期自动标记
- `/follow-up-tasks/{id}/records` — 随访记录
- `/consultation-sessions` — 咨询会话管理 + 消息 + 导出 + 关闭
- `/consultation-messages` — 咨询消息发送
- `/doctors` — 医护档案 CRUD
- `/articles` — 健康文章 CRUD + 审核状态机draft→pending_review→published
- `/articles/{id}/submit` — 提交审核
- `/articles/{id}/approve` — 批准发布
- `/articles/{id}/reject` — 拒绝(附原因)
- `/articles/{id}/unpublish` — 撤回已发布文章
- `/articles/{id}/view` — 增加阅读计数
- `/article-categories` — 分类 CRUD
- `/article-tags` — 标签 CRUD
- `/points/rules` — 积分规则 CRUD
- `/points/products` — 积分商品 CRUD
- `/points/orders` — 积分订单
- `/points/accounts` — 积分账户 + 签到
- `/offline-events` — 线下活动 CRUD + 报名
- `/stats/*` — 统计概览(透析/化验/预约/体征上报率)
- `/critical-value-thresholds` — 危急值阈值管理
### 预约并发控制
创建预约时使用原子 CAS事务内
1. 查找匹配日期+时段的排班
2. 原子 `UPDATE current_appointments + 1 WHERE current < max`
3. CAS 成功后 INSERT 预约记录
4. 事务保证 CAS + INSERT 原子性
### 预约状态机
```
pending → confirmed → completed
→ no_show → confirmed (重新确认)
→ cancelled
pending → cancelled
```
### 文章审核状态机
```
draft → pending_review → published → draft (撤回)
→ rejected → pending_review (重新提交)
```
- `submit` — draft/rejected → pending_review
- `approve` — pending_review → published自动设置 published_at、reviewed_by
- `reject` — pending_review → rejected附 review_note
- `unpublish` — published → draft
### PII 数据保护
- `PiiCrypto`erp-core: AES-256-GCM 加密KEK/DEK 分层管理(每租户独立 DEK
- `masking.rs`: 手机号脱敏 `138****1234`,身份证脱敏 `110****1111`
- HMAC 盲索引: 支持加密字段的等值查询(手机号、身份证号搜索)
- 生产密钥通过环境变量 `ERP__CRYPTO__KEK` 配置 KEKDEK 由 `tenant_crypto_keys` 表管理
### 事件发布25 个事件)
| 服务 | 事件类型 |
|------|---------|
| patient_service | patient.created, patient.updated |
| appointment_service | appointment.created, appointment.confirmed, appointment.cancelled |
| consultation_service | consultation.opened, consultation.closed |
| article_service | article.published, article.rejected |
| consent_service | consent.granted, consent.revoked |
| device_reading_service | device.readings.synced |
| doctor_service | doctor.online_status_changed |
| daily_monitoring_service | daily_monitoring.created |
| follow_up_service | follow_up.created, follow_up.completed, follow_up.overdue |
| health_data_service | lab_report.uploaded, health_data.critical_alert |
| points_service | points.earned, points.exchanged, points.expired |
| alert_engine | alert.triggered |
所有消费者都有幂等保护(`is_event_processed` / `mark_event_processed`)。
### 后台任务
- 随访逾期检查器 — 每 6 小时扫描 `follow_up_task` 中超过 `planned_date` 仍未完成的任务
- 积分过期清理 — 每 24 小时扫描并处理过期积分
- 预约提醒 — 每 1 小时扫描即将到来的预约并发送提醒
**不变量**: 预约创建必须走原子 CAS不能用 read-then-write
**不变量**: `patient.user_id` 允许 NULL先建档后绑定
**不变量**: `doctor_id` 在创建预约时必填(关联排班做 CAS
**不变量**: 状态流转必须带 `version` 字段(乐观锁)
## 4. 活跃问题 + 陷阱
### 当前状态: ✅ 已完成
46 实体、26 个 handler~160 个 pub fn、39 权限、25+ Web 路由页面 + 工作台组件,~27k 行 Rust 代码。状态转换验证统一到 validation 模块104 纯函数测试。24 个集成测试文件覆盖所有子域。
### 待优化
| 问题 | 级别 | 说明 |
|------|------|------|
| 文件上传基础能力 | P1 | 化验单/体检报告需要文件存储服务 |
| 健康趋势图 ECharts | P1 | 小程序已有 echarts 集成Web 端待接入 |
| 咨询导出 Excel | P2 | 后端已有 `rust_xlsxwriter` 依赖,导出端点已实现 |
### 2026-04-30 审计发现
**功能域评分**(审计报告 8 个域):
| 域 | 评分 | 关键问题 |
|----|------|---------|
| 患者管理 | 93% | 健康摘要仅 MP家庭医生管理仅 Web |
| 健康数据 | 85% | 小程序丢失晚间血压/体温/血氧字段 |
| 预约管理 | 95% | Web/MP 基本对齐 |
| 随访管理 | 88% | MP 仅列表+创建 |
| 咨询管理 | 94% | 高度对齐 |
| 内容管理 | 86% | MP 仅只读 published 文章 |
| 积分商城 | 90% | 角色分叉正常 |
| 告警系统 | 87% | 前端权限码拼写错误(`alert` vs `alerts` |
**关键审计发现**
| 发现 | 严重性 | 说明 |
|------|--------|------|
| 告警管理按钮不显示 | CRITICAL | 前端 `health.alert.manage` 缺 s应为 `health.alerts.manage` |
| 小程序晚间血压丢失 | CRITICAL | indicator_type 固定映射 `*_morning``*_evening` 从未写入 |
| 小程序透析管理缺失 | HIGH | 后端 12 路由完整,小程序 0 入口 |
| 小程序知情同意缺失 | HIGH | 后端完整,小程序 0 入口 |
| 运行时日志不足 | HIGH | 26 个 service 仅 11 处 tracing |
| 14 事件无消费者 | LOW | 发布到 EventBusSSE 推送仍有价值 |
| DTO 覆盖率 | 100% | 105 个 DTO 完整覆盖 23 个 handler |
| 调用链连通性 | 100% | Handler→Service→Entity 全部连通 |
### 全链路验证结果2026-04-25
| 链路 | API | 前端 UI | 状态 |
|------|-----|---------|------|
| 医生 CRUD | 创建/搜索/编辑 | 医护管理页面 | ✅ |
| 排班管理 | 创建/列表/日历 | 排班管理页面 | ✅ |
| 预约管理 | 创建+状态流转 | 预约列表/新建弹窗 | ✅ |
| 随访管理 | 创建→进行→完成 | 随访列表/操作 | ✅ |
| 咨询管理 | 创建会话+消息 | 咨询列表/导出 | ✅ |
| 患者详情 | 详情/编辑/标签 | 详情页+健康数据标签 | ✅ |
| 内容管理 | 文章CRUD+审核状态机 | 列表/编辑器/分类/标签 | ✅ |
## 5. 变更记录
| 日期 | 变更 |
|------|------|
| 2026-05-01 | 审计数据更新:权限码 22→39、审计发现2 CRITICAL + 3 HIGH、功能域评分、DTO/调用链 100% |
| 2026-04-28 | 全面数据刷新45 实体(+10 告警/设备/随访模板/体征小时聚合等、21 handler、39 权限、25+ Web 路由、事件系统完善25 发布/25+ 消费者、3 个后台任务、PiiCrypto 迁移到 erp-core |
| 2026-04-26 | 全面更新34 实体(+13 积分/透析/诊断/日常监测/线下活动/危急值/知情同意、16 handler、stats 统计端点、validation 统一模块83 测试、PII 加密扩展doctor_profile/dialysis_record/lab_report/diagnosis key_version |
| 2026-04-26 | 新增内容管理article_category/article_tag/article_article_tag/article_revision 4 实体、审核状态机 |
| 2026-04-25 | 全面更新为已实现状态18 实体、14 权限、全链路验证通过 |
| 2026-04-23 | 创建模块 wiki 页,设计规格确认 |