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
+265
View File
@@ -0,0 +1,265 @@
# AGENTS.md - AuraK (AI人才评测系统)
## Quick Start
```bash
# Start Docker services (WSL)
wsl sudo service docker start
wsl docker compose up -d
# Development
yarn dev # Both: web@13001 + server@3001
cd web && yarn dev # Frontend only (port 13001)
cd server && yarn start:dev # Backend only (port 3001)
```
## Critical Commands
```bash
# Tests (Jest)
cd server && yarn test
cd server && yarn test --testPathPattern=AssessmentService
# Lint & Format
cd server && yarn lint
cd server && yarn format
```
## Services (Docker)
| Service | Port |
|---------|------|
| Frontend (prod) | 80/443 |
| Backend API | 3001 |
| Elasticsearch | 9200 |
| Apache Tika | 9998 |
| LibreOffice | 8100 |
## Environment Setup
```bash
cp server/.env.sample server/.env
cp web/.env.example web/.env
```
Key vars: `OPENAI_API_KEY`, `GEMINI_API_KEY`, `ELASTICSEARCH_HOST`, `JWT_SECRET`
## Architecture
**Stack**: React 19 + TypeScript + Vite (web) | NestJS + LangChain + LangGraph (server)
**Assessment System** (LangGraph state machine):
- `server/src/assessment/graph/builder.ts` - Route logic
- `server/src/assessment/graph/nodes/grader.node.ts` - Scoring
- `server/src/assessment/graph/nodes/interviewer.node.ts` - Question flow
- `server/src/assessment/graph/nodes/generator.node.ts` - Question generation
- `web/components/views/AssessmentView.tsx` - Frontend UI
---
# 完整测评体系设计文档(评审通过版)
> 文档状态: ✅ 评审通过
> 最后更新: 2026-04-23
> 版本: 2.0
---
## 一、测评体系闭环
```
知识库 → 模板 → 题库(AI生成+单题审核) → 评估抽取 → 用户答题 → 评分 → 成绩 → 证书
复查(调整总分)
```
---
## 二、组织架构与权限
### 2.1 组织结构
```
公司
└── 本部A / 本部B
└── 开发部 / 其他部门
```
### 2.2 角色权限
| 角色 | 数据范围 |
|------|---------|
| 学员 | 仅自己 |
| 开发部长 | 开发部全员 |
| 本部长 | 本部全员 |
| 公司高管 | 全公司 |
| 管理员 | 全部数据 |
| 讲师 | 复查(调总分) |
---
## 三、题库管理模块 (A) - ✅评审通过
### 核心规则
- 模板新增 `dimensionQuota` 字段配置各维度题目数量
- 模板与题库**一对一**关系
- **单题逐审**(可批量选择操作)
- 审核流程:草稿 → 待审 → 发布/否决
### 数据模型
```typescript
// QuestionBank
{
id, templateId, name, description,
status: DRAFT/PENDING_REVIEW/PUBLISHED,
createdBy, reviewedBy, reviewedAt, reviewComment
}
// QuestionBankItem
{
id, bankId, questionText, questionType,
options, correctAnswer, keyPoints,
difficulty, dimension, basis,
status: PENDING_REVIEW/PUBLISHED
}
```
---
## 四、评估执行模块 (B) - ✅评审通过
### 核心规则
- 题目抽取:维度均衡/高频优先
- 发起方式:新人强制管理员发起,认证后可自评
- 评分:≥6分通过
- **超时不记分**(不影响得分)
- **中断超时强制提交**
- 追问:预置+超时降级
### 时间控制
| 限制 | 默认值 |
|------|--------|
| 单题限时 | 300秒 |
| 总时长限制 | 1800秒 |
---
## 五、成绩管理模块 (C) - ✅评审通过
### 核心规则
- 权限:按组织架构隔离
- 历史:保留最近3次
- 统计:准实时(**缓存5分钟**
- 复查:**只能调整总分**,不影响已发证书
- 导出:Excel/PDF/CSV
### 统计维度
- 通过率、平均分、最高分
- 各维度平均分(雷达图)
- 评估次数趋势
---
## 六、证书管理模块 (D) - ✅评审通过
### 核心规则
- 生成:首次通过即发
- 唯一性:**同一模板只保留第一次通过的证书**
- 有效期:永久有效
- **仅预览,不可下载**
- 验真:二维码/ID查询
- **复查不影响已发证书**(保持不变)
### 证书内容
| 字段 | 说明 |
|------|------|
| certificateId | 唯一ID |
| userId | 持证人 |
| templateId | 评估模板 |
| totalScore | 总分 |
| passedAt | 通过时间 |
| qrCode | 防伪二维码 |
---
## 七、实施计划(简化版)
| Phase | 内容 | 优先级 |
|-------|------|--------|
| 1 | 题库管理(AI生成+单题审核) | P0 |
| 2 | 评估执行(抽取+超时处理) | P0 |
| 3 | 成绩管理(统计+复查) | P1 |
| 4 | 证书功能(预览+验真) | P1 |
---
## 八、验收标准
- [ ] 模板新增 dimensionQuota 字段
- [ ] 题库与模板一对一关联
- [ ] AI批量生成按dimensionQuota配置
- [ ] 单题逐审(可批量操作)
- [ ] 维度均衡抽取(高频优先)
- [ ] 超时不记分,中断超时强制提交
- [ ] 统计缓存5分钟
- [ ] 复查只调总分
- [ ] 首次通过才发证书
- [ ] 证书仅预览不可下载
- [ ] 同一模板只保留首次证书
- [ ] 复查不影响已发证书
---
## Verified Bug Fixes (DO NOT REVERT)
1. `grader.node.ts:87-89`: Use `let shortFeedback` (not `const`) - scope bug
2. `grader.node.ts:454` & `interviewer.node.ts:104`: Use `questions || []` - undefined array
3. `builder.ts:41`: Use `Math.max(0, questionsLen - nextIndex)` - negative remaining
4. **API consistency**: Frontend uses non-streaming `/answer` (NOT `/answer-stream`)
5. **DeepSeek config**: Use `modelId` not `modelName` in getModel()
6. **targetCount**: Pass to all graph.stream() configurable calls
7. **Question limit**: generator.node.ts limits generation to targetCount
8. **Force emit next question**: When stream doesn't emit updates
## Design Doc Features Verified
| Feature | Status | File |
|---------|--------|------|
| dimensionScores 多维度计分 | ✅ | `assessment.service.ts:131-176` |
| weightConfig 权重配置 | ✅ | Template entity |
| 即时反馈(评分) | ✅ | grader.node.ts |
| shouldFollowUp 追问 | ✅ | grader.node.ts, interviewer.node.ts |
| followUpCount 追问计数 | ✅ | state.ts, assessment-session.entity.ts |
| 题目数量限制 | ✅ | generator.node.ts |
## Code Standards
- **Comments/logs**: English only (enforced)
- **User messages**: i18n required (ja/zh/en support)
- **UI**: Use Toast components, never `alert()`
## TDD Enforcement
When implementing features or fixing bugs:
1. Write failing test first (RED)
2. Run test to verify failure: `cd server && yarn test --testPathPattern=<TestName>`
3. Write minimal code to pass (GREEN)
4. Verify test passes
5. Refactor if needed (all tests must pass)
See `test-driven-development` skill for full TDD workflow.
## Debugging
- Backend logs: Check `assessment.service.ts` submitAnswer method
- Services: `curl http://localhost:9200/_cat/indices`, `curl localhost:9998/tika`
## Related Docs
- `CLAUDE.md` - Detailed architecture and dev guide
- `.cursorrules` - Code constraints (English + i18n)
- `STARTUP.md` - Docker startup guide
- `docs/plans/2026-04-23-assessment-system-full-plan-v2.md` - **完整实施计划(评审通过)**
- `docs/plans/2026-04-18-l1-talent-assessment-design.md` - L1设计文档
- `docs/plans/2026-04-20-assessment-system-complete-plan.md` - 旧版计划