import { Inject, Injectable } from '@nestjs/common' import { Pothos, PothosRef, PothosSchema, SchemaBuilderToken } from '@smatch-corp/nestjs-pothos' import { Builder } from '../Graphql/graphql.builder' import { PrismaService } from '../Prisma/prisma.service' import { AnswerType } from '@prisma/client' import { QuestionType } from '@prisma/client' @Injectable() export class QuizSchema extends PothosSchema { constructor( @Inject(SchemaBuilderToken) private readonly builder: Builder, private readonly prisma: PrismaService, ) { super() } // Types section @PothosRef() quiz() { return this.builder.prismaObject('Quiz', { fields: (t) => ({ id: t.exposeID('id'), serviceId: t.exposeID('serviceId'), service: t.relation('service'), quizTitle: t.exposeString('quizTitle'), quizSynopsis: t.exposeString('quizSynopsis'), progressBarColor: t.exposeString('progressBarColor'), nrOfQuestions: t.exposeInt('nrOfQuestions'), questions: t.relation('questions'), createdAt: t.expose('createdAt', { type: 'DateTime', }), updatedAt: t.expose('updatedAt', { type: 'DateTime', }), }), }) } @PothosRef() question() { return this.builder.prismaObject('Question', { fields: (t) => ({ id: t.exposeID('id'), quizId: t.exposeID('quizId'), quiz: t.relation('quiz'), question: t.exposeString('question'), questionType: t.expose('questionType', { type: QuestionType, }), questionPic: t.exposeString('questionPic'), answerSelectionType: t.expose('answerSelectionType', { type: AnswerType, }), answers: t.exposeStringList('answers'), correctAnswer: t.field({ type: this.correctAnswerObject(), resolve: (parent) => parent.correctAnswer, }), messageForCorrectAnswer: t.exposeString('messageForCorrectAnswer'), messageForIncorrectAnswer: t.exposeString('messageForIncorrectAnswer'), explanation: t.exposeString('explanation'), point: t.exposeInt('point'), createdAt: t.expose('createdAt', { type: 'DateTime', }), updatedAt: t.expose('updatedAt', { type: 'DateTime', }), }), }) } @PothosRef() stringType() { return this.builder.objectRef('StringType') } @PothosRef() stringListType() { return this.builder.objectRef('StringListType') } @PothosRef() correctAnswerObject() { const StringType = this.builder.objectType(this.stringType(), { fields: (t) => ({ value: t.string({ resolve: (parent) => parent as string, }), }), }) const StringListType = this.builder.objectType(this.stringListType(), { fields: (t) => ({ items: t.stringList({ resolve: (parent) => parent as string[], }), }), }) return this.builder.unionType('CorrectAnswerObject', { types: [StringType, StringListType], resolveType: (value) => { return Array.isArray(value) ? StringListType : StringType }, }) } @Pothos() init(): void { this.builder.queryFields((t) => ({ quiz: t.prismaField({ type: this.quiz(), args: this.builder.generator.findUniqueArgs('Quiz'), resolve: async (query, _root, args, ctx, _info) => { if (ctx.isSubscription) throw new Error('Subscription is not allowed') if (!ctx.http.me) throw new Error('User is not authenticated') return await this.prisma.quiz.findUnique({ ...query, where: { id: args.where.id } }) }, }), quizzes: t.prismaField({ type: [this.quiz()], args: this.builder.generator.findManyArgs('Quiz'), resolve: async (query, _root, args, ctx, _info) => { if (ctx.isSubscription) throw new Error('Subscription is not allowed') if (!ctx.http.me) throw new Error('User is not authenticated') return await this.prisma.quiz.findMany({ ...query, where: args.filter ?? undefined, orderBy: args.orderBy ?? undefined, cursor: args.cursor ?? undefined, take: args.take ?? undefined, skip: args.skip ?? undefined, }) }, }), })) this.builder.mutationFields((t) => ({ createQuiz: t.prismaField({ type: this.quiz(), args: { data: t.arg({ type: this.builder.generator.getCreateInput('Quiz', ['id', 'centerMentorId', 'createdAt', 'updatedAt']), required: true, }), }, resolve: async (query, _root, args, ctx, _info) => { if (ctx.isSubscription) throw new Error('Subscription is not allowed') if (!ctx.http.me) throw new Error('User is not authenticated') if (!args.data) throw new Error('Data is required') return await this.prisma.quiz.create({ ...query, data: { ...args.data, centerMentorId: ctx.http.me.id, }, }) }, }), updateQuiz: t.prismaField({ type: this.quiz(), args: { where: t.arg({ type: this.builder.generator.getWhereUnique('Quiz'), required: true, }), data: t.arg({ type: this.builder.generator.getUpdateInput('Quiz'), required: true, }), }, resolve: async (query, _root, args, ctx, _info) => { if (ctx.isSubscription) throw new Error('Subscription is not allowed') if (!ctx.http.me) throw new Error('User is not authenticated') return await this.prisma.quiz.update({ ...query, where: args.where, data: args.data, }) }, }), })) } }