feat: implement QuestionBank CRUD with pagination and template query

- Add pagination support to findAll (page, limit query params)
- Add findByTemplateId method to service
- Add GET /by-template/:templateId endpoint to controller
- Service already includes CRUD for QuestionBank and QuestionBankItem
This commit is contained in:
Developer
2026-04-23 17:19:11 +08:00
commit 0a9588abb7
492 changed files with 112453 additions and 0 deletions
@@ -0,0 +1,405 @@
# L1 人才育成测评系统设计文档
## 文档信息
- **版本**: 1.1
- **日期**: 2026-04-18
- **状态**: 评审通过
- **关联**: AI 人才育成计划
---
## 1. 业务背景
### 1.1 目标
针对讯和 AI 人才育成计划的 L1 级别(认知与起步),建立系统化的在线评估认证体系。
### 1.2 L1 级别定义
- **目标**: 建立安全使用习惯,理解基本概念
- **面向**: 全员
- **内容**: AI基础概念、安全合规、Prompt入门、IDE基本操作
- **认证**: 在线考试 ≥90分
---
## 2. 评估范围
### 2.1 五门课程
| 序号 | 课程名称 | 对应维度 | 知识组 |
|------|----------|----------|--------|
| 1 | 工作能力-安全 | 工作能力 | AI基础概念 + 安全合规 |
| 2 | 技术能力-LLM | 技术能力 | 大语言模型原理 |
| 3 | 技术能力-提示词 | 技术能力 | 提示词工程 |
| 4 | IDE协作能力 | IDE协作 | IDE操作、代码辅助 |
| 5 | AI开发范式 | AI开发范式 | Flow-State理解 |
### 2.2 知识组说明
知识组存储在 KnowledgeGroup 中,每个组包含:
- 课程名称
- 相关学习资料(文档、PDF等)
- 评估要点说明
---
## 3. 评估流程设计
### 3.1 基本流程
```
发起评估 → 知识组检索 → 生成问题 → 用户回答 → 即时评分/追问 → 全部完成 → 生成报告 → 发放证书
```
### 3.2 评估步骤
1. **发起评估**: 用户选择 L1 认证评估,系统自动关联五个知识组
2. **问题生成**: 基于五个知识组内容生成 8-10 道理解性问题
3. **答题交互**: 用户逐题回答,AI 判断理解深度,如不足则追问确认
4. **即时反馈**: 每题回答后即时反馈分数和简短评语
5. **最终报告**: 全部完成后生成综合报告
6. **证书发放**: 通过者发放电子证书
### 3.3 追问策略
- 每题最多追问 1-2 次以确认理解深度
- 根据回答情况动态调整追问深度
- 超过追问次数后强制进入下一题
---
## 4. 评分设计
### 4.1 权重配置
| 维度 | 权重 | 分值 |
|------|------|------|
| 技术能力-提示词 | 50% | 50分 |
| 其他四门 | 50% | 50分 |
### 4.2 理解深度层级
| 分数 | 层级 | 说明 |
|------|------|------|
| 1-3 | 基础 | 知道概念,无法应用 |
| 4-6 | 理解 | 理解含义,可简单应用 |
| 7-8 | 应用 | 理解本质,能解释原因 |
| 9-10 | 创新 | 能迁移到新场景 |
### 4.3 维度计分规则
- **题目维度归属**:生成问题时确定维度归属(从哪个知识组出题就属于哪个维度)
- **dimensionScores 生成**:每道题记录所属维度,积分时按维度汇总
### 4.4 权重计算
| 维度 | 权重 | 分值 | 说明 |
|------|------|------|------|
| 技术能力-提示词 | 50% | 50分 | 4-5道题 |
| 其他四门 | 50% | 50分 | 4-5道题,平均分配 |
- **计算公式**
- 各维度得分 = 该维度所有题目平均分(0-10)
- 其他四门平均分 = (LLM + IDE + 开发范式 + 工作能力) / 4
- 总分 = 提示词平均分 × 0.5 + 其他四门平均分 × 0.5
- 最终分数 = 总分 × 10(转换为100分制)
- **示例**
- 提示词4题得分:10, 8, 9, 7 → 平均8.5
- 其他四门各1题得分:9, 7, 8, 6 → 平均7.5
- 总分 = 8.5×0.5 + 7.5×0.5 = 8.0
- 最终分数 = 8.0×10 = 80分 → 未通过(需≥90)
### 4.5 通过标准
- 总分 ≥ 90 分即可通过
- 各维度分别计分,支持薄弱环节识别
### 4.6 题目数量
- 总计 8-10 道题
- 提示词相关 4-5 道(50分)
- 其他四门 4-5 道(50分)
---
## 5. 模板设计
### 5.1 评估模板字段
| 字段 | 类型 | 说明 | 默认值 |
|------|------|------|--------|
| name | string | 模板名称 | L1-AI人才育成认证 |
| description | string | 描述 | L1级别能力认证评估 |
| linkedGroups | string[] | 关联知识组ID列表 | [] |
| weightConfig | JSON | 权重配置 | {"prompt":50,"other":50} |
| difficultyConfig | JSON | 难度配置 | {"standard":60,"advanced":30,"specialist":10} |
| questionCount | number | 题目数量 | 8-10 |
| questionCountMin | number | 最小题数 | 8 |
| questionCountMax | number | 最大题数 | 10 |
| passingScore | number | 通过分数 | 90 |
| style | string | 评估风格 | conversation |
| isActive | boolean | 是否启用 | true |
### 5.2 模板配置(扩展现有 AssessmentTemplate
```typescript
// 新增字段
@Column({ type: 'simple-json', name: 'linked_group_ids', nullable: true })
linkedGroupIds: string[]; // 支持多知识组
@Column({ type: 'simple-json', name: 'weight_config', nullable: true })
weightConfig: {
prompt: number; // 提示词权重 默认50
other: number; // 其他维度权重 默认50
};
@Column({ type: 'simple-json', name: 'difficulty_config', nullable: true })
difficultyConfig: {
standard: number; // 基础题比例 默认60
advanced: number; // 理解题比例 默认30
specialist: number; // 创新题比例 默认10
};
@Column({ type: 'int', name: 'question_count_min', default: 8 })
questionCountMin: number;
@Column({ type: 'int', name: 'question_count_max', default: 10 })
questionCountMax: number;
@Column({ type: 'int', name: 'passing_score', default: 90 })
passingScore: number;
```
---
## 6. 角色权限设计
### 6.1 角色说明
基于现有角色体系扩展,管理员角色(admin/super_admin)具备模板和题目调整权限。
| 角色 | 说明 |
|------|------|
| user | 普通员工/学员 |
| admin | 管理员(含题目/模板调整权限) |
| super_admin | 超级管理员(含全部权限) |
| instructor | 讲师(可选,复查功能) |
### 6.2 权限矩阵
| 功能 | 学员 | 管理员 | 超级管理员 | 讲师 |
|------|------|--------|------------|-----------|------|
| 发起评估 | ✓ | ✓ | ✓ | - |
| 查看个人报告 | ✓ | ✓ | ✓ | - |
| 查看全部报告 | - | ✓ | ✓ | ✓ |
| 创建/编辑模板 | - | ✓ | ✓ | - |
| 调整题目配置 | - | ✓ | ✓ | - |
| 配置知识组 | - | ✓ | ✓ | - |
| 导出统计数据 | - | ✓ | ✓ | - |
| 人工复查 | - | - | ✓ | ✓ |
| 手动调整分数 | - | - | ✓ | ✓ |
| 系统配置 | - | - | ✓ | - |
| 用户管理 | - | - | ✓ | - |
---
## 7. 评估结果设计
### 7.1 报告结构
```json
{
"sessionId": "uuid",
"userId": "uuid",
"templateId": "uuid",
"status": "COMPLETED",
"totalScore": 95,
"passed": true,
"dimensionScores": {
"prompt": 48,
"llm": 18,
"ide": 14,
"devPattern": 10,
"workCapability": 5
},
"radarData": {
"prompt": 9.6,
"llm": 9.0,
"ide": 7.0,
"devPattern": 5.0,
"workCapability": 5.0
},
"level": "Proficient",
"questions": [
{
"id": "uuid",
"dimension": "prompt",
"questionText": "...",
"score": 9,
"followUpCount": 1,
"feedback": "..."
}
],
"report": "总体评价...",
"suggestions": ["改进建议1", "改进建议2"],
"certifiedAt": "2026-04-18T10:00:00Z"
}
```
### 7.2 雷达图数据
五维度得分(归一化到 0-10:
1. 提示词工程 (prompt) - 出题自提示词知识组
2. LLM原理 (llm) - 出题自LLM知识组
3. IDE协作 (ide) - 出题自IDE知识组
4. AI开发范式 (devPattern) - 出题自开发范式知识组
5. 工作能力 (workCapability) - 出题自工作能力知识组
**维度归属规则**:生成问题时从哪个知识组检索内容,该题就属于哪个维度。
### 7.3 证书设计
| 字段 | 说明 |
|------|------|
| certificateId | 证书唯一ID |
| userId | 持有者ID |
| templateId | 评估模板ID |
| level | 通过级别 |
| totalScore | 总分 |
| issuedAt | 发放时间 |
| expiresAt | 有效期(null=永久) |
| qrCode | 防伪二维码 |
---
## 8. 功能设计
### 8.1 用户功能
| 功能 | 说明 |
|------|------|
| 发起评估 | 选择模板,开始评估流程 |
| 继续评估 | 断点续答 |
| 查看历史 | 查看历次评估记录和报告 |
| 下载证书 | 下载电子证书PDF |
| 重考 | 通过后重新考试 |
### 8.2 管理员功能
| 功能 | 说明 |
|------|------|
| 模板管理 | 创建/编辑/启用禁用模板 |
| 知识组配置 | 关联评估模板与知识组 |
| 评估记录 | 查看所有用户评估记录 |
| 统计分析 | 查看通过率、各维度得分分布 |
| 导出报表 | 导出CSV/Excel |
### 8.3 讲师功能(可选)
| 功能 | 说明 |
|------|------|
| 人工复查 | 查看并复查评估结果 |
| 手动评分 | 调整AI评分 |
| 添加评语 | 添加人工评语 |
---
## 9. 技术设计
### 9.1 现有架构复用
基于 AuraK 现有评估系统扩展:
```
AssessmentTemplate (扩展)
AssessmentSession (扩展)
LangGraph: generator → interviewer → grader → analyzer
```
### 9.2 新增数据库表
```sql
-- 证书表
CREATE TABLE assessment_certificates (
id UUID PRIMARY KEY,
user_id UUID NOT NULL,
session_id UUID NOT NULL,
template_id UUID NOT NULL,
level VARCHAR(50),
total_score FLOAT,
qr_code VARCHAR(255),
issued_at TIMESTAMP,
created_at TIMESTAMP
);
```
### 9.3 新增 API 接口
| 接口 | 方法 | 说明 | 权限 |
|------|------|------|------|
| /templates | GET | 模板列表 | 公开 |
| /templates | POST | 创建模板 | 管理员 |
| /templates/:id | PUT | 更新模板 | 管理员 |
| /templates/:id (软删除) | DELETE | 禁用模板 | 管理员 |
| /certificates/:sessionId | GET | 获取证书 | 所有者 |
| /certificates/:sessionId/download | GET | 下载证书PDF | 所有者 |
| /certificates/verify | POST | 二维码验真 | 公开 |
| /admin/statistics | GET | 统计报表 | 管理员 |
### 9.4 前端页面
| 页面 | 说明 |
|------|------|
| /assessment/templates | 模板管理 |
| /assessment/history | 评估历史 |
| /assessment/report/:id | 评估报告详情 |
| /assessment/certificate/:id | 证书查看/下载 |
| /admin/statistics | 管理统计 |
---
## 10. 实施计划
### 10.1 优先级
| 优先级 | 模块 | 说明 |
|--------|------|------|
| P0 | 模板扩展 | 支持多知识组、权重配置 |
| P0 | 评估流程 | 适配L1五课程流程 |
| P0 | 评分逻辑 | 调整追问策略、加权计分 |
| P1 | 报告生成 | 结构化报告、雷达图数据 |
| P1 | 证书功能 | 证书生成、下载 |
| P2 | 统计分析 | 管理后台统计 |
| P2 | 人工复查 | 讲师功能 |
### 10.2 里程碑
1. **M1**: 模板扩展 + 基本评估流程(1周)
2. **M2**: 报告生成 + 证书功能(1周)
3. **M3**: 管理后台 + 统计分析(1周)
4. **M4**: 测试优化 + 上线(1周)
---
## 11. 附录
### 11.1 参考文档
- AI人才育成计划.md
- 提示词工程.md
- 大语言模型入门.md
- AI安全使用指南.md
- Open Code使用指南.md
- GitHub Copilot使用指南.md
- Claude Code使用指南.md
- L1-开发范式是什么.md
### 11.2 现有代码参考
- `server/src/assessment/` - 评估模块
- `web/components/views/AssessmentView.tsx` - 前端评估界面
@@ -0,0 +1,490 @@
# L1人才育成评估系统实施计划
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
**Goal:** 实现L1人才育成评估系统,支持五门课程考核、多知识组关联、加权计分、证书生成
**Architecture:** 基于现有AuraK评估系统(LangGraph状态机)扩展,新增模板多知识组支持、维度计分、证书功能
**Tech Stack:** NestJS + TypeORM + LangGraph + React
---
## Phase 1: 模板扩展(P0
### Task 1.1: 扩展 AssessmentTemplate 实体
**Files:**
- Modify: `server/src/assessment/entities/assessment-template.entity.ts:1-80`
**Step 1: Add new columns**
```typescript
// Add after existing columns (line ~79)
@Column({ type: 'simple-json', name: 'linked_group_ids', nullable: true })
linkedGroupIds: string[];
@Column({ type: 'simple-json', name: 'weight_config', nullable: true })
weightConfig: {
prompt: number;
other: number;
};
@Column({ type: 'simple-json', name: 'difficulty_config', nullable: true })
difficultyConfig: {
standard: number;
advanced: number;
specialist: number;
};
@Column({ type: 'int', name: 'question_count_min', default: 8 })
questionCountMin: number;
@Column({ type: 'int', name: 'question_count_max', default: 10 })
questionCountMax: number;
@Column({ type: 'int', name: 'passing_score', default: 90 })
passingScore: number;
```
**Step 2: Commit**
```bash
git add server/src/assessment/entities/assessment-template.entity.ts
git commit -m "feat: extend AssessmentTemplate with multi-group and weight config"
```
---
### Task 1.2: 创建数据库迁移
**Files:**
- Create: `server/src/migrations/XXXXXX-add-template-extensions.sql`
**Step 1: Write migration**
```sql
ALTER TABLE assessment_templates
ADD COLUMN linked_group_ids TEXT,
ADD COLUMN weight_config TEXT,
ADD COLUMN difficulty_config TEXT,
ADD COLUMN question_count_min INTEGER DEFAULT 8,
ADD COLUMN question_count_max INTEGER DEFAULT 10,
ADD COLUMN passing_score INTEGER DEFAULT 90;
```
**Step 2: Test migration**
```bash
cd server && npx typeorm query "SELECT linked_group_ids, weight_config FROM assessment_templates LIMIT 1"
```
**Step 3: Commit**
```bash
git add server/src/migrations/
git commit -m "db: add template extension columns"
```
---
### Task 1.3: 更新 TemplateService CRUD
**Files:**
- Modify: `server/src/assessment/services/template.service.ts`
**Step 1: Add linkedGroupIds handling**
```typescript
// In create() method, add:
if (createTemplateDto.linkedGroupIds) {
template.linkedGroupIds = createTemplateDto.linkedGroupIds;
}
if (createTemplateDto.weightConfig) {
template.weightConfig = createTemplateDto.weightConfig;
}
// ... other fields
```
**Step 2: Verify compilation**
```bash
cd server && npx tsc --noEmit
```
**Step 3: Commit**
```bash
git add server/src/assessment/services/template.service.ts
git commit -m "feat: support linkedGroupIds in TemplateService"
```
---
## Phase 2: 评估流程适配(P0
### Task 2.1: 修改 QuestionGenerator 支持多知识组
**Files:**
- Modify: `server/src/assessment/assessment.service.ts:266-368` (startSession method)
**Step 1: Support multi-group content retrieval**
```typescript
// In startSession(), replace single content retrieval with multi-group:
private async getMultiGroupContent(
groupIds: string[],
userId: string,
tenantId: string,
): Promise<string> {
const contents: string[] = [];
for (const groupId of groupIds) {
const files = await this.groupService.getGroupFiles(groupId, userId, tenantId);
const content = files.map(f => f.content).join('\n\n---\n\n');
contents.push(content);
}
return contents.join('\n\n');
}
```
**Step 2: Pass content with dimension tag**
```typescript
// In getSessionContent, add dimension tag:
// === Document: [工作能力] ===
// ...content...
```
**Step 3: Commit**
```bash
git add server/src/assessment/assessment.service.ts
git commit -m "feat: support multi-group content retrieval"
```
---
### Task 2.2: Generator 输出维度信息
**Files:**
- Modify: `server/src/assessment/graph/nodes/generator.node.ts:176-182`
**Step 1: Add dimension field**
```typescript
const mappedNewQuestions = newQuestions.map((q: any) => ({
id: (existingQuestions.length + 1).toString(),
questionText: q.question_text,
keyPoints: q.key_points,
difficulty: q.difficulty,
basis: q.basis,
dimension: q.dimension || this.inferDimension(knowledgeBaseContent), // NEW FIELD
}));
private inferDimension(content: string): string {
// Detect dimension from content tags
if (content.includes('[提示词]')) return 'prompt';
if (content.includes('[LLM]')) return 'llm';
// ... etc
}
```
**Step 2: Commit**
```bash
git add server/src/assessment/graph/nodes/generator.node.ts
git commit -m "feat: generator outputs dimension field"
```
---
## Phase 3: 评分逻辑(P0
### Task 3.1: DimensionScores 计算
**Files:**
- Modify: `server/src/assessment/assessment.service.ts:600-630` (score calculation)
**Step 1: Calculate dimension scores**
```typescript
// Replace simple weighted score with dimension-aware calculation:
const calculateDimensionScores = (questions: any[], scores: Record<string, number>) => {
const dimensionScores: Record<string, number> = {
prompt: 0, llm: 0, ide: 0, devPattern: 0, workCapability: 0
};
const dimensionCounts: Record<string, number> = { prompt: 0, llm: 0, ide: 0, devPattern: 0, workCapability: 0 };
questions.forEach((q, idx) => {
const dim = q.dimension || 'workCapability';
dimensionScores[dim] += scores[q.id || idx.toString()] || 0;
dimensionCounts[dim]++;
});
// Average per dimension
Object.keys(dimensionScores).forEach(d => {
dimensionScores[d] = dimensionCounts[d] > 0
? dimensionScores[d] / dimensionCounts[d]
: 0;
});
return dimensionScores;
};
```
**Step 2: Commit**
```bash
git add server/src/assessment/assessment.service.ts
git commit -m "feat: calculate dimension scores"
```
---
### Task 3.2: 追问策略调整
**Files:**
- Modify: `server/src/assessment/graph/nodes/grader.node.ts:207`
**Step 1: Increase follow-up limit**
```typescript
// Current: currentFollowUpCount >= 1
// Change to:
if (currentFollowUpCount >= 2 || result.score >= 8 || saysIDontKnow) {
shouldFollowUp = false;
}
```
**Step 2: Commit**
```bash
git add server/src/assessment/graph/nodes/grader.node.ts
git commit -m "feat: increase follow-up limit to 2"
```
---
## Phase 4: 报告生成(P1
### Task 4.1: 扩展 Session 存储 dimension 数据
**Files:**
- Modify: `server/src/assessment/entities/assessment-session.entity.ts`
**Step 1: Add dimension fields**
```typescript
@Column({ type: 'simple-json', name: 'dimension_scores', nullable: true })
dimensionScores: Record<string, number>;
@Column({ type: 'simple-json', name: 'radar_data', nullable: true })
radarData: Record<string, number>;
```
**Step 2: Commit**
```bash
git add server/src/assessment/entities/assessment-session.entity.ts
git commit -m "feat: add dimension scores to session entity"
```
---
### Task 4.2: Analyzer 生成结构化报告
**Files:**
- Modify: `server/src/assessment/graph/nodes/analyzer.node.ts`
**Step 1: Generate dimension-aware report**
```typescript
// Modify system prompt to include:
const dimensionSummary = Object.entries(dimensionScores)
.map(([dim, score]) => `${dim}: ${score}/10`)
.join('\n');
const reportPrompt = `...
维度得分:
${dimensionSummary}
请在报告中包含:
1. 各维度得分分析
2. 薄弱环节识别
3. 针对性改进建议
`;
```
**Step 2: Commit**
```bash
git add server/src/assessment/graph/nodes/analyzer.node.ts
git commit -m "feat: generate structured report with dimension analysis"
```
---
## Phase 5: 证书功能(P1
### Task 5.1: 创建证书表
**Files:**
- Create: `server/src/assessment/entities/assessment-certificate.entity.ts`
**Step 1: Define entity**
```typescript
@Entity('assessment_certificates')
export class AssessmentCertificate {
@PrimaryGeneratedColumn('uuid')
id: string;
@Column({ name: 'user_id' })
userId: string;
@Column({ name: 'session_id' })
sessionId: string;
@Column({ name: 'template_id' })
templateId: string;
@Column()
level: string;
@Column({ type: 'float', name: 'total_score' })
totalScore: number;
@Column({ name: 'qr_code', nullable: true })
qrCode: string;
@CreateDateColumn({ name: 'issued_at' })
issuedAt: Date;
}
```
**Step 2: Commit**
```bash
git add server/src/assessment/entities/assessment-certificate.entity.ts
git commit -m "feat: create certificate entity"
```
---
### Task 5.2: 证书生成API
**Files:**
- Modify: `server/src/assessment/assessment.controller.ts`
**Step 1: Add certificate endpoints**
```typescript
@Get('certificate/:sessionId')
async getCertificate(
@Param('sessionId') sessionId: string,
@Req() req,
): Promise<AssessmentCertificate> {
// Generate or return existing certificate
}
@Get('certificate/:sessionId/download')
async downloadCertificate(
@Param('sessionId') sessionId: string,
): Promise<StreamableFile> {
// Generate PDF with jsPDF
}
```
**Step 2: Commit**
```bash
git add server/src/assessment/assessment.controller.ts
git commit -m "feat: add certificate endpoints"
```
---
## Phase 6: 前端集成(P2
### Task 6.1: 模板选择页面
**Files:**
- Modify: `web/components/views/AssessmentView.tsx`
**Step 1: Add template selection**
```typescript
// Add state:
const [templates, setTemplates] = useState<AssessmentTemplate[]>([]);
// Load templates on mount:
useEffect(() => {
const loadTemplates = async () => {
const res = await assessmentService.getTemplates();
setTemplates(res.data);
};
loadTemplates();
}, []);
```
**Step 2: Commit**
```bash
git add web/components/views/AssessmentView.tsx
git commit -m "feat: add template selection to frontend"
```
---
### Task 6.2: 报告页面的雷达图
**Files:**
- Create: `web/components/RadarChart.tsx`
**Step 1: Create component**
```typescript
export const RadarChart = ({ data }) => {
// Use recharts or echarts for radar
// Data: { prompt: 9.6, llm: 9.0, ide: 7.0, devPattern: 5.0, workCapability: 5.0 }
};
```
**Step 2: Commit**
```bash
git add web/components/RadarChart.tsx
git commit -m "feat: add radar chart component"
```
---
## 实施顺序
1. Task 1.1 → 1.3 (模板扩展)
2. Task 2.1 → 2.2 (评估流程)
3. Task 3.1 → 3.2 (评分逻辑)
4. Task 4.1 → 4.2 (报告)
5. Task 5.1 → 5.2 (证书)
6. Task 6.1 → 6.2 (前端)
**每个Task约需1-2小时**
---
## 依赖说明
- Phase 1 (模板) → Phase 2 → Phase 3 → Phase 4 → Phase 5
- 前端(Phase 6) 可在后端基本完成后并行开发
- 测试贯穿每个Task
---
## 验收标准
- [ ] 模板支持多知识组关联
- [ ] 题目带dimension字段
- [ ] 报告含dimensionScores和radarData
- [ ] 可生成书PDF
- [ ] 前端显示雷达图
- [ ] E2E测试通过
@@ -0,0 +1,593 @@
# AuraK 评估系统完整实施计划
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
**Goal:** 构建完整的AI人才评估系统,包含题库管理、维度均衡抽取、审核流程、评估统计
**Architecture:**
- 题库通过模板间接关联知识库分组
- 评估时从题库维度均衡抽取,不足时实时生成备用
- 管理员通过独立页面管理题库和查看统计
**Tech Stack:** NestJS + TypeORM + LangGraph + React + TypeScript
---
## 一、问题与方案对照表
| # | 待修复问题 | 解决思路 | 对应Task |
|---|------------|----------|----------|
| 1 | 评分计算错误 | 已修复 | ✅ |
| 2 | 题目维度分配不均 | 已修复 | ✅ |
| 3 | 多轮对话中断 | 已修复 | ✅ |
| 4 | 计数器显示错误 | 已修复 | ✅ |
| 5 | 历史问答查询 | 统计页面 | Task 4 |
| 6 | 知识覆盖度来源 | 用户不 care | - |
| 7 | 实时反馈无内容 | 用户确认已有内容 | - |
| 8 | 预生成题目功能 | 题库+抽取 | Task 1,2,3 |
| 9 | 题目生成不稳定 | 题库前置 | Task 1,7 |
| 10 | 题目来源不是知识库 | 题库+范围控制 | Task 1,3 |
| 11 | 选择题实际无选项 | 题库管理 | Task 1,5 |
---
## 二、系统架构
### 2.1 数据层级
```
KnowledgeGroup(知识库分组)
AssessmentTemplate(模板)→ 题目数量、知识库配置
QuestionBank(题库)→ 审核状态
QuestionBankItem(题目)→ 维度/难度/答案
评估抽取使用
```
### 2.2 评估流程
```
开始评估
1. 加载模板配置(题目数量、维度配置)
2. 检查已发布题库题目数量
充足 → 维度均衡随机抽取 → 进入答题
不足 → 实时生成题目(备用) → 进入答题
3. 用户答题 → 即时评分 → 实时反馈
4. 追问(如Grader判断需要)
5. 答题完成 → 生成报告 + 记录统计
```
---
## 三、数据模型
### 3.1 QuestionBank(题库)
```typescript
// server/src/assessment/entities/question-bank.entity.ts
@Entity('question_banks')
export class QuestionBank {
@PrimaryGeneratedColumn('uuid')
id: string;
@Column({ name: 'template_id' })
templateId: string;
@ManyToOne(() => AssessmentTemplate)
@JoinColumn({ name: 'template_id' })
template: AssessmentTemplate;
@Column({ name: 'name' })
name: string; // 题库名称
@Column({ type: 'text', description: '题库描述' })
description: string;
@Column({ type: 'enum', enum: QuestionBankStatus, default: QuestionBankStatus.DRAFT })
status: QuestionBankStatus; // DRAFT | PENDING_REVIEW | PUBLISHED
@Column({ name: 'created_by' })
createdBy: string;
@Column({ name: 'reviewed_by', nullable: true })
reviewedBy: string;
@Column({ name: 'reviewed_at', nullable: true })
reviewedAt: Date;
@Column({ name: 'review_comment', nullable: true })
reviewComment: string; // 审核意见
@OneToMany(() => QuestionBankItem, item => item.bank)
items: QuestionBankItem[];
@CreateDateColumn({ name: 'created_at' })
createdAt: Date;
@UpdateDateColumn({ name: 'updated_at' })
updatedAt: Date;
}
enum QuestionBankStatus {
DRAFT = 'DRAFT', // 草稿
PENDING_REVIEW = 'PENDING_REVIEW', // 待审核
PUBLISHED = 'PUBLISHED', // 已发布
REJECTED = 'REJECTED', // 审核拒绝
}
```
### 3.2 QuestionBankItem(题目)
```typescript
// server/src/assessment/entities/question-bank-item.entity.ts
@Entity('question_bank_items')
export class QuestionBankItem {
@PrimaryGeneratedColumn('uuid')
id: string;
@Column({ name: 'bank_id' })
bankId: string;
@ManyToOne(() => QuestionBank, bank => bank.items)
@JoinColumn({ name: 'bank_id' })
bank: QuestionBank;
@Column({ type: 'text', name: 'question_text' })
questionText: string;
@Column({ type: 'enum', enum: QuestionType })
questionType: QuestionType; // SHORT_ANSWER | MULTIPLE_CHOICE | TRUE_FALSE
@Column({ type: 'simple-json', nullable: true })
options: string[]; // 选择题选项 ["A. xxx", "B. xxx", ...]
@Column({ type: 'text', nullable: true })
correctAnswer: string; // 正确答案
@Column({ type: 'simple-json', name: 'key_points' })
keyPoints: string[]; // 关键点 ["point1", "point2"]
@Column({ type: 'enum', enum: QuestionDifficulty })
difficulty: QuestionDifficulty; // STANDARD | ADVANCED | SPECIALIST
@Column({ type: 'enum', enum: QuestionDimension })
dimension: QuestionDimension; // PROMPT | LLM | IDE | DEV_PATTERN | WORK_CAPABILITY
@Column({ type: 'text', name: ' basis', nullable: true })
basis: string; // 出题依据
@Column({ name: 'created_by' })
createdBy: string;
@CreateDateColumn({ name: 'created_at' })
createdAt: Date;
}
enum QuestionType {
SHORT_ANSWER = 'SHORT_ANSWER', // 简答题
MULTIPLE_CHOICE = 'MULTIPLE_CHOICE', // 选择题
TRUE_FALSE = 'TRUE_FALSE', // 判断题
}
enum QuestionDifficulty {
STANDARD = 'STANDARD', // 标准
ADVANCED = 'ADVANCED', // 进阶
SPECIALIST = 'SPECIALIST', // 专家
}
enum QuestionDimension {
PROMPT = 'PROMPT', // 提示词
LLM = 'LLM', // LLM原理
IDE = 'IDE', // IDE协作
DEV_PATTERN = 'DEV_PATTERN', // 开发范式
WORK_CAPABILITY = 'WORK_CAPABILITY', // 工作能力
}
```
### 3.3 评估统计
```typescript
// API返回结构
interface AssessmentStats {
// 统计卡片
totalAttempts: number; // 总考核次数
highestScore: number; // 最高分
averageScore: number; // 平均分
completionRate: number; // 完成率
// 得分趋势(可选用于图表)
scoreTrend: { date: string; score: number }[];
// 历史记录
recentRecords: {
id: string;
knowledgeBase: string;
template: string;
score: number;
status: 'IN_PROGRESS' | 'COMPLETED';
createdAt: string;
}[];
}
```
---
## 四、API设计
### 4.1 题库管理API
```typescript
// 题库CRUD
POST /api/question-banks // 创建题库
GET /api/question-banks // 列表(带分页)
GET /api/question-banks/:id // 详情(含题目)
PUT /api/question-banks/:id // 更新题库信息
DELETE /api/question-banks/:id // 删除题库
// 题目管理
POST /api/question-banks/:bankId/items // 添加单题
PUT /api/question-banks/:bankId/items/:id // 更新题目
DELETE /api/question-banks/:bankId/items/:id // 删除题目
// 批量操作
POST /api/question-banks/:bankId/batch-add // 批量添加题目(AI生成或Excel导入)
POST /api/question-banks/:bankId/generate // AI批量生成待审核
// 审核流程
PUT /api/question-banks/:id/submit // 提交审核(草稿→待审核)
PUT /api/question-banks/:id/review // 审核(通过/拒绝,附带意见)
PUT /api/question-banks/:id/publish // 发布(审核通过→已发布)
PUT /api/question-banks/:id/unpublish // 下架
// 模板关联
GET /api/question-banks/by-template/:templateId // 按模板查询题库
```
### 4.2 统计API
```typescript
// 评估统计
GET /api/assessment/stats // 当前用户统计
GET /api/assessment/stats/admin // 管理员统计(所有用户)
Query: startDate, endDate, templateId, knowledgeGroupId
```
---
## 五、前端页面设计
### 5.1 题库管理页面(QuestionBankView
```
┌──────────────────────────────────────────────────────────────────────────┐
│ 题库管理 [新建题库] │
├────────────┬─────────────────────────────────────────────────────┤
│ 我的题库 │ 筛选: [模板▼] [状态▼] [维度▼] [难度▼] [搜索...] │
│ ├─────────────────────────────────────────────────────┤
│ □ AI开发 │ ┌────┬────────┬────────┬──────┬────────────┐ │
│ □ Python │ │选择│ 题目内容│ 题型 │ 维度 │ 难度 │ 操作│ │
│ │ ├────┼────────┼────────┼──────┼────────────┤ │
│ │ │ ○ │xxx │ 简答 │ llm │ 标准 │编辑│ │
│ │ │ ○ │xxx │ 选择 │ ide │ 进阶 │编辑│ │
│ │ │ ○ │xxx │ 判断 │ Work │ 专家 │删除│ │
│ │ └────┴────────┴────────┴──────┴────────────┘ │
│ │ [批量导入] │
│ ├─────────────────────────────────────────────────────┤
│ │ [AI批量生成] [提交审核] [全选] [取消选择] │
└────────────┴─────────────────────────────────────────────────────┘
```
### 5.2 题库详情/编辑面板
```
┌────────────────────────────────────┐
│ 编辑题目 [保存] │
├────────────────────────────────────┤
│ 题目内容 │
│ ┌──────────────────────────────┐ │
│ │ │ │
│ └────────────────────────────┘ │
│ │
│ 题型: ●简答 ○选择 ○判断 │
│ │
│ [选择题时显示] │
│ 选项: │
│ A. ___________________ │
│ B. ___________________ │
│ C. ___________________ │
│ D. ___________________ │
│ │
│ 正确答案: ________________ │
│ │
│ 关键点: │
│ _________________________ │
│ _________________________ │
│ │
│ 维度: [prompt▼] 难度: [标准▼] │
│ │
│ 出题依据: │
│ _________________________ │
└────────────────────────────────────┘
```
### 5.3 统计页面(AssessmentStatsView
```
┌─────────────────────────────────────────────────────────────────┐
│ 评估统计 [导出] │
├─────────────────────────────────────────────────────────────────┤
│ 筛选: [时间范围▼] [知识库▼] [重置] │
├─────────────────────────────────────────────────────────────────┤
│ 总考核 │ 最高分 │ 平均分 │ 完成率 │
│ 15 │ 9.2 │ 7.8 │ 80% │
├─────────────────────────────────────────────────────────────────┤
│ 得分趋势(折线图 - 可选) │
│ 10 ____ │
│ 8 ____▓▓▓____▓▓ │
│ 6 ____▓▓▓▓▓____▓▓▓▓___ │
│ 4 _______________________________________ │
│ 2 ____________________________________________│
│ 04/10 04/12 04/14 04/16 04/18 │
├─────────────────────────────────────────────────────────────────┤
│ 历史记录 │
│ 日期 知识库 模板 得分 状态 操作│
│ 04/18 AI开发 AI基础 9.2 完成 查看 │
│ 04/15 Python 编程基础 7.5 完成 查看 │
│ 04/12 AI开发 AI基础 8.1 完成 查看 │
│ 04/10 - LLM原理 - 进行中 查看 │
└─────────────────────────────────────────────────────────────────┘
```
---
## 六、实施计划
### Task 1: 题库管理功能(核心)
**Files:**
- Create: `server/src/assessment/entities/question-bank.entity.ts`
- Create: `server/src/assessment/entities/question-bank-item.entity.ts`
- Create: `server/src/assessment/question-bank.service.ts`
- Create: `server/src/assessment/question-bank.controller.ts`
- Modify: `server/src/assessment/assessment.module.ts` (import)
- Create: 迁移文件 `add_question_banks.sql`
**实施步骤:**
1. 创建 QuestionBank 实体 + 迁移
2. 创建 QuestionBankItem 实体 + 迁移
3. 实现 QuestionBankServiceCRUD
4. 实现 QuestionBankControllerAPI
5. 注册模块
**验收标准:**
- [ ] 可以创建题库
- [ ] 可以添加/编辑/删除题目
- [ ] 可以设置题目维度/难度/答案
- [ ] 支持审核流程(草稿→待审核→发布)
---
### Task 2: AI批量生成
**目标:** 调用AI批量生成题目,待人工审核
**Files:**
- Modify: `server/src/assessment/question-bank.service.ts` (generate)
- Modify: `server/src/assessment/graph/nodes/generator.node.ts` (复用)
**实施步骤:**
1. 实现批量生成逻辑
2. 调用generator node生成题目
3. 保存为草稿状态
4. 提供审核界面
**验收标准:**
- [ ] 点击生成按钮,调用AI生成题目
- [ ] 生成的题目进入草稿状态
- [ ] 可以批量审核通过
---
### Task 3: 题目抽取逻
**目标:** 评估时从题库维度均衡随机抽取
**Files:**
- Modify: `server/src/assessment/question-bank.service.ts` (selectQuestions)
**实施步骤:**
1. 实现维度均衡抽取算法
2. 处理题目不足情况
3. 单元测试
**验收标准:**
- [ ] 抽取的题目维度大致均衡
- [ ] 不重复抽取同一题目
- [ ] 数量不足时有补充逻辑
---
### Task 4: 评估接入题库
**目标:** 评估优先使用题库题目
**Files:**
- Modify: `server/src/assessment/assessment.service.ts` (startSession)
**实施步骤:**
1. 修改startSession逻辑
2. 先查询题库
3. 题库不足时使用实时生成
4. 测试完整流程
**验收标准:**
- [ ] 有题库时优先从题库抽取
- [ ] 题库不足时使用实时生成
- [ ] 两者都可正常工作
---
### Task 5: 统计页面
**目标:** 独立统计页面
**Files:**
- Create: `server/src/assessment/assessment.controller.ts` (stats API)
- Create: `web/src/services/assessmentStatsService.ts`
- Create: `web/components/views/AssessmentStatsView.tsx`
- Modify: `web/index.tsx` (路由)
- Modify: `web/components/layouts/WorkspaceLayout.tsx` (侧边栏)
**验收标准:**
- [ ] 统计卡片显示正确
- [ ] 支持时间筛选
- [ ] 管理员可查看所有用户
- [ ] 历史记录表格完整
---
### Task 6: 选择题渲染
**目标:** 前端支持选择题渲染
**Files:**
- Modify: `web/components/views/AssessmentView.tsx`
**验收标准:**
- [ ] 选择题显示选项按钮
- [ ] 点击选项提交答案
---
### Task 7: 判断题渲染
**目标:** 前端支持判断题渲染
**Files:**
- Modify: `web/components/views/AssessmentView.tsx`
**验收标准:**
- [ ] 判断题显示True/False按钮
- [ ] 点击提交答案
---
### Task 8: 稳定性优化
**目标:** 提高AI生成稳定性
**Files:**
- Modify: `server/src/assessment/graph/nodes/generator.node.ts`
**实施步骤:**
1. 添加重试逻辑
2. 优化prompt
3. 错误处理
---
## 七、执行顺序
```
Task 1 (题库管理)
Task 2 (AI批量生成)
Task 3 (抽取逻辑)
Task 4 (评估接入)
Task 5 (统计页面)
Task 6 (选择题)
Task 7 (判断题)
Task 8 (稳定性)
```
---
## 八、技术要点
### 8.1 维度均衡算法
```typescript
// 伪代码
function selectQuestions(bankId: string, count: number): Question[] {
const allItems = getPublishedItems(bankId);
const dimensions = ['prompt', 'llm', 'ide', 'devPattern', 'workCapability'];
const selected: Question[] = [];
const usedIds = new Set<string>();
// 轮询从各维度选取
let dimIdx = 0;
while (selected.length < count && dimIdx < count * dimensions.length) {
const dim = dimensions[dimIdx % dimensions.length];
const available = allItems.filter(
(i) => i.dimension === dim && !usedIds.has(i.id)
);
if (available.length > 0) {
const random = available[Math.floor(Math.random() * available.length)];
selected.push(random);
usedIds.add(random.id);
}
dimIdx++;
}
// 补充不足的题目(随机)
if (selected.length < count) {
const remaining = allItems.filter((i) => !usedIds.has(i.id));
// ... 随机补充
}
return selected;
}
```
### 8.2 审核工作流
```
草稿(DRAFT) → 提交审核 → 待审核(PENDING_REVIEW)
审核通过 → 已发布(PUBLISHED)
审核拒绝 → 草稿(DRAFT) + 意见
```
---
## 九、注意事项
1. **权限控制**:题库管理、统计只对管理员开放
2. **数据隔离**:用户只能看到自己的评估记录,管理员可见所有
3. **维度映射**:确保题目维度与评估维度一致
4. **题库状态**:只有已发布的题目才能被抽取
5. **回退机制**:题库不足时使用实时生成作为备用
---
## Plan Complete
**Two execution options:**
**1. Subagent-Driven (this session)** - 继续在此会话,使用 subagent 逐个执行任务
**2. Parallel Session (separate)** - 开新会话使用 executing-plans,分批执行
**Which approach?**
@@ -0,0 +1,522 @@
# AuraK 人才测评体系完整实施计划
> **文档状态**: ✅ 评审通过
> **创建日期**: 2026-04-23
> **版本**: 2.0
> **评审日期**: 2026-04-23
---
## 一、系统概述
### 1.1 目标
构建一个完整的AI人才测评体系,实现"选→育→评→用"闭环。聚焦在**评(认证)阶段**,形成包含题库管理、评估执行、成绩管理、证书管理的完整系统。
### 1.2 核心流程
```
知识库 → 模板配置 → 题库(AI生成+审核) → 评估抽取 → 用户答题 → 评分 → 成绩 → 证书
复查(调整总分)
```
### 1.3 评估发起模式
| 场景 | 发起方式 |
|------|---------|
| 新人入职认证 | 管理员发起(强制) |
| 认证后自评 | 学员可自评 |
---
## 二、组织架构与权限设计
### 2.1 组织结构
```
公司
├── 本部A
│ ├── 开发部
│ └── 其他部门
└── 本部B
├── 开发部
└── 其他部门
```
### 2.2 角色权限矩阵
| 角色 | 查看自己 | 查看本部门 | 查看全公司 | 题库管理 | 发起评估 | 复查 |
|------|---------|-----------|-----------|---------|---------|------|
| 学员 | ✅ | ❌ | ❌ | ❌ | 自评 | ❌ |
| 开发部长 | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ |
| 本部长 | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ |
| 公司高管 | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ |
| 管理员 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| 讲师 | ✅ | ✅ | ✅ | ❌ | ❌ | ✅ |
### 2.3 权限规则
- 学员只能看自己的历史成绩
- 各级管理者可查看下属员工成绩
- 管理员可查看全部数据、管理题库
- 讲师仅用于复查调整分数
---
## 三、模块A:题库管理
### 3.1 功能清单
| 功能 | 说明 | 优先级 |
|------|------|--------|
| 创建题库 | 关联知识库,关联模板(一对一),设定题目范围 | P0 |
| 单题管理 | 增删改查,支持简答/选择/判断 | P0 |
| AI批量生成 | 按模板dimensionQuota配置生成待审题目 | P0 |
| 智能标注 | AI自动标注维度、难度 | P1 |
| 单题审核 | 逐题审核(可批量选择操作) | P0 |
| 相似检测 | 检测与已有题目重复度 | P2 |
| 查询统计 | 多条件筛选、维度分布、使用统计 | P1 |
### 3.2 题目属性
| 属性 | 类型 | 说明 |
|------|------|------|
| questionText | string | 题干文字 |
| questionType | enum | SHORT_ANSWER/MULTIPLE_CHOICE/TRUE_FALSE |
| options | string[] | ABCD选项 |
| correctAnswer | string | 正确答案 |
| keyPoints | string[] | 评分要点 |
| difficulty | enum | STANDARD/ADVANCED/SPECIALIST |
| dimension | enum | PROMPT/LLM/IDE/DEV_PATTERN/WORK_CAPABILITY |
| basis | string | 出题依据 |
### 3.3 模板与题库关联
- **方案**:一对一关系(模板→单一题库)
- 题库不单独关联知识库,由模板指定知识库范围
- 模板配置 `dimensionQuota` 字段指定各维度题目数量
### 3.4 审核流程
```
草稿(DRAFT)
↓ [提交审核]
待审核(PENDING_REVIEW)
↓ [单题审核:逐题通过/否决]
├── 通过 → 发布(PUBLISHED)
└── 否决 → 草稿(DRAFT) + 审核意见
```
### 3.5 版本管理
- 简化版:仅记录最近一次修改时间和修改人
### 3.6 数据模型
```typescript
// QuestionBank 实体
{
id: string;
templateId: string; // 关联模板(一对一)
name: string; // 题库名称
description: string; // 描述
status: enum; // DRAFT/PENDING_REVIEW/PUBLISHED
createdBy: string;
reviewedBy: string; // 审核人
reviewedAt: Date; // 审核时间
reviewComment: string; // 审核意见
createdAt: Date;
updatedAt: Date;
}
// QuestionBankItem 实体
{
id: string;
bankId: string; // 关联题库
questionText: string; // 题干
questionType: enum; // 题型
options: string[]; // 选项
correctAnswer: string; // 答案
keyPoints: string[]; // 关键点
difficulty: enum; // 难度
dimension: enum; // 维度
basis: string; // 出题依据
createdBy: string;
createdAt: Date;
status: enum; // PENDING_REVIEW/PUBLISHED
}
```
### 3.7 API设计
```typescript
// 题库CRUD
POST /api/question-banks // 创建题库
GET /api/question-banks // 列表(分页)
GET /api/question-banks/:id // 详情
PUT /api/question-banks/:id // 更新
DELETE /api/question-banks/:id // 删除
// 题目管理
POST /api/question-banks/:bankId/items // 添加题目
PUT /api/question-banks/:bankId/items/:id // 更新题目
DELETE /api/question-banks/:bankId/items/:id // 删除题目
// 批量操作
POST /api/question-banks/:bankId/generate // AI批量生成
POST /api/question-banks/:bankId/batch-add // 批量导入
// 审核流程
PUT /api/question-banks/:id/submit // 提交审核
PUT /api/question-banks/:bankId/items/:id/review // 单题审核
PUT /api/question-banks/:id/publish // 发布
PUT /api/question-banks/:id/unpublish // 下架
// 查询
GET /api/question-banks/by-template/:templateId // 按模板查询
```
---
## 四、模块B:评估执行
### 4.1 功能清单
| 功能 | 说明 | 优先级 |
|------|------|--------|
| 题目抽取 | 按模板/维度均衡/高频优先抽取 | P0 |
| 答题交互 | 展示题目、接收答案、即时反馈 | P0 |
| AI评分 | 按关键点评分,0-10分 | P0 |
| 追问机制 | 预置追问+超时降级 | P0 |
| 时间控制 | 单题限时+总时长限制(超时不记分) | P1 |
| 中断处理 | 超时强制提交 | P0 |
| 成绩判定 | ≥6分通过 | P0 |
### 4.2 题目抽取算法
```typescript
function selectQuestions(bankId, templateConfig) {
// 1. 按模板指定的知识库范围查已发布题目
// 2. 按dimensionQuota配置的比例抽取
// 3. 高频题目优先被抽(不限制重复次数)
// 4. 不足时提示"题库不足"
}
```
### 4.3 追问机制
| 方案 | 说明 |
|------|------|
| 预置追问 | 题库中预存追问内容 |
| 实时补充 | 超时则降级跳过 |
| 追问限制 | 最多2次追问 |
### 4.4 时间控制
| 限制 | 默认值 | 超时处理 |
|------|--------|---------|
| 单题限时 | 300秒 | 超时不记分,自动下一题 |
| 总时长限制 | 1800秒 | 超时强制提交 |
### 4.5 中断处理
- 评估进行中中断,超时强制提交
- 已答题目计入成绩,超时题目不记分
### 4.6 评估流程
```
开始评估
加载模板(数量/dimensionQuota/时长)
从题库抽取题目(维度均衡)
展示第1题
用户答题
AI评分(按关键点0-10分)
追问?(预置+超时降级)
下一题(循环至最后一题)
生成报告 + 判断通过/未通过(≥6分)
通过 → 发放证书(首次通过才发)
```
### 4.7 API设计
```typescript
// 评估管理
POST /api/assessment/start // 发起评估
GET /api/assessment/:id/state // 获取状态
POST /api/assessment/:id/answer // 提交答案
// 评估管理(管理员)
GET /api/assessment // 所有评估列表
GET /api/assessment/:id // 评估详情
DELETE /api/assessment/:id // 删除评估
```
---
## 五、模块C:成绩管理
### 5.1 功能清单
| 功能 | 说明 | 优先级 |
|------|------|--------|
| 成绩查看 | 按权限查看成绩 | P0 |
| 统计报表 | 通过率/分数/趋势/雷达图 | P1 |
| 历史管理 | 保留最近3次 | P1 |
| 导出功能 | Excel/PDF/CSV | P1 |
| 复查功能 | 只能调整最终总分 | P2 |
| 统计缓存 | 准实时(缓存5分钟) | P1 |
### 5.2 统计维度
| 维度 | 说明 |
|------|------|
| 通过人数/通过率 | 整体和分组 |
| 平均分/最高分/最低分 | 按组统计 |
| 各维度平均分 | 雷达图数据 |
| 评估次数趋势 | 时序折线图 |
### 5.3 报表页面
```
┌──────────────────────────────────────────┐
│ 成绩统计 [导出] [筛选] │
├──────────────────────────────────────────┤
│ 总人数 │ 通过率 │ 平均分 │ 待审核 │
│ 156 │ 82% │ 7.5 │ 3 │
├──────────────────────────────────────────┤
│ 雷达图(各维度平均分) │
│ prompt ████████ 8.2 │
│ llm ███████░░ 7.6 │
│ ide ██████░░░ 6.8 │
│ devPattern █████░░░░ 6.2 │
│ workCap ██████░░░░ 6.5 │
├──────────────────────────────────────────┤
│ 成绩列表(按组织筛选) │
│ 姓名 │ 部门 │ 分数 │ 状态 │ 时间 │ 操作 │
│ [查看] │ [复查] │
└──────────────────────────────────────────┘
```
### 5.4 复查规则
- 讲师只能调整最终总分
- 复查记录可追溯
- **复查不影响已发证书**(保持不变)
### 5.5 API设计
```typescript
// 成绩统计
GET /api/assessment/stats // 当前用户统计
GET /api/assessment/stats/admin // 管理员统计
Query: startDate, endDate, templateId, groupId
// 复查(只调整总分)
PUT /api/assessment/:id/review // 调整总分
```
---
## 六、模块D:证书管理
### 6.1 功能清单
| 功能 | 说明 | 优先级 |
|------|------|--------|
| 证书生成 | 通过即发(首次通过才发) | P1 |
| 证书预览 | 仅预览,不可下载 | P1 |
| 证书验真 | 二维码/ID查询 | P1 |
### 6.2 证书内容
| 字段 | 说明 |
|------|------|
| certificateId | 唯一ID |
| userId | 持证人 |
| templateId | 评估模板 |
| totalScore | 总分 |
| passedAt | 通过时间 |
| qrCode | 防伪二维码 |
### 6.3 证书唯一性规则
- **同一模板只保留第一次通过的证书**
- 后续通过同一评估不生成新证书
- 复查后分数变化不影响已发证书
### 6.4 有效期
- **永久有效**:一次通过,终身有效
### 6.5 证书展示
- 仅提供预览功能,不提供下载
- 可通过二维码或证书ID验证真伪
### 6.6 证书样式
```
┌────────────────────────────────────────┐
│ [公司LOGO] │
│ │
│ 能力认证证书 │
│ │
│ 兹证明 [学员姓名] 通过 │
│ [评估模板名称] 能力评估 │
│ 总分:[分数] 分 │
│ │
│ 发证日期:[日期] │
│ 证书编号:[ID] │
│ │
│ [二维码] │
│ 验证真伪 │
└────────────────────────────────────────┘
```
### 6.7 API设计
```typescript
// 证书
GET /api/assessment/:id/certificate // 获取证书(预览)
POST /api/assessment/certificate/verify // 验证证书
```
---
## 七、实施计划
### 7.1 任务分解
| Phase | Task | 内容 | 优先级 |
|-------|------|------|--------|
| 1 | A1 | 题库实体创建(关联模板一对一) | P0 |
| 1 | A2 | 题目实体创建 | P0 |
| 1 | A3 | 题库Service/Controller | P0 |
| 1 | A4 | AI批量生成(按dimensionQuota配置) | P0 |
| 1 | A5 | 单题审核流程 | P0 |
| 2 | B1 | 题目抽取算法(维度均衡/高频优先) | P0 |
| 2 | B2 | 评估流程接入题库 | P0 |
| 2 | B3 | 追问预置+降级 | P0 |
| 2 | B4 | 时间控制(超时不记分) | P1 |
| 2 | B5 | 中断超时强制提交 | P0 |
| 3 | C1 | 统计API(缓存5分钟) | P1 |
| 3 | C2 | 报表前端 | P1 |
| 3 | C3 | 历史管理(保留3次) | P1 |
| 3 | C4 | 导出功能 | P1 |
| 3 | C5 | 复查功能(只调总分) | P2 |
| 4 | D1 | 证书实体 | P1 |
| 4 | D2 | 证书生成(首次通过才发) | P1 |
| 4 | D3 | 证书预览 | P1 |
| 4 | D4 | 证书验真 | P1 |
### 7.2 执行顺序
```
Phase 1 (题库)
Phase 2 (评估)
Phase 3 (成绩)
Phase 4 (证书)
```
### 7.3 里程碑
| 里程碑 | 内容 | 时间 |
|--------|------|------|
| M1 | 题库管理基础功能 | 1周 |
| M2 | 评估流程优化 | 1周 |
| M3 | 成绩报表 | 1周 |
| M4 | 证书功能 | 1周 |
| M5 | 测试优化 | 1周 |
---
## 八、验收标准
- [ ] 题库支持创建/关联模板(一对一)/辑/单题审核/发布
- [ ] AI批量生成题目按dimensionQuota配置
- [ ] 评估可从题库维度均衡抽取
- [ ] 追问支持预置+降级
- [ ] 超时不记分,中断超时强制提交
- [ ] 成绩按组织架构权限隔离
- [ ] 统计准实时(缓存5分钟)
- [ ] 历史记录保留最近3次
- [ ] 复查只能调整总分,不影响已发证书
- [ ] 通过后生成证书(首次通过才发)
- [ ] 证书仅预览不可下载
- [ ] 证书可验真(二维码/ID
---
## 九、闭环确认
### 数据流闭环
```
知识库 → 模板 → 题库(AI生成+单题审核)→ 评估抽取 → 用户答题 → 评分 → 成绩 → 证书
复查(调总分)
```
### 关键闭环点
| 检查点 | 确认 |
|--------|------|
| 知识库→题库 | ✅ AI生成题目关联知识库 |
| 题库→评估 | ✅ 按模板(一对一)抽取已发布题目 |
| 评估→成绩 | ✅ 答题后记录成绩 |
| 成绩→证书 | ✅ 首次通过后生成证书 |
| 复查→成绩 | ✅ 讲师可调整总分 |
| 复查→证书 | ✅ 不影响已发证书 |
---
## 附录
### A. 相关文档
- `docs/plans/2026-04-18-l1-talent-assessment-design.md` - L1设计
- `docs/plans/2026-04-20-assessment-system-complete-plan.md` - 旧版计划
### B. 现有代码参考
- `server/src/assessment/` - 评估模块
- `web/components/views/AssessmentView.tsx` - 前端评估界面
### C. 评审记录
| 日期 | 版本 | 变更内容 |
|------|------|----------|
| 2026-04-23 | 1.0 | 初稿 |
| 2026-04-23 | 2.0 | 评审通过,更新10项确认内容 |
### D. 评审确认内容(v2.0
1. 模板新增 `dimensionQuota` 字段配置各维度数量
2. 审核改为单题逐审(可批量选择操作)
3. 超时不记分(不影响得分)
4. 中断超时强制提交
5. 统计准实时(缓存5分钟)
6. 复查只能调整最终总分
7. 同一模板只保留首次通过证书
8. 证书仅预览不可下载
9. 模板一对一题库
10. 复查不影响已发证书(保持不变)
---
**文档状态**: ✅ 最终版(评审通过)
**下一步**: 进入实施阶段
@@ -0,0 +1,517 @@
# AuraK 人才测评体系完整实施计划
> **文档状态**: 待评审
> **创建日期**: 2026-04-23
> **版本**: 1.0
---
## 一、系统概述
### 1.1 目标
构建一个完整的AI人才测评体系,实现"选→育→评→用"闭环。聚焦在**评(认证)阶段**,形成包含题库管理、评估执行、成绩管理、证书管理的完整系统。
### 1.2 核心流程
```
人才输入 → 评估执行 → 结果输出 → 应用决策
↑___________↓
持续反馈
```
### 1.3 评估发起模式
| 场景 | 发起方式 |
|------|---------|
| 新人入职认证 | 管理员发起(强制) |
| 认证后自评 | 学员可自评 |
---
## 二、组织架构与权限设计
### 2.1 组织结构
```
公司
├── 本部A
│ ├── 开发部
│ └── 其他部门
└── 本部B
├── 开发部
└── 其他部门
```
### 2.2 角色权限矩阵
| 角色 | 查看自己 | 查看本部门 | 查看全公司 | 题库管理 | 发起评估 | 复查 |
|------|---------|-----------|-----------|---------|---------|------|
| 学员 | ✅ | ❌ | ❌ | ❌ | 自评 | ❌ |
| 开发部长 | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ |
| 本部长 | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ |
| 公司高管 | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ |
| 管理员 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| 讲师 | ✅ | ✅ | ✅ | ❌ | ❌ | ✅ |
### 2.3 权限规则
- 学员只能看自己的历史成绩
- 各级管理者可查看下属员工成绩
- 管理员可查看全部数据、管理题库
- 讲师仅用于复查调整分数
---
## 三、模块A:题库管理
### 3.1 功能清单
| 功能 | 说明 | 优先级 |
|------|------|--------|
| 创建题库 | 关联知识库,设定题目范围 | P0 |
| 单题管理 | 增删改查,支持简答/选择/判断 | P0 |
| AI批量生成 | 按模板维度配置生成待审题目 | P0 |
| 智能标注 | AI自动标注维度、难度 | P1 |
| 审核流程 | 草稿→待审→发布/否决 | P0 |
| 相似检测 | 检测与已有题目重复度 | P2 |
| 查询统计 | 多条件筛选、维度分布、使用统计 | P1 |
### 3.2 题目属性
| 属性 | 类型 | 说明 |
|------|------|------|
| questionText | string | 题干文字 |
| questionType | enum | SHORT_ANSWER/MULTIPLE_CHOICE/TRUE_FALSE |
| options | string[] | ABCD选项 |
| correctAnswer | string | 正确答案 |
| keyPoints | string[] | 评分要点 |
| difficulty | enum | STANDARD/ADVANCED/SPECIALIST |
| dimension | enum | PROMPT/LLM/IDE/DEV_PATTERN/WORK_CAPABILITY |
| basis | string | 出题依据 |
### 3.3 题目与知识库关联
- **方案**:题目不单独关联知识库
- 由模板指定知识库范围,范围内题目均可被抽取
- 模板预设各维度的题目数量
### 3.4 审核流程
```
草稿(DRAFT)
↓ [提交审核]
待审核(PENDING_REVIEW)
↓ [通过] ↓ [否决]
已发布(PUBLISHED) 草稿(DRAFT)
+ 审核意见
```
### 3.5 版本管理
- 简化版:仅记录最近一次修改时间和修改人
### 3.6 数据模型
```typescript
// QuestionBank 实体
{
id: string;
templateId: string; // 关联模板
name: string; // 题库名称
description: string; // 描述
status: enum; // DRAFT/PENDING_REVIEW/PUBLISHED
createdBy: string;
reviewedBy: string; // 审核人
reviewedAt: Date; // 审核时间
reviewComment: string; // 审核意见
createdAt: Date;
updatedAt: Date;
}
// QuestionBankItem 实体
{
id: string;
bankId: string; // 关联题库
questionText: string; // 题干
questionType: enum; // 题型
options: string[]; // 选项
correctAnswer: string; // 答案
keyPoints: string[]; // 关键点
difficulty: enum; // 难度
dimension: enum; // 维度
basis: string; // 出题依据
createdBy: string;
createdAt: Date;
}
```
### 3.7 API设计
```typescript
// 题库CRUD
POST /api/question-banks // 创建题库
GET /api/question-banks // 列表(分页)
GET /api/question-banks/:id // 详情
PUT /api/question-banks/:id // 更新
DELETE /api/question-banks/:id // 删除
// 题目管理
POST /api/question-banks/:bankId/items // 添加题目
PUT /api/question-banks/:bankId/items/:id // 更新题目
DELETE /api/question-banks/:bankId/items/:id // 删除题目
// 批量操作
POST /api/question-banks/:bankId/generate // AI批量生成
POST /api/question-banks/:bankId/batch-add // 批量导入
// 审核流程
PUT /api/question-banks/:id/submit // 提交审核
PUT /api/question-banks/:id/review // 审核
PUT /api/question-banks/:id/publish // 发布
PUT /api/question-banks/:id/unpublish // 下架
// 查询
GET /api/question-banks/by-template/:templateId // 按模板查询
```
---
## 四、模块B:评估执行
### 4.1 功能清单
| 功能 | 说明 | 优先级 |
|------|------|--------|
| 题目抽取 | 按模板/维度均衡/高频优先抽取 | P0 |
| 答题交互 | 展示题目、接收答案、即时反馈 | P0 |
| AI评分 | 按关键点评分,0-10分 | P0 |
| 追问机制 | 预置追问+超时降级 | P0 |
| 时间控制 | 单题限时+总时长限制 | P1 |
| 成绩判定 | ≥6分通过 | P0 |
### 4.2 题目抽取算法
```typescript
function selectQuestions(bankId, templateConfig) {
// 1. 按模板指定的知识库范围查已发布题目
// 2. 按维度比例随机抽取
// 3. 高频题目优先被抽(不限制重复次数)
// 4. 不足时提示"题库不足"
}
```
### 4.3 追问机制
| 方案 | 说明 |
|------|------|
| 预置追问 | 题库中预存追问内容 |
| 实时补充 | 超时则降级跳过 |
| 追问限制 | 最多2次追问 |
### 4.4 时间控制
| 限制 | 说明 | 默认值 |
|------|------|--------|
| 单题限时 | 超时强制下一题 | 300秒 |
| 总时长限制 | 超时强制提交 | 1800秒 |
### 4.5 评估流程
```
开始评估
加载模板(数量/维度/时长)
从题库抽取题目(维度均衡)
展示第1题
用户答题
AI评分(按关键点0-10分)
追问?(预置+超时降级)
下一题(循环至最后一题)
生成报告 + 判断通过/未通过(≥6分)
通过 → 发放证书
```
### 4.6 API设计
```typescript
// 评估管理
POST /api/assessment/start // 发起评估
GET /api/assessment/:id/state // 获取状态
POST /api/assessment/:id/answer // 提交答案
// 评估管理(管理员)
GET /api/assessment // 所有评估列表
GET /api/assessment/:id // 评估详情
DELETE /api/assessment/:id // 删除评估
```
---
## 五、模块C:成绩管理
### 5.1 功能清单
| 功能 | 说明 | 优先级 |
|------|------|--------|
| 成绩查看 | 按权限查看成绩 | P0 |
| 统计报表 | 通过率/分数/趋势/雷达图 | P1 |
| 历史管理 | 保留最近3次 | P1 |
| 导出功能 | Excel/PDF/CSV | P1 |
| 复查功能 | 讲师调整分数 | P2 |
### 5.2 统计维度
| 维度 | 说明 |
|------|------|
| 通过人数/通过率 | 整体和分组 |
| 平均分/最高分/最低分 | 按组统计 |
| 各维度平均分 | 雷达图数据 |
| 评估次数趋势 | 时序折线图 |
### 5.3 报表页面
```
┌──────────────────────────────────────────┐
│ 成绩统计 [导出] [筛选] │
├──────────────────────────────────────────┤
│ 总人数 │ 通过率 │ 平均分 │ 待审核 │
│ 156 │ 82% │ 7.5 │ 3 │
├──────────────────────────────────────────┤
│ 雷达图(各维度平均分) │
│ prompt ████████ 8.2 │
│ llm ███████░░ 7.6 │
│ ide ██████░░░ 6.8 │
│ devPattern █████░░░░ 6.2 │
│ workCap ██████░░░░ 6.5 │
├──────────────────────────────────────────┤
│ 成绩列表(按组织筛选) │
│ 姓名 │ 部门 │ 分数 │ 状态 │ 时间 │ 操作 │
│ [查看] │ [复查] │
└─────────────────────────────────────────┘
```
### 5.4 API设计
```typescript
// 成绩统计
GET /api/assessment/stats // 当前用户统计
GET /api/assessment/stats/admin // 管理员统计
Query: startDate, endDate, templateId, groupId
// 复查
PUT /api/assessment/:id/review // 调整分数
```
---
## 六、模块D:证书管理
### 6.1 功能清单
| 功能 | 说明 | 优先级 |
|------|------|--------|
| 证书生成 | 通过即发 | P1 |
| 证书下载 | PDF导出 | P1 |
| 证书验真 | 二维码/ID查询 | P1 |
### 6.2 证书内容
| 字段 | 说明 |
|------|------|
| certificateId | 唯一ID |
| userId | 持证人 |
| templateId | 评估模板 |
| totalScore | 总分 |
| passedAt | 通过时间 |
| qrCode | 防伪二维码 |
### 6.3 有效期
- **永久有效**:一次通过,终身有效
### 6.4 证书样式
```
┌────────────────────────────────────────┐
│ [公司LOGO] │
│ │
│ 能力认证证书 │
│ │
│ 兹证明 [学员姓名] 通过 │
│ [评估模板名称] 能力评估 │
│ 总分:[分数] 分 │
│ │
│ 发证日期:[日期] │
│ 证书编号:[ID] │
│ │
│ [二维码] │
│ 验证真伪 │
└────────────────────────────────────────┘
```
### 6.5 API设计
```typescript
// 证书
GET /api/assessment/:id/certificate // 获取证书
GET /api/assessment/:id/certificate/download // 下载PDF
POST /api/assessment/certificate/verify // 验证证书
```
---
## 七、实施计划
### 7.1 任务分解
| Phase | Task | 内容 | 优先级 |
|-------|------|------|--------|
| 1 | A1 | 题库实体创建 | P0 |
| 1 | A2 | 题目实体创建 | P0 |
| 1 | A3 | 题库Service/Controller | P0 |
| 1 | A4 | AI批量生成 | P0 |
| 1 | A5 | 审核流程 | P0 |
| 2 | B1 | 题目抽取算法 | P0 |
| 2 | B2 | 评估流程接入题库 | P0 |
| 2 | B3 | 追问预置+降级 | P0 |
| 2 | B4 | 时间控制 | P1 |
| 3 | C1 | 统计API | P1 |
| 3 | C2 | 报表前端 | P1 |
| 3 | C3 | 历史管理 | P1 |
| 3 | C4 | 导出功能 | P1 |
| 4 | D1 | 证书实体 | P1 |
| 4 | D2 | 证书生成 | P1 |
| 4 | D3 | 证书下载/验真 | P1 |
| 5 | E1 | 复查功能 | P2 |
### 7.2 执行顺序
```
Phase 1 (题库)
Phase 2 (评估)
Phase 3 (成绩)
Phase 4 (证书)
Phase 5 (复查)
```
### 7.3 里程碑
| 里程碑 | 内容 | 时间 |
|--------|------|------|
| M1 | 题库管理基础功能 | 1周 |
| M2 | 评估流程优化 | 1周 |
| M3 | 成绩报表 | 1周 |
| M4 | 证书功能 | 1周 |
| M5 | 测试优化 | 1周 |
---
## 八、待评审问题
### 8.1 功能确认
| # | 问题 | 选项 |
|---|------|------|
| 1 | 题目抽取是否允许重复? | A.不可重复 B.可重复(推荐) C.限制次数 |
| 2 | 追问方案选择? | A.预置 B.实时 C.预置+降级(推荐) |
| 3 | 单题限时默认值? | 默认300秒 |
| 4 | 总时长限制默认值? | 默认1800秒 |
### 8.2 待扩展功能
- 多维度得分(当前为二元制)
- 组织架构动态调整
- 定时评估任务
---
## 九、验收标准
- [ ] 题库支持创建/编辑/审核/发布
- [ ] AI批量生成题目进入待审状态
- [ ] 评估可从题库维度均衡抽取
- [ ] 追问支持预置+降级
- [ ] 成绩按组织架构权限隔离
- [ ] 统计报表显示通过率/雷达图
- [ ] 通过后自动生成证书
- [ ] 证书可下载/验真
- [ ] 历史记录保留最近3次
---
## 十、技术要点
### 10.1 维度均衡算法
```typescript
function selectQuestions(bankId, count, dimensionRatio) {
const dimensions = ['prompt', 'llm', 'ide', 'devPattern', 'workCapability'];
const selected = [];
const usedIds = new Set();
// 轮询从各维度选取
let dimIdx = 0;
while (selected.length < count) {
const dim = dimensions[dimIdx % dimensions.length];
const available = allItems.filter(
(i) => i.dimension === dim && !usedIds.has(i.id) && i.status === 'PUBLISHED'
);
if (available.length > 0) {
// 高频题目优先
const random = available.sort((a, b) => b.useCount - a.useCount)[0];
selected.push(random);
usedIds.add(random.id);
}
dimIdx++;
}
return selected;
}
```
### 10.2 追问降级策略
```typescript
function getFollowUp(question, userAnswer, followUpCount) {
// 1. 检查预置追问
if (question.predefinedFollowUps && followUpCount < question.predefinedFollowUps.length) {
return question.predefinedFollowUps[followUpCount];
}
// 2. 降级:跳过追问
return null; // 进入下一题
}
```
---
## 附录
### A. 相关文档
- `docs/plans/2026-04-18-l1-talent-assessment-design.md` - L1设计
- `docs/plans/2026-04-20-assessment-system-complete-plan.md` - 旧版计划
### B. 现有代码参考
- `server/src/assessment/` - 评估模块
- `web/components/views/AssessmentView.tsx` - 前端评估界面
---
**文档状态**: 待评审后定稿
**下一步**: 评审并确认各模块功能