gongxiangp2/docs/shadow-testing-issues.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

11 KiB
Raw Blame History

影子系统测试问题记录

测试环境: 影子系统(端口 5320,数据库 lobechat_stage)
测试日期: 2025-12-27
测试目标: 用户状态管理和组织架构升级


📋 测试进度

  • 阶段一:用户状态管理
  • 阶段二:部门外键关联
  • 阶段三:部门层级结构
  • 阶段四:角色枚举扩展

🐛 问题记录

问题 #1: 迁移脚本类型错误 - status 字段查询 null

发现时间: 2025-12-27
测试阶段: 构建阶段
严重程度: 🟡 中

问题描述:

构建时 TypeScript 报错:Type 'null' is not assignable to type 'string | StringFilter<"User"> | undefined'
在 scripts/migrate-user-status.ts 和 scripts/verify-migration.ts 中

复现步骤:

  1. 运行 npm run build
  2. TypeScript 类型检查失败

错误信息:

Type error: Type 'null' is not assignable to type 'string | StringFilter<"User"> | undefined'.

解决方案:

// 问题原因:status 字段在 Schema 中定义为 String @default("pending")
// Prisma 类型系统不允许查询 null 值,因为字段有默认值

// 修复方法1:在 migrate-user-status-safe.ts 中
// 修改前(错误):
const nullStatusUsers = await prisma.user.count({ 
  where: { status: null }  // ❌ 类型错误
});

// 修改后(正确):
const nullStatusUsers = await prisma.user.count({ 
  where: { status: '' }  // ✅ 只检查空字符串
});

// 修复方法2:在 verify-migration.ts 中
// 同样移除 status: null 的查询,改为检查空字符串
// 因为 status 字段有默认值 'pending',所以不会有 null 值

实施步骤:

  1. 修改 scripts/migrate-user-status-safe.ts,移除所有 status: null 查询
  2. 修改 scripts/verify-migration.ts,移除所有 status: null 查询
  3. 重新运行 npm run build 验证类型错误已修复

正式系统改造注意事项:

  • ✅ 此问题已在代码中修复,正式系统不会遇到
  • ✅ 迁移脚本使用 migrate-user-status-safe.ts(已修复版本)
  • ✅ 验证脚本已更新,不会查询 null 值

相关文件:

  • scripts/migrate-user-status-safe.ts (已修复)
  • scripts/verify-migration.ts (已修复)

状态: ✅ 已解决


问题 #2: 验证脚本类型错误 - 阶段三和阶段四字段不存在

发现时间: 2025-12-27
测试阶段: 构建阶段
严重程度: 🟡 中

问题描述:

构建时 TypeScript 报错:阶段三的 level 字段和阶段四的 DEPT_ADMIN/SYSTEM_ADMIN 角色不存在
这些是未来阶段的字段,当前 Schema 中还没有

复现步骤:

  1. 运行 npm run build
  2. TypeScript 类型检查失败

错误信息:

Type error: Object literal may only specify known properties, and 'level' does not exist
Type error: Type '"DEPT_ADMIN"' is not assignable to type 'Role | EnumRoleFilter<"User"> | undefined'

解决方案:

// 问题原因:阶段三和阶段四的字段(level, DEPT_ADMIN, SYSTEM_ADMIN)尚未添加到 Schema
// 但验证脚本尝试验证这些字段,导致 TypeScript 类型错误

// 修复方法:使用原生 SQL 查询检查字段是否存在
// 如果字段不存在,跳过验证(这是正常的,因为阶段三和阶段四尚未实施)

// 示例代码(verify-migration.ts):
async function verifyStage3(): Promise<VerificationResult> {
  // 先检查字段是否存在
  const hasLevelField = await prisma.$queryRaw<Array<{column_name: string}>>`
    SELECT column_name 
    FROM information_schema.columns 
    WHERE table_name = 'departments' 
    AND column_name = 'level'
  `.then(result => result.length > 0).catch(() => false);
  
  if (!hasLevelField) {
    // 字段不存在,跳过验证(正常情况)
    return {
      stage: '阶段三:部门层级结构',
      passed: true,
      issues: ['字段尚未实施,跳过验证'],
      stats: {}
    };
  }
  
  // 字段存在,继续验证...
}

实施步骤:

  1. 修改 scripts/verify-migration.ts 中的阶段三和阶段四验证函数
  2. 使用 $queryRaw 检查字段是否存在
  3. 如果字段不存在,返回跳过验证的结果(不报错)
  4. 重新运行 npm run build 验证类型错误已修复

正式系统改造注意事项:

  • ✅ 此问题已在代码中修复,使用条件检查避免类型错误
  • ✅ 当实施阶段三和阶段四时,字段存在后验证会自动生效
  • ✅ 不会影响阶段一和阶段二的验证

相关文件:

  • scripts/verify-migration.ts (已修复,使用条件检查)

状态: ✅ 已解决


问题 #3: 构建时 DATABASE_URL 警告(正常现象)

发现时间: 2025-12-27
测试阶段: 构建阶段
严重程度: 🟢 低(正常现象)

问题描述:

构建过程中出现大量 Prisma 错误:Environment variable not found: DATABASE_URL
这些错误出现在静态页面生成阶段(SSG)

复现步骤:

  1. 运行 npm run build
  2. 看到大量 prisma:error Invalid prisma.* invocation: Environment variable not found: DATABASE_URL

错误信息:

prisma:error Invalid `prisma.systemSettings.findFirst()` invocation:
error: Environment variable not found: DATABASE_URL

解决方案:

这是正常现象,因为:
1. Next.js 在构建时会尝试预渲染所有页面(SSG)
2. 某些页面在构建时调用了需要数据库的 API
3. 构建环境中没有 DATABASE_URL(这是正常的,因为构建时不需要数据库)

不影响运行时功能,因为:
- 运行时容器中会有 DATABASE_URL 环境变量
- 这些 API 路由是动态的(ƒ),不会在构建时执行
- 静态页面生成失败不影响动态路由

无需修复,这是 Next.js 的正常行为

正式系统改造注意事项:

  • ✅ 这是 Next.js 的正常行为,无需担心
  • ✅ 构建时的警告不影响运行时功能
  • ✅ 生产环境部署时,容器中会有 DATABASE_URL 环境变量
  • ✅ 如果希望消除警告,可以:
    1. 在构建时设置一个临时的 DATABASE_URL(不推荐)
    2. 将使用数据库的页面标记为动态渲染(使用 export const dynamic = 'force-dynamic')
    3. 忽略这些警告(推荐,因为不影响功能)

相关文件:

  • 所有使用 Prisma 的 API 路由和页面组件

状态: ✅ 已确认(正常现象,无需修复)


✅ 已解决问题总结

问题 #1: 迁移脚本类型错误 - status 字段查询 null

  • 解决时间: 2025-12-27
  • 解决方案: 移除 status: null 查询,改为检查空字符串
  • 影响: 已修复,不影响正式系统

问题 #2: 验证脚本类型错误 - 阶段三和阶段四字段不存在

  • 解决时间: 2025-12-27
  • 解决方案: 使用原生 SQL 查询检查字段是否存在,条件跳过验证
  • 影响: 已修复,不影响正式系统

问题 #3: 构建时 DATABASE_URL 警告

  • 确认时间: 2025-12-27
  • 结论: 正常现象,无需修复
  • 影响: 不影响功能,可忽略

📝 测试日志

2025-12-27

测试内容: 代码更新和部署到影子系统

测试结果:

  • ✅ Schema 更新成功(阶段一和阶段二)
  • ✅ 代码更新成功(双写双读实现)
  • ✅ 构建成功(修复了类型错误)
  • ✅ 部署成功(镜像已部署到影子系统)
  • ⚠️ 构建时的 DATABASE_URL 警告(正常现象,不影响功能)

下一步:

  1. ✅ 在影子系统运行数据库迁移(npx prisma db push)
  2. ✅ 运行迁移脚本(阶段一和阶段二)
  3. ⏳ 验证功能正常

迁移执行记录:

  • ✅ 已创建迁移执行脚本:scripts/run-migration-shadow.ps1
  • ✅ 已创建执行计划文档:docs/migration-execution-plan.md
  • ✅ 数据库备份完成:/tmp/lobechat_stage_backup_20251230_191343.dump (332KB)
  • ✅ Schema更新完成(数据库已同步)
  • ✅ 阶段一迁移完成(177个用户,160个active,17个pending)
  • ✅ 阶段二迁移完成(167个用户部门关联已迁移,18个部门)
  • ✅ 所有验证通过

执行时间: 2025-12-30 19:13

部署记录:

  • ✅ 代码已部署到影子系统(容器:youyidian-3d-shadow)
  • ✅ 容器运行正常(端口:5320)
  • ✅ 应用已启动(Ready in 116ms)
  • ✅ 数据库查询正常(日志显示Prisma查询成功)

访问地址: http://192.168.58.20:5320

单元测试记录 (2025-12-30):

  • ✅ 镜像版本确认:使用最新镜像(创建时间:2025-12-30 19:18:12)
  • ✅ 数据库连接测试:通过
  • ✅ 用户状态字段检查:通过(所有用户都有status和isActive字段)
  • ✅ 部门外键关联检查:通过(departmentId和departmentRef正确关联)
  • ✅ 角色切换功能测试:通过(USER ↔ ADMIN切换正常)
  • ✅ 状态切换功能测试:通过(active ↔ suspended切换正常)
  • ✅ 双写逻辑验证:通过(status和isActive字段一致性检查通过)
  • ✅ 数据统计:正常(177个用户,160个active,17个pending,18个部门)

🔍 待验证项

  • 用户登录功能正常(需测试)
  • 用户状态切换正常(需测试)
  • 审计字段记录正常(需测试登录后检查lastLoginAt等字段)
  • 部门关联查询正常(需测试用户列表API返回departmentRef字段)
  • 权限检查逻辑正常(需测试权限相关功能)
  • 前端显示正常(需访问影子系统测试UI)

迁移完成后待测试功能:

  • 访问影子系统:http://192.168.58.20:5320
  • 测试用户登录(验证审计字段更新)
  • 测试管理员切换用户状态
  • 测试用户列表API返回新字段
  • 测试部门关联查询功能


📚 正式系统改造参考

关键经验总结

  1. 类型安全:

    • Prisma 类型系统严格,查询不存在的字段会报错
    • 使用条件检查或原生 SQL 查询来避免类型错误
    • 字段有默认值时,不会为 null,查询时注意
  2. 迁移脚本设计:

    • 所有迁移脚本都应该是幂等的(可重复执行)
    • 使用 -safe 后缀的脚本,包含安全检查
    • 迁移前自动检查 Schema 是否已更新
  3. 验证策略:

    • 分阶段验证,避免验证未实施的字段
    • 使用条件检查,字段不存在时跳过验证
    • 提供详细的验证报告和统计信息
  4. 构建警告:

    • Next.js 构建时的 DATABASE_URL 警告是正常现象
    • 不影响运行时功能,可以安全忽略
    • 如需消除,使用动态渲染标记

正式系统执行清单

执行迁移前:

  • 备份生产数据库(必须!)
  • 确认 Schema 已更新到最新版本
  • 确认迁移脚本已修复所有已知问题
  • 在影子系统完成测试验证

执行迁移时:

  • 使用 scripts/run-migration-shadow.ps1 或类似脚本
  • 按照 docs/migration-execution-plan.md 执行
  • 每个步骤后验证结果

执行迁移后:

  • 运行完整验证脚本
  • 进行功能测试
  • 检查数据一致性
  • 更新本文档记录新问题(如有)

最后更新: 2025-12-27
文档用途: 记录影子系统测试问题,为正式系统改造提供参考