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

341 lines
11 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.

# 影子系统测试问题记录
> **测试环境**: 影子系统(端口 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'.
```
**解决方案**:
```typescript
// 问题原因: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'
```
**解决方案**:
```typescript
// 问题原因:阶段三和阶段四的字段(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
**文档用途**: 记录影子系统测试问题,为正式系统改造提供参考