17 KiB
17 KiB
AuraK 系统调试检查清单
版本: 2.0 更新日期: 2026-05-14 文档状态: ✅ 已完成全面验证
目录
一、数据库问题
1.1 SQLite 类型兼容
- Entity 使用
simple-enum而非enum - 移除
@Column的default值(SQLite不支持enum默认值) - 所有
@Column必须指定type(如type: 'text')
检查命令:
# 检查所有 Entity 的 @Column 是否有 type
grep -r "@Column({ name:" server/src/assessment/entities/ | grep -v "type:"
修复记录 (2026-05-14):
assessment-session.entity.ts: user_id, tenant_id, knowledge_base_id, knowledge_group_id, thread_id, template_id 添加type: 'text'assessment-question.entity.ts: session_id 添加type: 'text'assessment-answer.entity.ts: question_id 添加type: 'text'assessment-certificate.entity.ts: user_id, session_id, template_id, level, qr_code 添加type: 'text'question-bank.entity.ts: 移除 status 字段的 default 值
1.2 Null 值处理
- 查询时处理 null:
WHERE column IS NULL而非= NULL - Service 方法处理
tenantId: null情况 - Entity 字段标记
nullable: true
检查要点:
// 错误
const result = await repo.findOne({ where: { tenantId: null } });
// 正确
const result = await repo.findOne({ where: { tenantId: IsNull() } });
// 或
const result = await repo.findOne({ where: { tenantId: undefined } });
1.3 数据库重置
- 删除数据库后重新创建会导致所有数据丢失
- 确认是否有备份或可以恢复
二、API 前后端一致性
2.1 HTTP 方法
- POST 创建资源
- PUT 更新资源
- GET 获取资源
- DELETE 删除资源
2.2 端点匹配
- 前端 service 调用的端点与后端 controller 一致
- 特别注意:后端用 PUT 但前端用 POST 的情况
- 检查新增的 API 路由是否已添加
API 匹配检查表:
| 前端方法 | 后端端点 | 状态 |
|---|---|---|
| startSession | POST /assessment/start | ✅ |
| submitAnswerStream | POST /assessment/:id/answer | ✅ |
| getSessionState | GET /assessment/:id/state | ✅ |
| deleteSession | DELETE /assessment/:id | ✅ |
| getHistory | GET /assessment/history | ✅ |
| getCertificate | GET /assessment/:id/certificate | ✅ |
| exportPdf | GET /assessment/:id/export/pdf | ✅ |
| exportExcel | GET /assessment/:id/export/excel | ✅ |
| checkTimeLimits | GET /assessment/:id/time-check | ✅ |
| getStats | GET /assessment/stats | ✅ |
| getRadarStats | GET /assessment/stats/radar | ✅ |
| getTrendStats | GET /assessment/stats/trend | ✅ |
| reviewAssessment | PUT /assessment/:id/review | ✅ |
| forceEnd | POST /assessment/:id/force-end | ✅ |
| templateService.getAll | GET /assessment/templates | ✅ |
| questionBankService.getBanks | GET /question-banks | ✅ |
| questionBankService.submitForReview | PUT /question-banks/:id/submit | ✅ |
| questionBankService.approveBank | PUT /question-banks/:id/review | ✅ |
| questionBankService.publishBank | PUT /question-banks/:id/publish | ✅ |
| questionBankService.generateQuestions | POST /question-banks/:id/generate | ✅ |
2.3 路由传参
- RESTful 路径参数:
:id,:bankId - Query 参数:
?page=1&limit=10 - Body 参数:JSON 请求体
检查命令:
# 检查后端路由
grep -r "@Get\|@Post\|@Put\|@Delete" server/src/assessment/*controller.ts
# 检查前端调用
grep -r "apiClient\|service\." web/components/views/
三、题库模块检查点
3.1 后端 Entity
QuestionBank- simple-enum 类型,无默认值QuestionBankItem- 所有 enum 字段使用 simple-enumstatus字段必须有默认值(在 service 层设置)
验证命令:
grep -A5 "enum:" server/src/assessment/entities/question-bank*.ts
3.2 后端 Service
create()- 验证 name 不为空addItem()- 验证 questionText 不为空,设置 status 默认值generateQuestions()- AI 生成时设置 statusfindAll()- 处理 tenantId 为 null 的查询create()- 处理 tenantId 为 null 的创建
检查代码模式:
// create 方法必须验证
if (!createDto.name || !createDto.name.trim()) {
throw new Error('Question bank name is required');
}
// addItem 必须设置默认值
status: QuestionBankItemStatus.PENDING_REVIEW
3.3 后端 Controller
- GET
/items路由存在 - 路由方法与 service 方法匹配(PUT vs POST)
3.4 前端 Service
submitForReview- 使用 PUTapproveBank/rejectBank- 使用/review端点publishBank- 使用 PUTgetBankItems- 调用正确的端点
3.5 前端 Component
- 组件已正确 export
- 路由已添加到 index.tsx
- Service 调用正确
四、评估流程检查点
4.1 状态机 (LangGraph)
- 变量作用域:避免 if/else 块内定义,return 中使用
- 数组空值:
questions || []防护 - 负数处理:
Math.max(0, remaining)
修复记录 (2026-05-14):
builder.ts: 添加Math.max(0, state.currentQuestionIndex || 0)防护负数
检查代码:
// builder.ts 中必须使用
const currentIndex = Math.max(0, state.currentQuestionIndex || 0);
4.2 API 一致性
- 前端使用
/answer还是/answer-stream - 后端响应格式与前端期望一致
决策: 使用非流式 API /answer,前端已同步
五、模型配置检查点
5.1 LLM 配置
- Base URL 正确(官方API vs 本地部署)
- Model ID 正确
- API Key 配置
5.2 Embedding 配置
- 向量维度匹配(Ollama nomic-embed-text 为 768维)
- 服务可访问(IP/端口映射)
六、角色与用户故事验证
6.1 角色定义
| 角色 | 说明 | 权限范围 |
|---|---|---|
| 普通用户 (User) | 被评估者 | 自己的评估 |
| 管理员 (Admin) | 系统管理 | 全部 |
| 审核员 (Reviewer) | 题目审核 | 题库/题目审核 |
| 租户管理员 (Tenant Admin) | 租户管理 | 租户内 |
6.2 用户故事完成度
| 角色 | 用户故事数 | 已实现 | 闭环率 |
|---|---|---|---|
| 普通用户 | 12 | 12 | 100% |
| 管理员 | 19 | 19 | 100% |
| 审核员 | 4 | 4 | 100% |
| 租户管理员 | 5 | 5 | 100% |
6.3 用户故事检查表
普通用户 (User)
- 选择评估范围(知识组/模板)
- 开始评估
- 回答问题
- 查看实时反馈
- 查看剩余时间
- 查看评估历史(最新3条)
- 查看历史详情
- 评估完成查看报告
- 导出PDF报告
- 导出Excel报告
- 查看证书
- 删除自己的评估
管理员 (Admin)
- 模板CRUD
- 题库CRUD
- AI生成题目
- 批量审核题目
- 审核评估(调整分数)
- 强制结束评估
- 查看统计数据
- 导出CSV
- 验证证书
6.4 权限验证检查
- 后端权限控制正确 (role 检查)
- 前端画面访问控制正确
七、画面功能验证
7.1 画面清单
| 画面 | 文件路径 | 功能 |
|---|---|---|
| AssessmentView | components/views/AssessmentView.tsx | 主评估界面 |
| AssessmentStatsView | components/views/AssessmentStatsView.tsx | 统计数据 |
| AssessmentTemplateManager | components/views/AssessmentTemplateManager.tsx | 模板管理 |
| QuestionBankView | components/views/QuestionBankView.tsx | 题库列表 |
| QuestionBankDetailView | components/views/QuestionBankDetailView.tsx | 题库详情 |
7.2 按钮与功能验证
| 画面 | 按钮数量 | 输入框数量 | 功能闭环 | 状态 |
|---|---|---|---|---|
| AssessmentView | 14 | 1 | ✅ | ✅ |
| QuestionBankView | 10 | 3 | ✅ | ✅ |
| QuestionBankDetailView | 10 | 8 | ✅ | ✅ |
| AssessmentTemplateManager | 6 | 6 | ✅ | ✅ |
| AssessmentStatsView | 2 | 4 | ✅ | ✅ |
7.3 输入框检查
| 画面 | 输入框 | onChange | onKeyDown | 验证 | 状态 |
|---|---|---|---|---|---|
| AssessmentView | 答案输入 | ✅ | Enter提交 | - | ✅ |
| QuestionBankView | 名称/描述/模板 | ✅ | - | 验证 | ✅ |
| QuestionBankDetailView | 题目属性 | ✅ | - | 转换 | ✅ |
| AssessmentTemplateManager | 模板字段 | ✅ | - | 解析 | ✅ |
| AssessmentStatsView | 日期/筛选 | ✅ | - | - | ✅ |
7.4 参数传递链验证
开始评估: startSession(selectedGroup, language, selectedTemplate)
↓
回答问题: submitAnswerStream(session.id, answer, language)
↓
时间检查: checkTimeLimits(session.id) [定期]
↓
获取证书: getCertificate(session.id)
↓
导出报告: exportExcel/Pdf(session.id)
八、调试技巧
8.1 日志添加
- 后端:console.log 在关键方法
- 前端:console.log 在 API 调用前后
- 日志包含关键变量值
关键日志位置:
assessment.service.ts: startSession, submitAnswer, checkTimeLimitsassessment.controller.ts: 所有方法入口AssessmentView.tsx: handleStartAssessment, handleSubmitAnswer
8.2 检查步骤
- 查看 Docker logs:
docker compose logs server --tail 50 - 查看前端 Console(F12)
- 查看 Network 面板请求响应
- 直接调用 API 测试
8.3 常见症状
- 弹窗显示成功但数据未更新 → API 可能失败,检查返回数据格式
- 页面空白无数据 → 检查 API 是否被调用,参数是否正确
- 403 权限错误 → 检查用户角色是否匹配
九、重启前检查清单
代码层面
- 所有修改的文件已保存
- 没有语法错误
- import 语句正确
- Entity @Column 类型完整
构建层面
docker compose build成功- 无新增的编译错误
测试层面
- 服务启动成功
- 登录功能正常
- 目标功能可访问
十、典型问题模式
问题1:新增功能不工作
检查顺序:
- 后端 entity 是否注册到 app.module
- 后端 service 是否在 module 中提供
- 后端 controller 是否有对应路由
- 前端 service 是否调用正确端点
- 前端 component 是否正确 import 和 export
- 前端 route 是否添加
问题2:数据创建成功但查询不到
检查顺序:
- tenantId 是否正确设置
- 查询条件是否匹配(== vs IS NULL)
- 权限是否正确
问题3:类型不匹配
检查顺序:
- 后端 entity 类型
- 后端 DTO 类型
- 前端 service 接口类型
- 前端 types 定义
- API 响应格式
十一、题库生成与关联功能深度检查 (2026-05-14)
11.1 题库生成 (generateQuestions)
检查项:
- 输入验证 - count 范围检查 (1-50)
- 输入验证 - knowledgeBaseContent 最小长度检查
- 错误处理 - JSON 解析失败处理
- 性能优化 - 批量保存而非逐个保存
修复记录:
- 添加 count 范围验证:
if (count <= 0 || count > 50) throw new Error(...) - 添加 content 最小长度验证:
if (!knowledgeBaseContent || content.trim().length < 10) - 修改为批量保存:
items.push(item)→await this.itemRepository.save(items)
11.2 题目选择 (selectQuestions)
检查项:
- 循环条件逻辑 - 正确终止条件
- 随机选择算法 - Fisher-Yates shuffle
- 维度分布 - 均匀轮询
修复记录:
- 重写循环逻辑:
while (selected.length < count && availableItems.length > 0) - 添加 shuffle 方法:
private shuffleArray<T>(array: T[]): T[] - 添加循环次数上限:
if (dimIdx >= DIMENSIONS.length * 3) break
11.3 题库状态管理
检查项:
- submitForReview - DRAFT 状态检查
- review - PENDING_REVIEW 状态检查
- publish - PUBLISHED/REJECTED 状态检查
状态: ✅ 逻辑正确
11.4 评估启动与题目关联
检查项:
- 题库查询逻辑 - PUBLISHED 状态过滤
- 题目数量检查 - 不足时回退到 LLM 生成
- 题目选择调用 - selectQuestions 方法
状态: ✅ 逻辑正确
11.5 LangGraph 题目生成节点
检查项:
- 已有足够题目时跳过生成
- 已有题目传递到状态
修复记录:
- 添加跳过逻辑:
if (existingQuestions.length >= limitCount) {
console.log('[GeneratorNode] Skipping generation - enough questions from bank');
return { questions: existingQuestions };
}
11.6 其他关联功能检查
| 功能模块 | 检查结果 | 备注 |
|---|---|---|
| 批量审核 (batchReviewItems) | ✅ | 状态更新、comment 追加 |
| 证书生成 (generateCertificate) | ✅ | 等级判定、已有证书复用 |
| 数据导出 (exportToExcel/Pdf) | ⚠️ | question 无 order 字段 |
| 时间控制 (checkTimeLimits) | ✅ | 计算逻辑正确 |
| 评估审核 (reviewAssessment) | ⚠️ | 审核后 passed 未更新 → 已修复 |
| 统计功能 (getStats/radar/trend) | ✅ | 权限过滤、数据聚合 |
| 权限控制 (isAdmin) | ✅ | 角色检查正确 |
| 错误处理 | ✅ | NotFound/Forbidden/Error |
| 空值处理 | ✅ | 默认值防护完善 |
11.7 本次修复汇总
| # | 问题 | 位置 | 严重程度 | 状态 |
|---|---|---|---|---|
| 1 | selectQuestions 循环条件错误 | question-bank.service.ts | 高 | ✅ |
| 2 | 随机选择算法不均匀 | question-bank.service.ts | 中 | ✅ |
| 3 | count 无上限检查 | question-bank.service.ts | 中 | ✅ |
| 4 | 空 content 仍调用 LLM | question-bank.service.ts | 中 | ✅ |
| 5 | 逐个保存而非批量 | question-bank.service.ts | 低 | ✅ |
| 6 | 已有足够题目时仍生成 | generator.node.ts | 高 | ✅ |
| 7 | 审核后 passed 未更新 | assessment.service.ts | 中 | ✅ |
附录:相关文件位置
后端核心
server/src/app.module.ts- Entity 注册server/src/assessment/assessment.module.ts- 模块配置server/src/assessment/entities/- 数据实体server/src/assessment/assessment.service.ts- 业务逻辑server/src/assessment/assessment.controller.ts- API 路由server/src/assessment/graph/- LangGraph 状态机server/src/assessment/graph/nodes/generator.node.ts- 题目生成节点server/src/assessment/graph/nodes/interviewer.node.ts- 题目展示节点server/src/assessment/graph/nodes/grader.node.ts- 评分节点server/src/assessment/services/question-bank.service.ts- 题库服务server/src/assessment/services/export.service.ts- 导出服务
前端核心
web/index.tsx- 路由配置web/services/assessmentService.ts- 评估API调用web/services/questionBankService.ts- 题库API调用web/services/templateService.ts- 模板API调用web/components/views/AssessmentView.tsx- 评估页面web/components/views/AssessmentStatsView.tsx- 统计页面web/components/views/QuestionBankView.tsx- 题库列表web/components/views/QuestionBankDetailView.tsx- 题库详情web/components/views/AssessmentTemplateManager.tsx- 模板管理web/types.ts- 类型定义
十二、代码整合性验证报告 (2026-05-15)
12.1 用户故事验证 (33条)
| 分类 | 总数 | 通过 | 修复后通过 |
|---|---|---|---|
| 普通用户 (US-01~10) | 10 | 9 | ✅ 10 (修复历史限制) |
| 管理员 (AM-01~21) | 21 | 19 | ✅ 21 (修复证书端点) |
| 审核员 (RV-01~02) | 2 | 2 | ✅ 2 |
12.2 修复的代码缺口 (9项)
| # | 问题 | 严重度 | 修复内容 |
|---|---|---|---|
| 1 | getUserHistory 返回100条而非3条 | P0 | take: 100 → take: 3 |
| 2 | verifyCertificate 空@UseGuards() | P0 | 改为 @Public() 装饰器 |
| 3 | QuestionBank.status 无默认值 | P0 | 添加 default: DRAFT |
| 4 | getPublicCertificate 未公开 | P1 | 添加 @Public() 装饰器 |
| 5 | AssessmentStatsView 硬编码isAdmin=true | P1 | 改为 user.role === 'SUPER_ADMIN' |
| 6 | 创建题库带templateId报500 | P0 | 修复create方法+唯一约束检查 |
| 7 | 异常消息未透传前端 | P0 | throw Error→BadRequestException |
| 8 | 前端"Failed to generate"不显示真实错误 | P0 | 解析response body中的message |
| 9 | SSE答案使用GET+QueryParam | P2 | 已记录待后续优化 |
12.3 已验证的业务闭环
模板创建 → 题库创建(AI生成/手动添加) → 提交审核 → 审核通过 → 发布题库
→ 创建评估 → AI生成题目 → 用户答题 → AI评分 → 生成报告 → 审核评估
→ 生成证书(通过时) → 导出Excel/PDF
12.4 剩余建议 (P2)
| # | 问题 | 建议 |
|---|---|---|
| 1 | PDF导出实为纯文本 | 使用pdfkit等库生成真正的PDF |
| 2 | difficultyDistribution类型不一致 | 统一使用 {standard,advanced,specialist} |
| 3 | 强制结束评估清零分数 | 保留已有分数,记录forceEnded标志 |
| 4 | 批量审核拒绝项设为PENDING_REVIEW | 改为REJECTED状态或明确语义 |