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 自动清理:
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 预留项 |