gongxiangp2/docs/shadow-testing-guide.md
chenpei ea9076df45 feat: 实现统一的下载错误处理系统并修复产品全案数据库Schema
- 创建统一的下载错误处理模块 (lib/download-errors.ts)
- 实现13种错误类型分类和中文错误消息
- 后端统一使用 createDownloadError 创建标准化错误响应
- 前端统一使用 parseDownloadError 解析错误并显示
- 修复正式系统数据库Schema,添加产品全案相关字段和表
- 执行数据库迁移:添加 task_no, task_status, task_fetched_at 字段
- 创建 material_assets, api_keys, api_call_logs 表
2026-01-05 17:52:42 +08:00

8.3 KiB
Raw Blame History

影子系统测试指南 - 阶段一

测试环境: 影子系统(端口 5320,数据库 lobechat_stage)
测试阶段: 阶段一 - 用户状态管理
测试日期: 2025-12-27


📋 测试前准备

1. 确认影子系统配置

检查项:

  • 影子系统数据库:lobechat_stage
  • 影子系统端口:5320
  • 影子系统URL:http://192.168.58.20:5320

2. 备份数据库

# 备份影子系统数据库
pg_dump -h 192.168.58.20 -U gongxiangpan -d lobechat_stage > backup_shadow_$(date +%Y%m%d_%H%M%S).sql

3. 更新 Schema

# 在项目根目录执行
npx prisma db push

# 确认 Schema 已更新
npx prisma studio

4. 运行迁移脚本

# 运行用户状态迁移脚本
npx tsx scripts/migrate-user-status-safe.ts

5. 验证迁移结果

# 运行验证脚本
npx tsx scripts/verify-migration.ts 1

🧪 测试用例

测试用例 1: 用户登录 - 正常用户

测试步骤:

  1. 访问 http://192.168.58.20:5320/login
  2. 使用已激活的用户账号登录
  3. 检查是否能成功登录

预期结果:

  • ✅ 登录成功
  • ✅ 用户状态为 active
  • ✅ lastLoginAt 字段已更新
  • ✅ loginCount 字段已递增
  • ✅ lastLoginIp 字段已记录(如果有)

验证方法:

-- 查询用户登录信息
SELECT id, username, status, isActive, lastLoginAt, loginCount, lastLoginIp 
FROM users 
WHERE username = '测试用户名';

测试用例 2: 用户登录 - 未激活用户

测试步骤:

  1. 访问登录页面
  2. 使用未激活的用户账号登录(isActive=false, status='pending')

预期结果:

  • ❌ 登录失败
  • ✅ 提示"账号未激活,请联系管理员"

测试用例 3: 用户登录 - 钉钉登录

测试步骤:

  1. 访问钉钉登录页面
  2. 使用钉钉扫码登录
  3. 检查新用户创建

预期结果:

  • ✅ 新用户创建时 status='pending'
  • ✅ 新用户创建时 isActive=false
  • ✅ 已激活用户登录后,审计字段已更新

测试用例 4: 管理员切换用户状态

测试步骤:

  1. 以管理员身份登录
  2. 进入用户管理页面
  3. 切换用户激活状态(使用旧API:isActive)
  4. 切换用户状态(使用新API:status)

预期结果:

  • ✅ 使用 isActive 参数时,同时更新 status 字段
  • ✅ 使用 status 参数时,同时更新 isActive 字段
  • ✅ 状态切换后,用户登录行为正确

API 测试:

# 测试旧API(向后兼容)
curl -X POST http://192.168.58.20:5320/api/admin/users/toggle-active \
  -H "Content-Type: application/json" \
  -d '{"userId": "用户ID", "isActive": true}'

# 测试新API
curl -X POST http://192.168.58.20:5320/api/admin/users/toggle-active \
  -H "Content-Type: application/json" \
  -d '{"userId": "用户ID", "status": "active"}'

测试用例 5: 用户状态流转

测试步骤:

  1. 创建新用户(status='pending')
  2. 管理员激活用户(status='active')
  3. 管理员暂停用户(status='suspended')
  4. 管理员恢复用户(status='active')
  5. 管理员归档用户(status='archived')

预期结果:

  • ✅ 每个状态切换都正确
  • ✅ archived 状态时,archivedAt 字段已设置
  • ✅ 从 archived 恢复时,archivedAt 字段已清除
  • ✅ 每个状态下的登录行为正确

测试用例 6: 用户列表API

测试步骤:

  1. 以管理员身份登录
  2. 访问用户列表API:/api/admin/users
  3. 检查返回的数据

预期结果:

  • ✅ 返回数据包含 status 字段
  • ✅ 返回数据包含 lastLoginAt 字段
  • ✅ 返回数据包含 loginCount 字段
  • ✅ 返回数据包含 archivedAt 字段
  • ✅ 返回数据包含 isActive 字段(向后兼容)

测试用例 7: 数据一致性验证

测试步骤:

  1. 运行验证脚本
  2. 检查验证结果

预期结果:

  • ✅ 所有用户的 status 字段都已设置
  • ✅ isActive=true 的用户 status='active'
  • ✅ isActive=false 的用户 status='pending'(或 suspended/archived)
  • ✅ 没有不一致的数据

验证命令:

npx tsx scripts/verify-migration.ts 1

🐛 问题记录

发现问题时,请记录到 docs/shadow-testing-issues.md

记录格式:

### 问题 #X: [问题标题]

**发现时间**: YYYY-MM-DD HH:MM  
**测试阶段**: 阶段一  
**严重程度**: 🔴 高 / 🟡 中 / 🟢 低

**问题描述**:
详细描述问题现象

**复现步骤**:
1. 步骤1
2. 步骤2

**错误信息**:
错误日志或堆栈信息

**解决方案**:
解决方案描述

**相关文件**:
- 文件路径1
- 文件路径2

**状态**: ⏳ 待解决 / ✅ 已解决

✅ 测试检查清单

功能测试

  • 正常用户登录成功
  • 未激活用户无法登录
  • 暂停用户无法登录
  • 归档用户无法登录
  • 钉钉登录正常
  • 新用户创建时状态正确
  • 管理员切换用户状态正常
  • 用户状态流转正常
  • 审计字段记录正常

数据一致性

  • 所有用户都有 status 字段
  • isActive 和 status 字段一致
  • 登录后审计字段已更新
  • 状态切换后数据正确

API 兼容性

  • 旧API(isActive)正常工作
  • 新API(status)正常工作
  • 用户列表API返回新字段
  • 向后兼容性正常

性能测试

  • 登录响应时间正常
  • 用户列表查询性能正常
  • 数据库索引生效

📝 测试日志模板

测试日期: YYYY-MM-DD

测试人员: [姓名]

测试结果:

  • ✅ 通过: [测试项]
  • ❌ 失败: [测试项]
  • ⚠️ 警告: [测试项]

发现问题:

  • [问题描述]

下一步:

  • [待处理事项]

🚀 部署到正式系统前的检查

完成所有测试后,确认:

  • 所有测试用例通过
  • 没有发现严重问题
  • 数据一致性验证通过
  • 性能测试通过
  • 问题记录文档已更新
  • 测试日志已记录

只有所有检查项都通过后,才能部署到正式系统!


🧪 阶段二测试用例:部门外键关联

测试用例 8: 更新用户部门 - 双写验证

测试步骤:

  1. 以管理员身份登录
  2. 进入用户管理页面
  3. 更新用户部门(使用部门名称)
  4. 检查数据库中的 department 和 departmentId 字段

预期结果:

  • ✅ department 字段已更新(旧字段)
  • ✅ departmentId 字段已更新(新字段)
  • ✅ departmentId 指向正确的部门记录

验证方法:

-- 查询用户部门信息
SELECT id, username, department, departmentId, 
       (SELECT name FROM departments WHERE id = users.departmentId) as departmentName
FROM users 
WHERE username = '测试用户名';

测试用例 9: 钉钉用户完善资料 - 双写验证

测试步骤:

  1. 使用钉钉登录(新用户)
  2. 选择部门完善资料
  3. 检查数据库中的部门字段

预期结果:

  • ✅ department 字段已设置
  • ✅ departmentId 字段已设置
  • ✅ 两个字段一致

测试用例 10: 部门外键关联查询

测试步骤:

  1. 查询用户列表API:/api/admin/users
  2. 检查返回数据中的 departmentRef 字段

预期结果:

  • ✅ 返回数据包含 departmentRef 字段
  • ✅ departmentRef.name 与 department 字段一致
  • ✅ 如果用户没有部门,departmentRef 为 null

测试用例 11: 数据迁移验证

测试步骤:

  1. 运行部门外键关联迁移脚本
  2. 运行验证脚本

预期结果:

  • ✅ 所有有部门名称的用户都有对应的 departmentId
  • ✅ departmentId 指向的部门存在
  • ✅ department 和 departmentRef.name 一致

验证命令:

# 运行迁移脚本
npx tsx scripts/migrate-department-to-id-safe.ts

# 验证迁移结果
npx tsx scripts/verify-migration.ts 2

测试用例 12: 向后兼容性验证

测试步骤:

  1. 使用旧代码(只更新 department 字段)
  2. 检查 departmentId 是否自动更新

预期结果:

  • ✅ 旧代码仍然工作
  • ✅ 如果部门存在,departmentId 会自动设置
  • ✅ 如果部门不存在,departmentId 为 null

文档版本: 1.1
创建日期: 2025-12-27
最后更新: 2025-12-27