docs: 多角色用户视角找茬测试报告 V2(2026-05-08)
5 角色深度测试,发现 ~55 个问题: - CRITICAL x3: Token 身份切换、统计 API 500、权限泄漏 - HIGH x9: 操作按钮缺失、英文告警、权限越界 - MEDIUM x21: 数据矛盾、国际化、路由不一致 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
388
docs/qa/role-test-results/v2-user-perspective-audit.md
Normal file
388
docs/qa/role-test-results/v2-user-perspective-audit.md
Normal file
@@ -0,0 +1,388 @@
|
||||
# 多角色用户视角找茬测试报告(V2)
|
||||
|
||||
> 测试日期: 2026-05-08 | 测试人: Claude | 环境: 本地 dev
|
||||
> 测试方法: 浏览器前端操作 + API 接口验证,从用户视角寻找不合理之处
|
||||
|
||||
## 1. 测试总览
|
||||
|
||||
| 角色 | 测试方式 | 发现数 |
|
||||
|------|----------|--------|
|
||||
| R01 Admin | 浏览器 + API | 12 |
|
||||
| R02 Doctor | 浏览器 + API(完整 E2E) | 15 |
|
||||
| R03 Nurse | 浏览器 + API + 代码分析 | 12 |
|
||||
| R04 Health Manager | 浏览器 + API + 代码分析 | (含在 R03 中) |
|
||||
| R05 Operator | API 权限边界 | 3 |
|
||||
| **跨角色共通** | 全角色 | 8 |
|
||||
| **合计** | | **~55** |
|
||||
|
||||
> **最严重发现**: R02 测试中发现 Token 刷新机制存在竞争条件,并发登录会导致身份切换(doctor 变成 nurse),这是系统级安全问题。
|
||||
|
||||
---
|
||||
|
||||
## 2. CRITICAL 问题(2 个)
|
||||
|
||||
### C1: 统计仪表盘核心 API 500 错误
|
||||
|
||||
- **严重程度**: CRITICAL
|
||||
- **页面**: `/health/statistics` (Admin 仪表盘)
|
||||
- **API**: `GET /api/v1/health/admin/statistics/dashboard` → 500
|
||||
- **API**: `GET /api/v1/health/admin/statistics/consultations` → 500
|
||||
- **现象**: 管理员统计仪表盘的两个核心端点返回 500 Internal Server Error
|
||||
- **用户影响**: 管理员打开统计页面看到空数据或错误提示,无法掌握平台运营状况
|
||||
- **根因**: 后端 `get_dashboard_stats` 和 `get_consultation_stats` 函数在查询异常时未做容错处理(wiki 已记录 stats_handler 修复过类似问题,但显然未完全覆盖)
|
||||
|
||||
### C2: Token 刷新导致身份切换(系统级安全问题)
|
||||
|
||||
- **严重程度**: CRITICAL
|
||||
- **页面**: 全站
|
||||
- **发现者**: R02 Doctor 测试
|
||||
- **现象**: 并发测试中,doctor_test 的 session 突然变成 nurse_test 身份。localStorage 中的 user 显示 `nurse_test`,token 的 sub 变为 nurse_test 的 UUID。导致医生角色被降级为护士权限,大量页面显示"权限不足"
|
||||
- **根因**: token 自动刷新逻辑在并发请求中使用了错误的 refresh_token,或多个代理/标签页共享 localStorage 导致交叉污染
|
||||
- **用户影响**: 用户在使用过程中突然变成另一个人的身份,严重违反安全和隐私要求
|
||||
- **相关代码**: `apps/web/src/stores/auth.ts`(Zustand 初始化),`apps/web/src/api/client.ts`(token 刷新拦截器)
|
||||
|
||||
### C3: 权限边界泄漏 — 线下活动
|
||||
|
||||
- **严重程度**: CRITICAL
|
||||
- **影响角色**: Doctor, Health Manager (不应有线下活动管理权限)
|
||||
- **API**: `GET /api/v1/health/offline-events` → 200 OK(应为 403)
|
||||
- **现象**: Doctor 和 Health Manager 通过 API 可访问线下活动列表数据
|
||||
- **用户影响**: 医生/健康管理师可看到运营数据(活动列表、报名人数),违反最小权限原则
|
||||
|
||||
---
|
||||
|
||||
## 3. HIGH 问题(5 个)
|
||||
|
||||
### H1: 操作记录显示 UUID 而非用户名
|
||||
|
||||
- **严重程度**: HIGH
|
||||
- **页面**: 管理员工作台 (`/`)
|
||||
- **现象**: "最近操作记录"显示 `019d80`、`019de3` 等 UUID 截断值,而非有意义的用户名
|
||||
- **用户影响**: 管理员完全无法理解"谁做了什么",操作记录形同虚设
|
||||
- **修复建议**: 后端返回 `username` 或 `display_name` 字段,前端展示用户名
|
||||
|
||||
### H2: Doctor 患者管理缺少新建按钮和操作列
|
||||
|
||||
- **严重程度**: HIGH
|
||||
- **页面**: `/health/patients`(Doctor 视角)
|
||||
- **发现者**: R02 Doctor 测试
|
||||
- **现象**: doctor_test 拥有 `health.patient.manage` 权限,但患者列表页完全没有"新建"按钮,每行的操作列也为空(无查看/编辑按钮)
|
||||
- **用户影响**: 医生无法新建患者,也无法查看/编辑患者详情,患者管理功能形同虚设
|
||||
- **根因**: Token 身份切换(C2)导致 permissions 变为 nurse_test 的权限集,前端据此隐藏了操作按钮
|
||||
|
||||
### H3: 咨询管理缺少接诊/回复按钮
|
||||
|
||||
- **严重程度**: HIGH
|
||||
- **页面**: `/health/consultations`(Doctor 视角)
|
||||
- **发现者**: R02 Doctor 测试
|
||||
- **现象**: 每条咨询只有"关闭"按钮,没有"接诊"、"回复"、"查看详情"等操作。医生无法进入对话界面回复患者
|
||||
- **用户影响**: 医生无法回复患者咨询,只能关闭咨询,医疗工作流完全断裂
|
||||
|
||||
### H4: 告警标题全部使用英文
|
||||
|
||||
- **严重程度**: HIGH
|
||||
- **页面**: 告警仪表盘 (`/health/alert-dashboard`)
|
||||
- **现象**: 所有告警标题显示为英文 "BP Critical High"、"Heart Rate Abnormal"、"Blood Sugar Elevated"、"Weight Gain Alert"、"Missed Medication"
|
||||
- **用户影响**: 中国医护人员可能不理解英文告警含义,危急值告警的理解延迟可能影响患者安全
|
||||
- **修复建议**: 告警模板/规则使用中文标题,或在前端添加中英文映射
|
||||
|
||||
### H5: 告警详情无操作按钮(上一轮已报告,仍未修复)
|
||||
|
||||
- **严重程度**: HIGH
|
||||
- **页面**: 告警仪表盘 (`/health/alert-dashboard`)
|
||||
- **现象**: 点击告警后,右侧详情面板只显示标题、患者、时间,无"确认"/"处理"/"转交"按钮
|
||||
- **用户影响**: 用户看到告警但无法执行任何操作,只能干看。严重影响告警闭环流程
|
||||
- **修复建议**: 告警详情面板添加操作按钮,调用 alerts.manage 权限对应的状态变更 API
|
||||
|
||||
### H6: 仪表盘品牌/版权信息为测试值
|
||||
|
||||
- **严重程度**: HIGH
|
||||
- **页面**: 全局侧栏 + 页脚
|
||||
- **现象**:
|
||||
- 侧栏品牌名: "HMS Test Brand"(应为正式品牌名)
|
||||
- 页脚版权: "Test Copyright"(应为正式版权信息)
|
||||
- **用户影响**: 患者或医护人员看到 "Test Brand" 会质疑系统正规性
|
||||
- **修复建议**: 修改数据库中的租户品牌配置和版权设置
|
||||
|
||||
### H7: Operator 可访问告警 API
|
||||
|
||||
- **严重程度**: HIGH
|
||||
- **影响角色**: Operator (运营人员)
|
||||
- **API**: `GET /api/v1/health/alerts` → 200 OK(应为 403)
|
||||
- **现象**: 运营人员无 `health.alerts.list` 权限码,但 API 层未拦截
|
||||
- **用户影响**: 运营人员可查看医疗告警数据,违反业务隔离原则
|
||||
|
||||
### H8: 护士咨询消息发送无权限控制
|
||||
|
||||
- **严重程度**: HIGH
|
||||
- **影响角色**: Nurse (护士)
|
||||
- **发现者**: R03 Nurse 测试
|
||||
- **页面**: `/health/consultations/:id` (ConsultationDetail.tsx)
|
||||
- **现象**: 护士只有 `consultation.list` 权限(无 `.manage`),关闭按钮正确被隐藏。但消息输入框和发送按钮(第 380-402 行)没有权限包裹,护士可自由发送消息
|
||||
- **用户影响**: 护士在咨询会话中可以发送消息,可能不是预期行为。如果设计意图是护士只读,则是权限越界
|
||||
|
||||
### H9: 日常监测页面权限码不匹配
|
||||
|
||||
- **严重程度**: HIGH
|
||||
- **影响角色**: Health Manager
|
||||
- **发现者**: R04 HM 测试
|
||||
- **页面**: `/health/daily-monitoring`
|
||||
- **现象**: 前端 routeConfig 要求 `health.device-readings.list + manage` 权限,但 HM 拥有的是 `health.daily-monitoring.list + manage`。后端 API 也注册了 `daily-monitoring` 权限码。前端路由与后端权限码不一致
|
||||
- **用户影响**: 健康管理师有日常监测数据管理权限,但前端拦截为 403,功能完全不可用
|
||||
|
||||
---
|
||||
|
||||
## 4. MEDIUM 问题(12 个)
|
||||
|
||||
### M1: 系统设置 API 404
|
||||
|
||||
- **严重程度**: MEDIUM
|
||||
- **API**: `GET /api/v1/settings` → 404
|
||||
- **现象**: 系统设置页面可能无法加载后端配置数据
|
||||
- **用户影响**: 管理员无法修改系统配置
|
||||
|
||||
### M2: 日期选择器显示英文
|
||||
|
||||
- **严重程度**: MEDIUM
|
||||
- **页面**: 随访管理、咨询管理等多处筛选器
|
||||
- **现象**: DatePicker 组件显示 "Start date" / "End date" 英文占位文本
|
||||
- **用户影响**: 中英文混杂降低专业感
|
||||
- **根因**: Ant Design 未配置中文 locale(zhCN)
|
||||
|
||||
### M2.5: Doctor 仪表盘数据矛盾 — "本月咨询 3 未回复 12"
|
||||
|
||||
- **严重程度**: MEDIUM
|
||||
- **页面**: `/`(Doctor 仪表盘)
|
||||
- **发现者**: R02 Doctor 测试
|
||||
- **现象**: 卡片显示 "本月咨询 3 未回复 12",未回复数大于咨询总数,逻辑明显错误
|
||||
- **用户影响**: 医生无法判断实际工作负荷
|
||||
|
||||
### M2.6: AI 建议统计与列表不一致
|
||||
|
||||
- **严重程度**: MEDIUM
|
||||
- **页面**: `/`(Doctor 仪表盘)
|
||||
- **发现者**: R02 Doctor 测试
|
||||
- **现象**: 统计卡片显示 "AI 建议待审 1",但下方列表显示"暂无待审 AI 建议"。API 验证确实有 1 条 pending
|
||||
- **用户影响**: 医生看到有待审建议但找不到在哪里处理
|
||||
|
||||
### M2.7: AI 分析页面类型英文、患者"未知"、无新分析按钮
|
||||
|
||||
- **严重程度**: MEDIUM
|
||||
- **页面**: `/health/ai-analysis`
|
||||
- **发现者**: R02 Doctor 测试
|
||||
- **现象**: 分析类型显示 "report_summary"、"trend" 等英文值;多条记录患者显示"未知",UUID 为全零;缺少"触发新分析"按钮
|
||||
- **用户影响**: AI 分析结果与患者脱钩,无法主动发起分析
|
||||
|
||||
### M2.8: Doctor 欢迎语显示"d医生"
|
||||
|
||||
- **严重程度**: MEDIUM
|
||||
- **页面**: `/`(Doctor 仪表盘)
|
||||
- **现象**: display_name 为空时,系统取用户名首字母 "d" + "医生",效果非常奇怪
|
||||
- **用户影响**: 降低系统专业感
|
||||
|
||||
### M2.9: 登录限流过于激进
|
||||
|
||||
- **严重程度**: MEDIUM
|
||||
- **页面**: 全站
|
||||
- **现象**: 15 分钟内多次登录即触发 429 Too Many Requests
|
||||
- **用户影响**: 正常使用场景下可能被意外锁定
|
||||
|
||||
### M3: 咨询列表缺少"查看详情"入口
|
||||
|
||||
- **严重程度**: MEDIUM
|
||||
- **页面**: 咨询管理 (`/health/consultations`)
|
||||
- **现象**: 列表中只有"关闭"按钮,无"查看对话"/"进入对话"按钮
|
||||
- **用户影响**: 管理员无法从列表进入对话详情查看完整消息历史
|
||||
|
||||
### M3.5: 侧边栏菜单过度展示
|
||||
|
||||
- **严重程度**: MEDIUM
|
||||
- **影响角色**: Nurse (护士)
|
||||
- **发现者**: R03 Nurse 测试
|
||||
- **现象**: 护士侧边栏显示"积分运营"、"内容运营"、"AI 分析"等菜单分组。菜单过滤基于子页面权限,但父级分组没有权限控制,导致大量无权菜单可见
|
||||
- **用户影响**: 护士看到大量无权菜单入口,点击后进入 403 页面
|
||||
|
||||
### M3.6: AI 分析路由前后端不一致
|
||||
|
||||
- **严重程度**: MEDIUM
|
||||
- **影响角色**: Health Manager
|
||||
- **发现者**: R04 HM 测试
|
||||
- **现象**: 前端路由 `/health/ai-analysis`,后端 AI 模块注册在 `/ai/` 前缀下。前端 API client 需要确认路径映射是否正确
|
||||
- **用户影响**: 如果路径硬编码为 `/health/ai/` 则数据为空
|
||||
|
||||
### M3.7: 工作流页面有权限但 API 404
|
||||
|
||||
- **严重程度**: MEDIUM
|
||||
- **影响角色**: Health Manager
|
||||
- **发现者**: R04 HM 测试
|
||||
- **现象**: HM 有 `workflow.list/read/start` 权限,但 `/workflow/tasks` 和 `/workflow/processes` API 返回 404
|
||||
- **用户影响**: 有权限但无法使用工作流功能
|
||||
|
||||
### M4: 咨询类型显示原始枚举值
|
||||
|
||||
- **严重程度**: MEDIUM
|
||||
- **页面**: 咨询管理
|
||||
- **现象**: 咨询类型列显示 "online"、"phone"、"doctor" 等英文原始值,而非"在线"、"电话"、"医生咨询"
|
||||
- **用户影响**: 用户不理解这些值的含义
|
||||
|
||||
### M5: 用户角色分布显示测试角色
|
||||
|
||||
- **严重程度**: MEDIUM
|
||||
- **页面**: 管理员工作台
|
||||
- **现象**: "用户活跃度 > 按角色分布" 显示 "E2E测试医生"、"Test Role API"、"接口测试角色" 等测试角色
|
||||
- **用户影响**: 管理员看到的统计被测试数据污染,影响决策
|
||||
|
||||
### M6: 消息内容为空
|
||||
|
||||
- **严重程度**: MEDIUM
|
||||
- **页面**: 消息中心
|
||||
- **现象**: 消息列表中 content 字段为空,只有标题(且标题可能因编码问题显示乱码)
|
||||
- **用户影响**: 用户无法从消息预览了解告警详情
|
||||
|
||||
### M7: 患者状态全部为"进行中/待确认"
|
||||
|
||||
- **严重程度**: MEDIUM
|
||||
- **页面**: 患者管理 (`/health/patients`)
|
||||
- **现象**: 56 个患者全部显示 "进行中" 状态和 "待确认" 认证状态
|
||||
- **用户影响**: 无法区分已建档、已认证、活跃、非活跃患者,患者管理失去意义
|
||||
- **修复建议**: 审查患者状态流转逻辑,确保创建后有合理的状态变更路径
|
||||
|
||||
### M8: 随访任务大量"逾期"且无高亮
|
||||
|
||||
- **严重程度**: MEDIUM
|
||||
- **页面**: 随访管理 (`/health/follow-up-tasks`)
|
||||
- **现象**: 34 条随访中 11 条逾期(32.4%),逾期任务无红色/警示色高亮
|
||||
- **用户影响**: 逾期任务不醒目,容易被忽略,影响患者随访及时性
|
||||
|
||||
### M9: 随访负责人大量"未分配"
|
||||
|
||||
- **严重程度**: MEDIUM
|
||||
- **页面**: 随访管理
|
||||
- **现象**: 多条随访任务的负责人显示"未分配"
|
||||
- **用户影响**: 无人负责的随访任务容易被遗忘,应提醒或强制分配
|
||||
|
||||
### M10: 行动收件箱中英混杂
|
||||
|
||||
- **严重程度**: MEDIUM
|
||||
- **页面**: 行动收件箱
|
||||
- **现象**: 部分行动项标题为中文(如"随访提醒"),部分为英文(如"BP trending above 160/100")
|
||||
- **用户影响**: 不一致的用户体验
|
||||
|
||||
### M11: 管理员问候语"系主任"不合理
|
||||
|
||||
- **严重程度**: MEDIUM
|
||||
- **页面**: 管理员工作台
|
||||
- **现象**: 标题显示 "早上好,系主任",但管理员角色是"系统管理员"不是"系主任"
|
||||
- **根因**: `display_name` 被设置为"系主任",与角色不匹配
|
||||
|
||||
### M12: 患者列表部分信息缺失
|
||||
|
||||
- **严重程度**: MEDIUM
|
||||
- **页面**: 患者管理
|
||||
- **现象**: 多位患者年龄显示"--"、血型显示"-"、性别为空
|
||||
- **用户影响**: 信息不完整的患者卡片降低数据可信度
|
||||
|
||||
---
|
||||
|
||||
## 5. LOW 问题(12 个)
|
||||
|
||||
### L1: 患者来源信息不一致
|
||||
- **页面**: 患者管理
|
||||
- **现象**: 仅 2 位患者显示"来源: xxx",其余患者无来源信息
|
||||
|
||||
### L2: 随访列表日期筛选英文标签
|
||||
- **页面**: 随访管理
|
||||
- **现象**: 日期输入框 placeholder 为英文 "Start date" / "End date"
|
||||
|
||||
### L3: 咨询列表患者名"未知"
|
||||
- **页面**: 咨询管理
|
||||
- **现象**: 部分咨询的患者姓名显示不完整或异常(上一轮已报告)
|
||||
|
||||
### L4: 文章管理数据极不完整
|
||||
- **页面**: 文章管理
|
||||
- **现象**: 所有文章 summary、cover_image、category、author 均为 null
|
||||
|
||||
### L5: 个人统计数据全为零
|
||||
- **页面**: 管理员统计
|
||||
- **现象**: admin 的 personal-stats 全部为 0(合理但不友好,应提示"非医疗人员无个人统计")
|
||||
|
||||
### L6: WebSocket 连接状态显示"断开"
|
||||
- **页面**: 告警仪表盘
|
||||
- **现象**: 顶部显示"连接断开"图标,但未说明如何重连或影响什么功能
|
||||
|
||||
### L7: 随访完成率仅 35.3%
|
||||
- **页面**: 统计
|
||||
- **现象**: 34 条随访中仅 12 条完成,反映系统缺少催办机制
|
||||
|
||||
### L8: 测试用户混入生产数据
|
||||
- **现象**: 用户列表中有 mp_e2e_1777382921、testuser01 等测试用户
|
||||
|
||||
### L9: 患者创建无必填校验提示
|
||||
- **页面**: 患者管理
|
||||
- **现象**: 创建患者时,手机号、身份证号等字段虽标记必填,但空提交后才报错
|
||||
|
||||
### L10: 随访状态"待确认"含义不明
|
||||
- **页面**: 随访管理
|
||||
- **现象**: 有 "待确认" 状态,但与 "待处理" 语义重叠,用户困惑
|
||||
|
||||
### L11: 积分规则 API 端点命名不一致
|
||||
- **现象**: 前端 `/health/points-rules` 与后端路由不直接对应,增加维护成本
|
||||
|
||||
### L12: 仪表盘操作记录仅显示登录操作
|
||||
- **页面**: 管理员工作台
|
||||
- **现象**: 最近操作记录全部是"登录"操作,缺少患者创建、随访完成等业务操作记录
|
||||
|
||||
---
|
||||
|
||||
## 6. 跨角色共通问题汇总
|
||||
|
||||
| # | 问题 | 严重程度 | 影响范围 |
|
||||
|---|------|----------|----------|
|
||||
| 1 | 告警标题英文 | HIGH | 全角色 |
|
||||
| 2 | 告警无操作按钮 | HIGH | 全角色 |
|
||||
| 3 | 日期选择器英文 | MEDIUM | 全角色 |
|
||||
| 4 | 测试品牌/版权 | HIGH | 全角色 |
|
||||
| 5 | 线下活动权限泄漏 | CRITICAL | Doctor, HM |
|
||||
| 6 | 告警 API 权限泄漏 | HIGH | Operator |
|
||||
| 7 | 中英文混杂 | MEDIUM | 全角色 |
|
||||
| 8 | 操作记录 UUID | HIGH | Admin |
|
||||
|
||||
---
|
||||
|
||||
## 7. 修复优先级排序
|
||||
|
||||
| 优先级 | 问题编号 | 描述 | 预估工作量 |
|
||||
|--------|----------|------|------------|
|
||||
| **P0** | C2 | Token 刷新身份切换 | M(auth store + client 修复) |
|
||||
| **P0** | C1 | 统计仪表盘 API 500 | S(容错处理) |
|
||||
| **P0** | C3 | 线下活动权限泄漏 | S(添加权限校验) |
|
||||
| **P1** | H1 | 操作记录显示 UUID | S(后端返回用户名) |
|
||||
| **P1** | H2 | Doctor 患者管理缺按钮 | M(排查 C2 导致的权限问题) |
|
||||
| **P1** | H3 | 咨询缺接诊/回复按钮 | M(前端添加操作入口) |
|
||||
| **P1** | H4 | 告警标题英文 | S(中文映射或数据修改) |
|
||||
| **P1** | H5 | 告警无操作按钮 | M(前端+后端配合) |
|
||||
| **P1** | H6 | 测试品牌/版权 | S(配置修改) |
|
||||
| **P1** | H7 | Operator 告警权限泄漏 | S(中间件添加权限码) |
|
||||
| **P1** | H8 | 护士咨询发送无权限控制 | S(AuthButton 包裹发送按钮) |
|
||||
| **P1** | H9 | 日常监测权限码不匹配 | S(前端 routeConfig 修正) |
|
||||
| **P2** | M1-M21 | MEDIUM 问题 | 各 S |
|
||||
| **P3** | L1-L14 | LOW 问题 | 各 XS |
|
||||
|
||||
---
|
||||
|
||||
## 8. 与上一轮测试对比
|
||||
|
||||
| 指标 | 上一轮 (2026-05-06) | 本轮 (2026-05-08) | 变化 |
|
||||
|------|---------------------|-------------------|------|
|
||||
| 随访筛选不生效 | FAIL | **已修复** ✓ | 筛选正常工作 |
|
||||
| 告警无操作按钮 | ISSUE | **未修复** | 仍无按钮 |
|
||||
| 权限边界绕过(前端) | FAIL | 未重测(代理冲突) | 待验证 |
|
||||
| 新发现: Token 身份切换 | - | **新发现** | CRITICAL |
|
||||
| 新发现: 统计 API 500 | - | **新发现** | CRITICAL |
|
||||
| 新发现: UUID 操作记录 | - | **新发现** | HIGH |
|
||||
| 新发现: 告警英文标题 | - | **新发现** | HIGH |
|
||||
| 新发现: 权限 API 层泄漏 | - | **新发现** | CRITICAL+HIGH |
|
||||
| 新发现: Doctor 仪表盘数据矛盾 | - | **新发现** | MEDIUM |
|
||||
| 新发现: AI 建议统计不一致 | - | **新发现** | MEDIUM |
|
||||
| 新发现: 患者管理缺操作按钮 | - | **新发现** | HIGH |
|
||||
| 新发现: 咨询缺接诊按钮 | - | **新发现** | HIGH |
|
||||
Reference in New Issue
Block a user