# 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 预留项 |