fix(M-AI-07-06): answer leak fixes (A3/A4) + state compatibility
- getQuizQuestions: only return answer/explanation after user has submitted - findOne: remove questions include (use getQuizQuestions instead) - State mapping: lifecycleStatus compatible with legacy status field Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
40e772cc3a
commit
c3b8919489
@ -546,11 +546,20 @@ export class UserAiService {
|
|||||||
async getQuizQuestions(userId: string, quizId: string) {
|
async getQuizQuestions(userId: string, quizId: string) {
|
||||||
const quiz = await this.prisma.quiz.findFirst({ where: { id: quizId, userId }, select: { id: true } });
|
const quiz = await this.prisma.quiz.findFirst({ where: { id: quizId, userId }, select: { id: true } });
|
||||||
if (!quiz) throw new NotFoundException({ errorCode: 'QUIZ_NOT_FOUND', message: 'Quiz not found' });
|
if (!quiz) throw new NotFoundException({ errorCode: 'QUIZ_NOT_FOUND', message: 'Quiz not found' });
|
||||||
|
|
||||||
|
// M-AI-07-06: 检查用户是否已提交过该 Quiz(至少一次 attempt finished)
|
||||||
|
const hasAttempt = await this.prisma.quizAttempt.findFirst({
|
||||||
|
where: { quizId, userId, finishedAt: { not: null } },
|
||||||
|
select: { id: true },
|
||||||
|
});
|
||||||
|
|
||||||
return this.prisma.quizQuestion.findMany({
|
return this.prisma.quizQuestion.findMany({
|
||||||
where: { quizId },
|
where: { quizId },
|
||||||
select: {
|
select: {
|
||||||
id: true, type: true, stem: true, options: true,
|
id: true, type: true, stem: true, options: true,
|
||||||
answer: true, explanation: true, sourceBlockIds: true, orderIndex: true,
|
// ★ M-AI-07-06: 答案和解析仅在用户已提交后返回
|
||||||
|
...(hasAttempt ? { answer: true, explanation: true } : {}),
|
||||||
|
sourceBlockIds: true, orderIndex: true,
|
||||||
},
|
},
|
||||||
orderBy: { orderIndex: 'asc' },
|
orderBy: { orderIndex: 'asc' },
|
||||||
});
|
});
|
||||||
|
|||||||
@ -82,7 +82,9 @@ export class QuizService {
|
|||||||
|
|
||||||
async findOne(id: string) {
|
async findOne(id: string) {
|
||||||
const quiz = await this.prisma.quiz.findUnique({
|
const quiz = await this.prisma.quiz.findUnique({
|
||||||
where: { id }, include: { questions: { orderBy: { orderIndex: 'asc' } } },
|
where: { id },
|
||||||
|
// M-AI-07-06: 不 include questions(避免答案泄漏)
|
||||||
|
// 客户端应使用 getQuizQuestions 获取题目,submit 后通过 getResults 获取答案
|
||||||
});
|
});
|
||||||
if (!quiz) throw new NotFoundException('测验不存在');
|
if (!quiz) throw new NotFoundException('测验不存在');
|
||||||
return quiz;
|
return quiz;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user