192 lines
8.5 KiB
Markdown
192 lines
8.5 KiB
Markdown
# 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_service(PII 加密) | ✓ |
|
||
| 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 预留项 |
|