fix: add status guards to prevent data loss

- create: auto-delete REJECTED→throw error; add tenantId filter
- remove: forbid PUBLISHED bank deletion
- removeItem: forbid PUBLISHED item deletion
- generateQuestions: restrict to DRAFT status only
- frontend: render MULTIPLE_CHOICE options/judgment/followupHints
- frontend: add judgment and followupHints to QuestionBankItem type
- add 12 service guard tests (109 total)
This commit is contained in:
Developer
2026-05-21 08:55:35 +08:00
parent e782d180d7
commit 57898f939c
4 changed files with 210 additions and 5 deletions
@@ -266,13 +266,11 @@ export class QuestionBankService {
}
if (createDto.templateId) {
const existing = await this.bankRepository.findOne({
where: { templateId: createDto.templateId },
where: { templateId: createDto.templateId, tenantId: tenantId || undefined as any },
});
if (existing) {
if (existing.status === QuestionBankStatus.DRAFT || existing.status === QuestionBankStatus.REJECTED) {
await this.bankRepository.remove(existing);
} else {
throw new BadRequestException('该模板已关联有效题库,请编辑已有题库');
if (existing.status === QuestionBankStatus.DRAFT || existing.status === QuestionBankStatus.REJECTED || existing.status === QuestionBankStatus.PUBLISHED) {
throw new BadRequestException('该模板已关联题库,请编辑已有题库或删除后重建');
}
}
}
@@ -349,6 +347,9 @@ export class QuestionBankService {
async remove(id: string): Promise<void> {
const bank = await this.findOne(id);
if (bank.status === QuestionBankStatus.PUBLISHED) {
throw new ForbiddenException('已发布的题库不可删除');
}
await this.bankRepository.remove(bank);
}
@@ -441,6 +442,9 @@ export class QuestionBankService {
if (!item) {
throw new NotFoundException(`QuestionBankItem with ID "${itemId}" not found`);
}
if (item.status === QuestionBankItemStatus.PUBLISHED) {
throw new ForbiddenException('已发布的题目不可删除');
}
await this.itemRepository.remove(item);
}
@@ -452,6 +456,10 @@ export class QuestionBankService {
): Promise<QuestionBankItem[]> {
const bank = await this.findOne(bankId);
if (bank.status !== QuestionBankStatus.DRAFT) {
throw new ForbiddenException('仅草稿状态的题库可生成题目');
}
if (count <= 0 || count > 50) {
throw new BadRequestException('生成数量必须在 1-50 之间');
}