Files
hms/docs/audits/02-backend-integrity.md
iven d712ad78c3 docs: 审计报告(8 份) + 讨论记录(4 份)
审计报告: 基线快照/功能清单/后端完整性/事件系统/参数配置/
差距模式/错误处理/测试覆盖/审计总结报告
讨论记录: 设备管线/端到端测试/三端审计/工作台重构
2026-05-03 19:32:15 +08:00

192 lines
8.5 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.
# HMS 功能审计 — Phase 2: 后端完整性审计
> 日期: 2026-04-30 | 审计范围: 后端 Rust 代码
## 总览
| 指标 | 值 |
|------|-----|
| Handler 函数 | 169 个23 个文件) |
| Service 函数 | 180 个26 个文件) |
| Entity | 45 个46 个文件含 mod.rs |
| 路由 | 121 个erp-health |
| 编译警告 | 40 个 |
| 死代码抑制 | 4 处 |
| TODO 注释 | 4 处 |
| 生产代码 unwrap() | 10 处 |
---
## 1. 死代码分析
### 1.1 `#[allow(dead_code)]` 抑制4 处)
| 文件 | 行号 | 抑制内容 | 是否有调用者 | 判定 |
|------|------|---------|------------|------|
| `erp-auth/src/service/wechat_service.rs` | 43 | `unionid` 字段 | 微信 API 返回但不使用 | 保留合理(未来可能用于 UnionID 登录) |
| `erp-server/src/middleware/rate_limit.rs` | 27 | `RateLimitConfig` 整个 struct | 当前使用环境变量配置 | 保留合理(预留结构化配置) |
| `erp-plugin/src/host.rs` | 42 | `tenant_id` 字段 | HostState 中的 tenant_id | **建议清理**:已在 data_service 中改为函数参数传递 |
| `erp-plugin/src/host.rs` | 44 | `user_id` 字段 | HostState 中的 user_id | **建议清理**:同上 |
### 1.2 编译器死代码警告9 处未抑制)
| 文件 | 警告内容 | 严重性 |
|------|---------|--------|
| erp-health 多处 | `message`, `usage`, `input_tokens`, `output_tokens` 字段 | LOW — DTO 响应字段,前端可能使用 |
| erp-health | `RefRow` struct 从未构造 | MEDIUM — 可能是重构残留 |
| erp-health | `check_result`, `total` 字段 | LOW — 可能用于序列化 |
| erp-server | `AnalyticsEvent.timestamp` 字段 | LOW — 预留字段 |
### 1.3 未使用导入18 处)
分布在 6 个 crate 中,建议运行 `cargo fix` 自动清理:
```bash
cargo fix --lib -p erp-health --allow-dirty
cargo fix --lib -p erp-plugin --allow-dirty
cargo fix --lib -p erp-ai --allow-dirty
```
### 1.4 TODO 注释4 处)
| 文件 | 行号 | 内容 | 优先级 |
|------|------|------|--------|
| `erp-health/src/event.rs` | 50 | PATIENT_VERIFIED/PATIENT_DECEASED 未实现 | KNOWN |
| `erp-auth/src/handler/wechat_handler.rs` | 45 | 多租户微信登录租户解析策略 | P2 |
| `erp-auth/src/handler/wechat_handler.rs` | 76 | 同上 | P2 |
| `erp-plugin/src/data_service.rs` | 1073 | 未来版本添加 Redis 缓存层 | P3 |
---
## 2. 调用链完整性
### 2.1 Handler → Service 覆盖率
| Handler 文件 | Handler 函数数 | 对应 Service | 覆盖率 |
|-------------|--------------|-------------|--------|
| patient_handler | 17 | patient_service | 100% |
| health_data_handler | 18 | health_data_service + trend_service | 100% |
| points_handler | 28 | points_service + stats_service | 100% |
| stats_handler | 9 | stats_service | 100% |
| follow_up_handler | 10 | follow_up_service | 100% |
| article_handler | 11 | article_service | 100% |
| consultation_handler | 9 | consultation_service | 100% |
| doctor_handler | 5 | doctor_service | 100% |
| appointment_handler | 8 | appointment_service | 100% |
| follow_up_template_handler | 5 | follow_up_template_service | 100% |
| medication_record_handler | 5 | medication_record_service | 100% |
| medication_reminder_handler | 4 | medication_reminder_service | 100% |
| daily_monitoring_handler | 5 | daily_monitoring_service | 100% |
| diagnosis_handler | 4 | diagnosis_service | 100% |
| device_reading_handler | 3 | device_reading_service | 100% |
| device_handler | 2 | device_service | 100% |
| consent_handler | 3 | consent_service | 100% |
| alert_handler | 4 | alert_service | 100% |
| alert_rule_handler | 4 | alert_rule_service | 100% |
| critical_alert_handler | 3 | critical_alert_service | 100% |
| critical_value_threshold_handler | 4 | critical_value_threshold_service | 100% |
| article_category_handler | 4 | article_category_service | 100% |
| article_tag_handler | 4 | article_tag_service | 100% |
**结论Handler → Service 覆盖率 100%。每个 handler 都有对应的 service 实现。**
### 2.2 Service → Entity 覆盖率
| Entity | 对应 Service | 状态 |
|--------|-------------|------|
| patient | patient_service | ✓ |
| patient_family_member | patient_service | ✓ |
| patient_tag | patient_service | ✓ |
| patient_tag_relation | patient_service | ✓ |
| patient_doctor_relation | patient_service | ✓ |
| patient_devices | device_service | ✓ |
| blind_index | patient_servicePII 加密) | ✓ |
| consent | consent_service | ✓ |
| doctor_profile | doctor_service | ✓ |
| doctor_schedule | doctor_service | ✓ |
| health_record | health_data_service | ✓ |
| vital_signs | health_data_service | ✓ |
| vital_signs_hourly | health_data_service | ✓ |
| lab_report | health_data_service | ✓ |
| health_trend | trend_service | ✓ |
| diagnosis | diagnosis_service | ✓ |
| medication_record | medication_record_service | ✓ |
| medication_reminder | medication_reminder_service | ✓ |
| device_readings | device_reading_service | ✓ |
| appointment | appointment_service | ✓ |
| follow_up_task | follow_up_service | ✓ |
| follow_up_record | follow_up_service | ✓ |
| follow_up_template | follow_up_template_service | ✓ |
| follow_up_template_field | follow_up_template_service | ✓ |
| consultation_session | consultation_service | ✓ |
| consultation_message | consultation_service | ✓ |
| article | article_service | ✓ |
| article_category | article_category_service | ✓ |
| article_tag | article_tag_service | ✓ |
| article_article_tag | article_service | ✓ |
| article_revision | article_service | ✓ |
| alerts | alert_service | ✓ |
| alert_rules | alert_rule_service | ✓ |
| critical_alert | critical_alert_service | ✓ |
| critical_alert_response | critical_alert_service | ✓ |
| critical_value_threshold | critical_value_threshold_service | ✓ |
| points_account | points_service | ✓ |
| points_rule | points_service | ✓ |
| points_product | points_service | ✓ |
| points_order | points_service | ✓ |
| points_transaction | points_service | ✓ |
| points_checkin | points_service | ✓ |
| offline_event | points_service | ✓ |
| offline_event_registration | points_service | ✓ |
| daily_monitoring | daily_monitoring_service | ✓ |
**结论Entity → Service 覆盖率 100%。45 个实体全部有对应的 service 操作。**
---
## 3. unwrap() 调用审计
### 生产代码中的 unwrap()10 处)
| 模式 | 次数 | 安全性 |
|------|------|--------|
| `active.version.unwrap() + 1` | 9 处 | **安全** — version 从 DB 查询获取SeaORM ActiveModel 保证非 None |
| `existing.unwrap().into()` | 1 处 | **需审查** — device_reading_service.rs:192 |
device_reading_service.rs:192 上下文:在 `update()` 函数中,`existing` 来自 `find_by_id` 查询。如果调用 `update()` 时记录不存在,会 panic。**建议**:改用 `ok_or(AppError::NotFound)` 模式。
### 测试代码中的 unwrap()20+ 处)
全部在 `#[cfg(test)]` 块中,仅用于测试断言,无安全风险。
---
## 4. ErpModule Trait 覆盖率
| 模块 | on_startup | on_tenant_created | on_tenant_deleted | permissions | health_check | 等级 |
|------|-----------|-------------------|-------------------|-------------|-------------|------|
| erp-health | **5 个后台任务 + 事件监听** | **种子数据** | **软删除** | **56 个** | 默认 | **FULL** |
| erp-ai | 默认 | 默认 | 默认 | 6 个 | 默认 | PARTIAL |
| erp-dialysis | 默认 | 默认 | 默认 | 5 个 | 默认 | PARTIAL |
| erp-auth | 默认 | 默认 | 默认 | 默认 | 默认 | MINIMAL |
| erp-config | 默认 | 默认 | 默认 | 默认 | 默认 | MINIMAL |
| erp-workflow | 默认 | 默认 | 默认 | 默认 | 默认 | MINIMAL |
| erp-message | 默认 | 默认 | 默认 | 默认 | 默认 | MINIMAL |
| erp-plugin | 默认 | 默认 | 默认 | 默认 | 默认 | MINIMAL |
**说明**
- MINIMAL 不一定代表缺陷 — auth/config/workflow/message 的权限通过中间件和 JWT claims 管控,不需要声明 PermissionDescriptor
- 只有业务模块health/ai/dialysis需要声明细粒度权限码因为它们的路由使用 `require_permission` 中间件
---
## 5. 后端完整性评分
| 检查项 | 评分 | 说明 |
|--------|------|------|
| 代码存在性 | 100% | 所有实体/服务/处理器 完整 |
| 调用链连通性 | 100% | 处理器→服务→实体 全部连通 |
| 死代码率 | 2% | 4 处抑制 + 9 处警告 / 462 文件 |
| unwrap() 风险 | 98% | 仅 1 处 device_reading_service 可能 panic |
| Trait 实现完整度 | 37.5% | 3/8 模块有实质实现(其余使用默认值) |
| TODO 债务 | LOW | 4 处,均为已知的 P2/P3 预留项 |