import { Inject, Injectable, Logger } from '@nestjs/common' import { PersonalMilestoneStatus, ScheduleStatus } from '@prisma/client' import { Pothos, PothosRef, PothosSchema, SchemaBuilderToken } from '@smatch-corp/nestjs-pothos' import { Builder } from '../Graphql/graphql.builder' import { PrismaService } from '../Prisma/prisma.service' @Injectable() export class PersonalMilestoneSchema extends PothosSchema { constructor( @Inject(SchemaBuilderToken) private readonly builder: Builder, private readonly prisma: PrismaService, ) { super() } @PothosRef() personalMilestone() { return this.builder.prismaObject('PersonalMilestone', { fields: (t) => ({ id: t.exposeID('id', { description: 'The ID of the personal milestone.', }), milestoneOrder: t.exposeInt('milestoneOrder', { description: 'The order of the personal milestone.', }), scheduleId: t.exposeString('scheduleId', { description: 'The ID of the schedule the personal milestone belongs to.', }), schedule: t.relation('schedule', { description: 'The schedule the personal milestone belongs to.', }), userId: t.exposeString('userId', { description: 'The ID of the user the personal milestone belongs to.', }), user: t.relation('user', { description: 'The user the personal milestone belongs to.', }), title: t.exposeString('title', { description: 'The title of the personal milestone.', }), description: t.exposeString('description', { description: 'The description of the personal milestone.', }), status: t.expose('status', { type: PersonalMilestoneStatus, description: 'The status of the personal milestone.', }), createdAt: t.expose('createdAt', { type: 'DateTime', description: 'The date the personal milestone was created.', }), updatedAt: t.expose('updatedAt', { type: 'DateTime', description: 'The date the personal milestone was last updated.', }), }), }) } @Pothos() init(): void { this.builder.queryFields((t) => ({ personalMilestone: t.prismaField({ type: this.personalMilestone(), args: this.builder.generator.findUniqueArgs('PersonalMilestone'), description: 'Retrieve a single personal milestone by its unique identifier.', resolve: async (_query, _root, args, ctx, _info) => { if (!ctx.me) { throw new Error('Cannot get your info') } return this.prisma.personalMilestone.findUnique({ where: args.where, }) }, }), personalMilestones: t.prismaField({ type: [this.personalMilestone()], args: this.builder.generator.findManyArgs('PersonalMilestone'), description: 'Retrieve multiple personal milestones.', resolve: async (_query, _root, args, ctx, _info) => { if (!ctx.me) { throw new Error('Cannot get your info') } return this.prisma.personalMilestone.findMany({ where: args.filter ?? undefined, orderBy: args.orderBy ?? undefined, skip: args.skip ?? undefined, take: args.take ?? undefined, cursor: args.cursor ?? undefined, }) }, }), })) this.builder.mutationFields((t) => ({ createManyPersonalMilestones: t.prismaField({ type: [this.personalMilestone()], args: { scheduleId: t.arg({ type: 'String', description: 'The ID of the schedule the personal milestone belongs to.', required: true, }), userId: t.arg({ type: 'String', description: 'The ID of the user the personal milestone belongs to.', required: true, }), data: t.arg({ type: [this.builder.generator.getCreateManyInput('PersonalMilestone', ['schedule', 'user'])], description: 'The data for the personal milestone.', required: true, }), }, description: 'Create multiple personal milestones.', resolve: async (_query, _root, args, ctx, _info) => { if (!ctx.me) { throw new Error('Cannot get your info') } const userId = ctx.me.id const result = await this.prisma.personalMilestone.createManyAndReturn({ data: args.data.map((data) => ({ ...data, userId, scheduleId: args.scheduleId, })), skipDuplicates: true, }) // update schedule status to IN_PROGRESS await this.prisma.schedule.update({ where: { id: args.scheduleId }, data: { status: ScheduleStatus.IN_PROGRESS }, }) return result }, }), updatePersonalMilestone: t.prismaField({ type: this.personalMilestone(), args: { where: t.arg({ type: this.builder.generator.getWhereUnique('PersonalMilestone'), description: 'The where clause for the personal milestone.', required: true, }), data: t.arg({ type: this.builder.generator.getUpdateInput('PersonalMilestone'), description: 'The data for the personal milestone.', required: true, }), }, description: 'Update a personal milestone.', resolve: async (_query, _root, args, ctx, _info) => { if (!ctx.me) { throw new Error('Cannot get your info') } const userId = ctx.me.id return this.prisma.personalMilestone.update({ where: { ...args.where, userId, }, data: args.data, }) }, }), deletePersonalMilestone: t.prismaField({ type: this.personalMilestone(), args: { personalMilestoneId: t.arg({ type: 'String', description: 'The ID of the personal milestone to delete.', required: true, }), }, description: 'Delete a personal milestone.', resolve: async (_query, _root, args, ctx, _info) => { if (!ctx.me) { throw new Error('Cannot get your info') } // check if the user is mentor of the schedule where the personal milestone belongs to const personalMilestone = await this.prisma.personalMilestone.findUnique({ where: { id: args.personalMilestoneId }, }) const schedule = await this.prisma.schedule.findUnique({ where: { id: personalMilestone?.scheduleId }, }) if (schedule?.managedServiceId) { const managedService = await this.prisma.managedService.findUnique({ where: { id: schedule.managedServiceId }, }) if (managedService?.mentorId !== ctx.me.id) { throw new Error('Unauthorized') } } return this.prisma.personalMilestone.delete({ where: { id: args.personalMilestoneId, }, }) }, }), })) } }