F1-F10: audit fixes (dimension normalize, passingScore scale, DB defaults, onDelete, item status filter, timeout event type, userId privacy) + generator.node.ts strict prompt rules (anti-hallucination)

This commit is contained in:
Developer
2026-05-20 11:13:37 +08:00
parent 29bac74b58
commit 83483d8117
13 changed files with 205 additions and 202 deletions
@@ -22,6 +22,7 @@ import {
ReviewDto,
} from '../services/question-bank.service';
import { CombinedAuthGuard } from '../../auth/combined-auth.guard';
import { KnowledgeGroupService } from '../../knowledge-group/knowledge-group.service';
@Controller('question-banks')
@UseGuards(CombinedAuthGuard)
@@ -29,12 +30,20 @@ import { CombinedAuthGuard } from '../../auth/combined-auth.guard';
export class QuestionBankController {
private readonly logger = new Logger(QuestionBankController.name);
constructor(private readonly questionBankService: QuestionBankService) {}
constructor(
private readonly questionBankService: QuestionBankService,
private readonly groupService: KnowledgeGroupService,
) {}
@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);
async create(@Body() createDto: CreateQuestionBankDto, @Req() req: any) {
try {
this.logger.log(`Creating question bank: ${createDto.name}, user: ${req.user?.id}, tenant: ${req.user?.tenantId}`);
return await this.questionBankService.create(createDto, req.user.id, req.user.tenantId);
} catch (err: any) {
this.logger.error(`[create] Failed: ${err.message}`, err.stack);
throw err;
}
}
@Get()
@@ -125,11 +134,32 @@ export class QuestionBankController {
@Body() body: { count: number; knowledgeBaseContent?: string },
@Req() req: any,
) {
this.logger.log(`[generate] Generating ${body.count} questions for bank ${bankId}`);
let content = body.knowledgeBaseContent || '';
if (!content || content.trim().length < 10) {
try {
const bank = await this.questionBankService.findOne(bankId);
if (bank?.template?.knowledgeGroupId) {
const files = await this.groupService.getGroupFiles(
bank.template.knowledgeGroupId,
req.user.id,
req.user.tenantId,
);
content = files
.filter((f: any) => f.content && f.content.trim().length > 0)
.map((f: any) => `--- ${f.title || f.originalName || 'Document'} ---\n${f.content}`)
.join('\n\n');
this.logger.log(`[generate] Auto-loaded ${files.length} files, content length: ${content.length}`);
}
} catch (err: any) {
this.logger.warn(`[generate] Auto-load failed: ${err.message}`);
}
}
this.logger.log(`[generate] Generating ${body.count} questions for bank ${bankId}, content length: ${content.length}`);
return this.questionBankService.generateQuestions(
bankId,
body.count,
body.knowledgeBaseContent || '',
content,
req.user.tenantId,
);
}