- 创建统一的下载错误处理模块 (lib/download-errors.ts) - 实现13种错误类型分类和中文错误消息 - 后端统一使用 createDownloadError 创建标准化错误响应 - 前端统一使用 parseDownloadError 解析错误并显示 - 修复正式系统数据库Schema,添加产品全案相关字段和表 - 执行数据库迁移:添加 task_no, task_status, task_fetched_at 字段 - 创建 material_assets, api_keys, api_call_logs 表
341 lines
11 KiB
Markdown
341 lines
11 KiB
Markdown
# 影子系统测试问题记录
|
||
|
||
> **测试环境**: 影子系统(端口 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
|
||
**文档用途**: 记录影子系统测试问题,为正式系统改造提供参考
|
||
|