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,130 @@
import {
Controller,
Get,
Post,
Put,
Delete,
Body,
Param,
Query,
UseGuards,
UsePipes,
ValidationPipe,
Req,
Logger,
} from '@nestjs/common';
import { QuestionBankService } from '../services/question-bank.service';
import {
CreateQuestionBankDto,
UpdateQuestionBankDto,
CreateQuestionBankItemDto,
UpdateQuestionBankItemDto,
ReviewDto,
} from '../services/question-bank.service';
import { CombinedAuthGuard } from '../../auth/combined-auth.guard';
@Controller('question-banks')
@UseGuards(CombinedAuthGuard)
@UsePipes(ValidationPipe)
export class QuestionBankController {
private readonly logger = new Logger(QuestionBankController.name);
constructor(private readonly questionBankService: QuestionBankService) {}
@Post()
create(@Body() createDto: CreateQuestionBankDto, @Req() req: any) {
this.logger.log(`Creating question bank: ${createDto.name}`);
return this.questionBankService.create(createDto, req.user.id, req.user.tenantId);
}
@Get()
findAll(
@Req() req: any,
@Query('page') page?: string,
@Query('limit') limit?: string,
) {
const pageNum = page ? parseInt(page, 10) : undefined;
const limitNum = limit ? parseInt(limit, 10) : undefined;
return this.questionBankService.findAll(
req.user.id,
req.user.tenantId,
pageNum,
limitNum,
);
}
@Get('by-template/:templateId')
async findByTemplateId(@Param('templateId') templateId: string) {
return this.questionBankService.findByTemplateId(templateId);
}
@Get(':id')
async findOne(@Param('id') id: string) {
return this.questionBankService.findOne(id);
}
@Put(':id')
async update(@Param('id') id: string, @Body() updateDto: UpdateQuestionBankDto) {
return this.questionBankService.update(id, updateDto);
}
@Delete(':id')
async remove(@Param('id') id: string) {
return this.questionBankService.remove(id);
}
@Put(':id/submit')
async submitForReview(@Param('id') id: string, @Req() req: any) {
return this.questionBankService.submitForReview(id, req.user.id);
}
@Put(':id/review')
async review(@Param('id') id: string, @Body() reviewDto: ReviewDto, @Req() req: any) {
return this.questionBankService.review(id, reviewDto, req.user.id);
}
@Put(':id/publish')
async publish(@Param('id') id: string) {
return this.questionBankService.publish(id);
}
@Post(':bankId/items')
async addItem(
@Param('bankId') bankId: string,
@Body() createDto: CreateQuestionBankItemDto,
) {
return this.questionBankService.addItem(bankId, createDto);
}
@Put(':bankId/items/:id')
async updateItem(
@Param('bankId') bankId: string,
@Param('id') id: string,
@Body() updateDto: UpdateQuestionBankItemDto,
) {
return this.questionBankService.updateItem(bankId, id, updateDto);
}
@Delete(':bankId/items/:id')
async removeItem(
@Param('bankId') bankId: string,
@Param('id') id: string,
) {
return this.questionBankService.removeItem(bankId, id);
}
@Post(':bankId/generate')
async generate(
@Param('bankId') bankId: string,
@Body() body: { count: number; knowledgeBaseContent?: string },
@Req() req: any,
) {
this.logger.log(`[generate] Generating ${body.count} questions for bank ${bankId}`);
return this.questionBankService.generateQuestions(
bankId,
body.count,
body.knowledgeBaseContent || '',
req.user.tenantId,
);
}
}
@@ -0,0 +1,59 @@
import {
Controller,
Get,
Post,
Body,
Put,
Param,
Delete,
UseGuards,
Req,
} from '@nestjs/common';
import { TemplateService } from '../services/template.service';
import { CreateTemplateDto } from '../dto/create-template.dto';
import { UpdateTemplateDto } from '../dto/update-template.dto';
import { CombinedAuthGuard } from '../../auth/combined-auth.guard';
@Controller('assessment/templates')
@UseGuards(CombinedAuthGuard)
export class TemplateController {
constructor(private readonly templateService: TemplateService) {}
@Post()
create(@Body() createDto: CreateTemplateDto, @Req() req: any) {
return this.templateService.create(
createDto,
req.user.id,
req.user.tenantId,
);
}
@Get()
findAll(@Req() req: any) {
return this.templateService.findAll(req.user.tenantId);
}
@Get(':id')
async findOne(@Param('id') id: string, @Req() req: any) {
return this.templateService.findOne(id, req.user.id, req.user.tenantId);
}
@Put(':id')
async update(
@Param('id') id: string,
@Body() updateDto: UpdateTemplateDto,
@Req() req: any,
) {
return this.templateService.update(
id,
updateDto,
req.user.id,
req.user.tenantId,
);
}
@Delete(':id')
async remove(@Param('id') id: string, @Req() req: any) {
return this.templateService.remove(id, req.user.id, req.user.tenantId);
}
}