feat: enhance quiz schema with JsonList type and add quiz attempt fields

- Introduced a new 'JsonList' scalar type in the GraphQL schema to handle lists of JSON values, improving data structure flexibility.
- Updated the Quiz schema to replace 'Json' type with 'JsonList' for user input and questions, ensuring consistent data handling.
- Added new fields for retrieving quiz attempts, including individual and multiple attempts, with appropriate authorization checks for user roles.
- Enhanced error handling for quiz attempt retrieval to ensure proper access control and user feedback.

These changes improve the overall functionality and maintainability of the quiz feature, providing a more robust data model and user experience.
This commit is contained in:
2024-12-11 17:26:28 +07:00
parent c437022d41
commit 4168bff1e8
4 changed files with 98 additions and 5 deletions

View File

@@ -86,10 +86,10 @@ export class QuizSchema extends PothosSchema {
correctPoints: t.exposeInt('correctPoints'),
totalPoints: t.exposeInt('totalPoints'),
userInput: t.expose('userInput', {
type: 'Json',
type: 'JsonList',
}),
questions: t.expose('questions', {
type: 'Json',
type: 'JsonList',
}),
createdAt: t.expose('createdAt', {
type: 'DateTime',
@@ -227,6 +227,90 @@ export class QuizSchema extends PothosSchema {
}
},
}),
quizAttempt: t.prismaField({
type: this.quizAttempt(),
args: {
id: t.arg({
type: 'String',
required: true,
}),
},
resolve: async (query, _root, args, ctx, _info) => {
if (ctx.isSubscription) {
throw new Error('Not allowed')
}
if (!ctx.http.me) {
throw new Error('Unauthorized')
}
if (!args.id) {
throw new Error('Id is required')
}
const result = await this.prisma.quizAttempt.findUnique({
...query,
where: {
id: args.id,
},
})
if (!result) {
throw new Error('Quiz attempt not found')
}
// check if user is the owner of the quiz attempt
if (
result.userId !== ctx.http.me.id &&
ctx.http.me.role !== Role.CENTER_OWNER &&
ctx.http.me.role !== Role.CENTER_MENTOR &&
ctx.http.me.role !== Role.CUSTOMER
) {
throw new Error('Unauthorized')
}
return result
},
}),
quizAttempts: t.prismaField({
type: [this.quizAttempt()],
args: {
quizId: t.arg({
type: 'String',
required: false,
}),
},
resolve: async (query, _root, args, ctx, _info) => {
if (ctx.isSubscription) {
throw new Error('Not allowed')
}
if (!ctx.http.me) {
throw new Error('Unauthorized')
}
// use case 1: center mentor or center owner
if (ctx.http.me.role === Role.CENTER_MENTOR || ctx.http.me.role === Role.CENTER_OWNER) {
const centerMentor = await this.prisma.centerMentor.findUnique({
where: { mentorId: ctx.http.me.id },
})
if (!centerMentor) {
throw new Error('Center mentor not found')
}
return await this.prisma.quizAttempt.findMany({
...query,
where: {
quiz: {
centerMentorId: centerMentor.mentorId,
},
...(args.quizId ? [{ quizId: args.quizId }] : []),
},
})
}
// use case 2: customer
if (ctx.http.me.role === Role.CUSTOMER) {
return await this.prisma.quizAttempt.findMany({
...query,
where: {
userId: ctx.http.me.id,
...(args.quizId ? [{ quizId: args.quizId }] : []),
},
})
}
},
}),
}))
this.builder.mutationFields((t) => ({
createQuiz: t.prismaField({
@@ -298,7 +382,6 @@ export class QuizSchema extends PothosSchema {
'id',
'createdAt',
'updatedAt',
'quiz',
'user',
'userId',
]),