# 影子系统测试指南 - 阶段一 > **测试环境**: 影子系统(端口 5320,数据库 `lobechat_stage`) > **测试阶段**: 阶段一 - 用户状态管理 > **测试日期**: 2025-12-27 --- ## 📋 测试前准备 ### 1. 确认影子系统配置 **检查项**: - [ ] 影子系统数据库:`lobechat_stage` - [ ] 影子系统端口:`5320` - [ ] 影子系统URL:`http://192.168.58.20:5320` ### 2. 备份数据库 ```bash # 备份影子系统数据库 pg_dump -h 192.168.58.20 -U gongxiangpan -d lobechat_stage > backup_shadow_$(date +%Y%m%d_%H%M%S).sql ``` ### 3. 更新 Schema ```bash # 在项目根目录执行 npx prisma db push # 确认 Schema 已更新 npx prisma studio ``` ### 4. 运行迁移脚本 ```bash # 运行用户状态迁移脚本 npx tsx scripts/migrate-user-status-safe.ts ``` ### 5. 验证迁移结果 ```bash # 运行验证脚本 npx tsx scripts/verify-migration.ts 1 ``` --- ## 🧪 测试用例 ### 测试用例 1: 用户登录 - 正常用户 **测试步骤**: 1. 访问 `http://192.168.58.20:5320/login` 2. 使用已激活的用户账号登录 3. 检查是否能成功登录 **预期结果**: - ✅ 登录成功 - ✅ 用户状态为 `active` - ✅ `lastLoginAt` 字段已更新 - ✅ `loginCount` 字段已递增 - ✅ `lastLoginIp` 字段已记录(如果有) **验证方法**: ```sql -- 查询用户登录信息 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 测试**: ```bash # 测试旧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`) - ✅ 没有不一致的数据 **验证命令**: ```bash npx tsx scripts/verify-migration.ts 1 ``` --- ## 🐛 问题记录 ### 发现问题时,请记录到 `docs/shadow-testing-issues.md` **记录格式**: ```markdown ### 问题 #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` 指向正确的部门记录 **验证方法**: ```sql -- 查询用户部门信息 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` 一致 **验证命令**: ```bash # 运行迁移脚本 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