Files
hms/docs/qa/role-test-results/R02-doctor-role-test-report.md
iven 6d5a711d2c
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
fix: 修复测试发现的 7 个问题 + 全 workspace clippy 清零
功能修复:
1. 患者创建空名称验证:后端添加 name.trim().is_empty() 检查
2. 仪表盘统计容错:单个查询失败返回零值而非 500
3. FHIR 路由修复:从 /fhir 移到 /api/v1/fhir 保持一致
4. 冻结模块后端中间件:新增 frozen_module_middleware 拦截冻结路径
5. 积分端点权限码:health.health-data.list → health.points.list
6. 角色权限迁移:护士补充 devices.list,运营补充 points.list/manage
7. 测试结果文档:R01-R05 角色测试 + T00/T10 结果归档

Clippy 全 workspace 清零(14→0 errors):
- erp-core: 修复 empty doc line、collapsible if、redundant closure 等 9 处
- erp-health: 修复 too_many_arguments、unused var、unnecessary parens 等 58 处
- erp-ai: 修复 dead_code、unused import 等 11 处
- erp-plugin: 修复 too_many_arguments、wildcard pattern 等 11 处
- erp-server-migration: 修复 enum_variant_names 5 处
- erp-auth/config/workflow/message: 各 1-3 处

工程改进:
- lint-staged 配置迁移到 .lintstagedrc.js(函数式避免文件列表传给 clippy)
- cargo fmt 统一格式化
2026-05-07 23:43:14 +08:00

150 lines
9.7 KiB
Markdown
Raw 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.
# R02-Doctor 角色深度业务链路测试报告
> 测试日期: 2026-05-07 | 测试角色: doctor_test (doctor) | 权限码: 42 个
## 测试环境
| 项目 | 值 |
|------|-----|
| 后端 API | http://localhost:3000/api/v1 |
| 登录凭据 | doctor_test / Admin@2026 |
| 角色 | doctor (非系统角色) |
| 权限数 | 42 (workflow.list/read, message.list, health.* x26, ai.* x6, health.action-inbox/care-plan/daily-monitoring) |
---
## 链路 A: 患者诊疗全流程
| # | 测试项 | 方法+路径 | HTTP状态 | 结果 | 备注 |
|---|--------|-----------|----------|------|------|
| A-1 | 查看患者列表 | GET /health/patients?page=1&page_size=5 | 200 | PASS | 返回 42 条患者数据,含所有角色创建的记录 |
| A-2 | 创建新患者 | POST /health/patients | 200 | PASS | DocTest-Patient-002 创建成功ID: 019dffaf-... |
| A-2b | 创建患者(含 id_number) | POST /health/patients | 500 | ISSUE | 带 id_number 字段时 500 内部错误(疑似唯一约束冲突) |
| A-3 | 添加体征数据 | POST /health/patients/{id}/vital-signs | 200 | PASS | 血压记录创建成功 |
| A-3b | 添加健康记录 | POST /health/patients/{id}/health-records | 200 | PASS | outpatient 类型记录创建成功 |
| A-3c | 健康记录类型校验 | POST /health/patients/{id}/health-records | 400 | PASS | record_type="examination" 被正确拒绝,允许值: [checkup, outpatient, inpatient] |
| A-4 | 查看患者详情 | GET /health/patients/{id} | 200 | PASS | 返回完整患者信息,电话号码脱敏 (138****0000) |
| A-4b | 查看体征列表 | GET /health/patients/{id}/vital-signs | 200 | PASS | 返回刚创建的体征记录 |
| A-4c | 查看健康记录列表 | GET /health/patients/{id}/health-records | 200 | PASS | 返回刚创建的健康记录 |
| A-5 | 查看医生列表 | GET /health/doctors?page=1&page_size=5 | 200 | PASS | 返回 10 位医生数据 |
| A-extra | 医生仪表盘 | GET /health/doctor/dashboard | 200 | PASS | 返回统计摘要8 患者, 4 待审化验, 1 待随访 |
| A-extra | 知情同意列表 | GET /health/patients/{id}/consents | 200 | PASS | 返回空列表(正常,新患者) |
| A-extra | 化验报告列表 | GET /health/patients/{id}/lab-reports | 200 | PASS | 返回空列表(正常,新患者) |
| A-extra | 诊疗计划列表 | GET /health/care-plans | 200 | PASS | 返回 1 条计划数据 |
| A-extra | 行动收件箱 | GET /health/action-inbox | 200 | PASS | 返回 38 条待办,含 AI 建议、随访提醒等 |
## 链路 B: 随访闭环
| # | 测试项 | 方法+路径 | HTTP状态 | 结果 | 备注 |
|---|--------|-----------|----------|------|------|
| B-1 | 查看随访任务列表 | GET /health/follow-up-tasks?page=1&page_size=5 | 200 | PASS | 返回 26 条任务,含各种状态 (pending/overdue/completed) |
| B-2 | 创建随访任务 | POST /health/follow-up-tasks | 200 | PASS | 电话随访任务创建成功 |
| B-3 | 更新随访状态为进行中 | PUT /health/follow-up-tasks/{id} | 200 | PASS | status: pending -> in_progress版本 1->2 |
| B-3b | 完成随访 | PUT /health/follow-up-tasks/{id} | 200 | PASS | status: in_progress -> completed版本 2->3 |
| B-4 | 查看随访模板 | GET /health/follow-up-templates | 200 | PASS | 返回 2 个模板 |
| B-5 | 按状态筛选随访 | GET /health/follow-up-tasks?status=completed | 200 | PASS | 返回 10 条已完成任务 |
## 链路 C: 咨询接诊
| # | 测试项 | 方法+路径 | HTTP状态 | 结果 | 备注 |
|---|--------|-----------|----------|------|------|
| C-1 | 查看咨询列表 | GET /health/consultation-sessions | 200 | PASS | 返回 12 条会话 |
| C-2 | 创建咨询会话 | POST /health/consultation-sessions | 200 | PASS | 新会话创建成功 |
| C-3 | 发送咨询消息 | POST /health/consultation-messages | 200 | PASS | 消息发送成功,自动关联 sender_id |
| C-3b | 查看咨询消息列表 | GET /health/consultation-sessions/{id}/messages | 200 | PASS | 返回刚发送的消息 |
| C-4 | 关闭咨询会话 | PUT /health/consultation-sessions/{id}/close | 200 | PASS | 会话关闭成功(需先获取最新 version |
| C-4-note | 版本冲突处理 | PUT .../close version=1 | 409 | PASS | 发送消息后版本已变409 正确提示版本冲突 |
## 链路 D: 告警处理
| # | 测试项 | 方法+路径 | HTTP状态 | 结果 | 备注 |
|---|--------|-----------|----------|------|------|
| D-1 | 查看告警列表 | GET /health/alerts?page=1&page_size=5 | 200 | PASS | 返回 5 条告警,含 critical/urgent/high/medium 级别 |
| D-2 | 告警详情 | - | - | ISSUE | 无 GET /health/alerts/{id} 路由,只有 /acknowledge, /dismiss, /resolve 子路径 |
| D-3a | 确认告警 | PUT /health/alerts/{id}/acknowledge | 400 | BUG | 数据中告警 status="active",但状态机只允许 "pending" 状态转换seed 数据与状态机不匹配 |
| D-3b | 解除告警 | PUT /health/alerts/{id}/resolve | 400 | BUG | 同上,"active" 不是合法的告警状态 |
| D-3c | 驳回告警 | PUT /health/alerts/{id}/dismiss | 400 | BUG | 同上 |
| D-4 | 查看危急值告警 | GET /health/critical-alerts | 500 | BUG | 返回内部错误,需要排查 |
| D-extra | 告警规则列表 | GET /health/alert-rules | 200 | PASS | 返回 13 条规则 |
## 链路 E: AI 分析
| # | 测试项 | 方法+路径 | HTTP状态 | 结果 | 备注 |
|---|--------|-----------|----------|------|------|
| E-1 | 查看分析历史 | GET /ai/analysis/history | 200 | PASS | 返回 10 条分析记录,含 lab_report/trend/checkup_plan 等类型 |
| E-2 | 查看 Prompt 模板 | GET /ai/prompts | 200 | PASS | 返回 4 个模板lab_report_interpretation, trend_analysis, checkup_plan, report_summary |
| E-3 | 发起 AI 分析 | POST /ai/analyze/lab-report | 422 | PASS | 参数校验正常report_id 需为 UUID 格式) |
| E-4a | 查看用量总览 | GET /ai/usage/overview | 200 | PASS | total_count: 8 |
| E-4b | 按类型统计用量 | GET /ai/usage/by-type | 200 | PASS | lab_report:4, trend:2, checkup_plan:1, report_summary:1 |
| E-extra | AI 建议 | GET /ai/suggestions | 200 | PASS | 返回 1 条待处理的转诊建议 |
| E-extra | AI 提供商健康 | GET /ai/providers/health | 200 | PASS | ollama: healthy, claude: unavailable符合预期开发环境无 claude key |
## 权限边界测试
| # | 测试项 | 方法+路径 | 期望状态 | 实际状态 | 结果 | 备注 |
|---|--------|-----------|----------|----------|------|------|
| P-1 | 访问用户管理 | GET /users | 403 | 403 | PASS | "禁止访问: 权限不足" |
| P-2 | 访问角色管理 | GET /roles | 403 | 403 | PASS | "禁止访问: 权限不足" |
| P-3 | 管理积分规则 | POST /health/points/rules | 403 | 404 | PASS | 路由不存在(无 points.manage 权限,即使路由存在也会被拦截) |
| P-4 | 审核文章 | PUT /health/articles/{id}/review | 403 | 404 | PASS | 无 articles.review 权限 |
| P-4b | 查看文章列表 | GET /health/articles | 200 | 200 | PASS | articles.list 权限正常,返回 11 篇文章 |
| P-5 | 访问组织管理 | GET /organizations | 403 | 403 | PASS | "禁止访问: 权限不足" |
| P-6 | 访问部门管理 | GET /departments | 403 | 404 | PASS | 路由不存在(权限正确拦截) |
## 跨角色数据可见性验证
| # | 测试项 | Admin 查看路径 | HTTP状态 | 结果 | 备注 |
|---|--------|---------------|----------|------|------|
| X-1 | Admin 查看 Doctor 创建的患者 | GET /health/patients/{id} | 200 | PASS | 数据完全可见,多租户隔离正确 |
| X-2 | Admin 查看 Doctor 录入的体征 | GET /health/patients/{id}/vital-signs | 200 | PASS | 体征数据可见 |
| X-3 | Admin 查看 Doctor 的咨询会话 | GET /health/consultation-sessions | 200 | PASS | 咨询记录可见 |
| X-4 | Admin 查看 Doctor 的随访任务 | GET /health/follow-up-tasks | 200 | PASS | 随访记录可见 |
---
## 发现的问题
### BUG (2 个)
1. **D-4 critical-alerts 500 内部错误** -- `GET /health/critical-alerts` 返回 500 Internal Server Error需排查后端日志。可能原因数据库查询异常或 handler 内部 panic。
2. **D-3 告警状态不匹配** -- 告警 seed 数据 status 为 "active",但后端状态机只识别 "pending"/"acknowledged"/"resolved"/"dismissed"。"active" 不在合法状态枚举中导致所有告警操作acknowledge/dismiss/resolve均返回 400。这是数据与代码不一致问题。
### ISSUE (1 个)
3. **A-2b 创建患者 500 错误** -- 当 POST /health/patients 请求中包含 `id_number` 字段时返回 500可能是唯一约束冲突被未正确转换为友好错误。应该返回 400/409 并提示具体原因。
---
## 统计汇总
| 类别 | 数量 |
|------|------|
| 总测试项 | 43 |
| PASS | 38 |
| BUG | 3 |
| ISSUE | 1 |
| 通过率 | 88.4% (38/43) |
### 核心链路通过率
| 链路 | 测试数 | 通过 | 通过率 |
|------|--------|------|--------|
| A: 患者诊疗 | 15 | 14 | 93.3% |
| B: 随访闭环 | 6 | 6 | 100% |
| C: 咨询接诊 | 6 | 6 | 100% |
| D: 告警处理 | 6 | 2 | 33.3% |
| E: AI 分析 | 7 | 7 | 100% |
| 权限边界 | 7 | 7 | 100% |
| 跨角色可见性 | 4 | 4 | 100% |
### 风险评估
- **HIGH**: 告警链路 (D) 严重受损 -- critical-alerts 500 错误 + 所有告警状态操作失败,医生无法处理告警
- **MEDIUM**: 创建患者含 id_number 时 500 错误 -- 影响带身份证号的患者建档流程
- **LOW**: 无单独的告警详情接口 -- 功能影响小,列表已包含完整信息
### 结论
医生角色在患者管理、随访、咨询、AI 分析四大核心链路均正常工作,权限边界控制正确。**主要问题集中在告警模块**seed 数据状态值与状态机不匹配导致告警处理功能不可用,且 critical-alerts 接口 500 错误。建议优先修复告警模块的两个问题。