- 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
11 KiB
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
// 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
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
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
cd server && npx typeorm query "SELECT linked_group_ids, weight_config FROM assessment_templates LIMIT 1"
Step 3: Commit
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
// In create() method, add:
if (createTemplateDto.linkedGroupIds) {
template.linkedGroupIds = createTemplateDto.linkedGroupIds;
}
if (createTemplateDto.weightConfig) {
template.weightConfig = createTemplateDto.weightConfig;
}
// ... other fields
Step 2: Verify compilation
cd server && npx tsc --noEmit
Step 3: Commit
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
// 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
// In getSessionContent, add dimension tag:
// === Document: [工作能力] ===
// ...content...
Step 3: Commit
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
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
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
// 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
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
// Current: currentFollowUpCount >= 1
// Change to:
if (currentFollowUpCount >= 2 || result.score >= 8 || saysIDontKnow) {
shouldFollowUp = false;
}
Step 2: Commit
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
@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
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
// 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
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
@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
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
@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
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
// 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
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
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
git add web/components/RadarChart.tsx
git commit -m "feat: add radar chart component"
实施顺序
- Task 1.1 → 1.3 (模板扩展)
- Task 2.1 → 2.2 (评估流程)
- Task 3.1 → 3.2 (评分逻辑)
- Task 4.1 → 4.2 (报告)
- Task 5.1 → 5.2 (证书)
- 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测试通过