diff --git a/biome.json b/biome.json index b7dd15a..17642cd 100644 --- a/biome.json +++ b/biome.json @@ -3,7 +3,7 @@ "vcs": { "enabled": false, "clientKind": "git", - "useIgnoreFile": false + "useIgnoreFile": true }, "files": { "ignoreUnknown": false, @@ -30,42 +30,42 @@ "complexity": { "noUselessThisAlias": "error", "noUselessTypeConstraint": "error", - "useArrowFunction": "off" + "useArrowFunction": "error" }, "correctness": { - "noConstAssign": "off", - "noGlobalObjectCalls": "off", - "noInvalidBuiltinInstantiation": "off", - "noInvalidConstructorSuper": "off", - "noNewSymbol": "off", - "noSetterReturn": "off", + "noConstAssign": "error", + "noGlobalObjectCalls": "error", + "noInvalidBuiltinInstantiation": "error", + "noInvalidConstructorSuper": "error", + "noNewSymbol": "error", + "noSetterReturn": "error", "noUndeclaredVariables": "off", - "noUnreachable": "off", - "noUnreachableSuper": "off", + "noUnreachable": "error", + "noUnreachableSuper": "error", "noUnusedVariables": "error", - "useArrayLiterals": "off" + "useArrayLiterals": "error" }, "style": { "noArguments": "error", "noNamespace": "error", "noVar": "error", "useAsConstAssertion": "error", - "useBlockStatements": "off", + "useBlockStatements": "error", "useConst": "error" }, "suspicious": { - "noDuplicateClassMembers": "off", - "noDuplicateObjectKeys": "off", - "noDuplicateParameters": "off", + "noDuplicateClassMembers": "error", + "noDuplicateObjectKeys": "error", + "noDuplicateParameters": "error", "noExplicitAny": "error", "noExtraNonNullAssertion": "error", - "noFunctionAssign": "off", - "noImportAssign": "off", + "noFunctionAssign": "error", + "noImportAssign": "error", "noMisleadingInstantiator": "error", - "noRedeclare": "off", + "noRedeclare": "error", "noUnsafeDeclarationMerging": "error", - "noUnsafeNegation": "off", - "useGetterReturn": "off", + "noUnsafeNegation": "error", + "useGetterReturn": "error", "useNamespaceKeyword": "error" } }, @@ -80,7 +80,7 @@ "arrowParentheses": "always", "bracketSameLine": false, "quoteStyle": "single", - "attributePosition": "auto", + "attributePosition": "multiline", "bracketSpacing": true }, "parser": { diff --git a/package.json b/package.json index ad0d1e9..7d71121 100644 --- a/package.json +++ b/package.json @@ -19,8 +19,10 @@ "prisma:seed": "npx prisma db seed --schema=./epess-database/prisma/schema.prisma", "prisma:format": "npx prisma format --schema=./epess-database/prisma/schema.prisma", "prisma:studio": "dotenv -e .env -- npx prisma studio --schema=./epess-database/prisma/schema.prisma", - "biome:check": "biome check --write --unsafe", + "biome:check": "biome check --write", "biome:format": "biome format --write", + "biome:lint": "biome lint", + "biome:check:unsafe": "biome check --write --unsafe", "test": "jest", "test:watch": "jest --watch", "test:cov": "jest --coverage", diff --git a/src/Analytic/analytic.schema.ts b/src/Analytic/analytic.schema.ts index de83f52..eeec61f 100644 --- a/src/Analytic/analytic.schema.ts +++ b/src/Analytic/analytic.schema.ts @@ -171,9 +171,15 @@ export class AnalyticSchema extends PothosSchema { type: this.customerAnalytic(), description: 'Retrieve a single customer analytic.', resolve: async (_parent, _args, ctx, _info) => { - if (ctx.isSubscription) throw new Error('Not allowed') - if (!ctx.http.me) throw new Error('Unauthorized') - if (ctx.http.me.role !== Role.CUSTOMER) throw new Error('Only customers can access this data') + if (ctx.isSubscription) { + throw new Error('Not allowed') + } + if (!ctx.http.me) { + throw new Error('Unauthorized') + } + if (ctx.http.me.role !== Role.CUSTOMER) { + throw new Error('Only customers can access this data') + } // calculate analytic const activeServiceCount = await this.prisma.order.count({ where: { @@ -217,9 +223,15 @@ export class AnalyticSchema extends PothosSchema { type: this.mentorAnalytic(), description: 'Retrieve a single mentor analytic.', resolve: async (_parent, _args, ctx, _info) => { - if (ctx.isSubscription) throw new Error('Not allowed') - if (!ctx.http.me) throw new Error('Unauthorized') - if (ctx.http.me.role !== Role.CENTER_MENTOR) throw new Error('Only center mentors can access this data') + if (ctx.isSubscription) { + throw new Error('Not allowed') + } + if (!ctx.http.me) { + throw new Error('Unauthorized') + } + if (ctx.http.me.role !== Role.CENTER_MENTOR) { + throw new Error('Only center mentors can access this data') + } // calculate analytic return { userId: ctx.http.me.id, @@ -230,16 +242,24 @@ export class AnalyticSchema extends PothosSchema { type: this.centerAnalytic(), description: 'Retrieve a single center analytic.', resolve: async (_parent, _args, ctx, _info) => { - if (ctx.isSubscription) throw new Error('Not allowed') - if (!ctx.http.me) throw new Error('Unauthorized') - if (ctx.http.me.role !== Role.CENTER_OWNER) throw new Error('Only center owners can access this data') + if (ctx.isSubscription) { + throw new Error('Not allowed') + } + if (!ctx.http.me) { + throw new Error('Unauthorized') + } + if (ctx.http.me.role !== Role.CENTER_OWNER) { + throw new Error('Only center owners can access this data') + } // get center by owner id const center = await this.prisma.center.findUnique({ where: { centerOwnerId: ctx.http.me.id, }, }) - if (!center) throw new Error('Center not found') + if (!center) { + throw new Error('Center not found') + } // calculate analytic // active mentor include center owner @@ -277,7 +297,9 @@ export class AnalyticSchema extends PothosSchema { const service = await this.prisma.service.findUnique({ where: { id: order.serviceId }, }) - if (!service) continue + if (!service) { + continue + } const commission = service.commission const actualRevenue = (order.total || 0) - (order.total || 0) * commission revenue += actualRevenue @@ -318,10 +340,15 @@ export class AnalyticSchema extends PothosSchema { }, description: 'Retrieve a single platform analytic.', resolve: async (_parent, args, ctx, _info) => { - if (ctx.isSubscription) throw new Error('Not allowed') - if (!ctx.http.me) throw new Error('Unauthorized') - if (ctx.http.me.role !== Role.ADMIN && ctx.http.me.role !== Role.MODERATOR) + if (ctx.isSubscription) { + throw new Error('Not allowed') + } + if (!ctx.http.me) { + throw new Error('Unauthorized') + } + if (ctx.http.me.role !== Role.ADMIN && ctx.http.me.role !== Role.MODERATOR) { throw new Error('Only admins and moderators can access this data') + } // calculate analytic for services sorted by args.serviceSortBy and args.timeframes const topServices = await this.prisma.service.findMany({ where: { @@ -428,7 +455,9 @@ export class AnalyticSchema extends PothosSchema { const service = await this.prisma.service.findUnique({ where: { id: order.serviceId }, }) - if (!service) continue + if (!service) { + continue + } const commission = service.commission const actualRevenue = (order.total || 0) - (order.total || 0) * commission revenue += actualRevenue diff --git a/src/CollaborationSession/collaborationsession.schema.ts b/src/CollaborationSession/collaborationsession.schema.ts index 3d712a5..4e3c0f0 100644 --- a/src/CollaborationSession/collaborationsession.schema.ts +++ b/src/CollaborationSession/collaborationsession.schema.ts @@ -73,14 +73,20 @@ export class CollaborationSessionSchema extends PothosSchema { }, description: 'Retrieve a single collaboration session by its unique identifier.', resolve: async (_query, _root, args, ctx, _info) => { - if (ctx.isSubscription) throw new Error('Not allowed') - if (!ctx.http.me) throw new Error('Cannot get your info') + if (ctx.isSubscription) { + throw new Error('Not allowed') + } + if (!ctx.http.me) { + throw new Error('Cannot get your info') + } const scheduleDate = await this.prisma.scheduleDate.findUnique({ where: { id: args.scheduleDateId, }, }) - if (!scheduleDate) throw new Error('Schedule date not found') + if (!scheduleDate) { + throw new Error('Schedule date not found') + } let collaborationSession: CollaborationSession | null = null collaborationSession = await this.prisma.collaborationSession.findUnique({ where: { @@ -90,7 +96,9 @@ export class CollaborationSessionSchema extends PothosSchema { /* ---------- use case 1 : customer get collaboration session by id --------- */ if (ctx.http.me?.role === Role.CUSTOMER && collaborationSession) { // check if user is participant - if (!collaborationSession.collaboratorsIds.includes(ctx.http.me.id)) throw new Error('User not allowed') + if (!collaborationSession.collaboratorsIds.includes(ctx.http.me.id)) { + throw new Error('User not allowed') + } // update schedule date status await this.prisma.scheduleDate.update({ where: { @@ -104,20 +112,30 @@ export class CollaborationSessionSchema extends PothosSchema { } /* ---------- use case 2 : center mentor get collaboration session by schedule date id --------- */ if (ctx.http.me.role !== Role.CENTER_MENTOR && ctx.http.me.role !== Role.CENTER_OWNER) { - if (!collaborationSession) throw new Error('Mentor does not created collaboration session yet') + if (!collaborationSession) { + throw new Error('Mentor does not created collaboration session yet') + } throw new Error('User not allowed') } // check if user is participant - if (!scheduleDate.participantIds.includes(ctx.http.me.id)) throw new Error('User not allowed') + if (!scheduleDate.participantIds.includes(ctx.http.me.id)) { + throw new Error('User not allowed') + } // check if order is exist in schedule date - if (!scheduleDate.orderId) throw new Error('Order not found') + if (!scheduleDate.orderId) { + throw new Error('Order not found') + } const order = await this.prisma.order.findUnique({ where: { id: scheduleDate.orderId, }, }) - if (!order) throw new Error('Order not found') - if (!order.chatRoomId) throw new Error('Order chat room not found') + if (!order) { + throw new Error('Order not found') + } + if (!order.chatRoomId) { + throw new Error('Order chat room not found') + } // only in time before 10 minutes from start time or less and not after end time can create new collaboration session const now = DateTimeUtils.now() const startTime = DateTimeUtils.fromDate(scheduleDate.start) @@ -135,7 +153,9 @@ export class CollaborationSessionSchema extends PothosSchema { id: order.chatRoomId, }, }) - if (!chatRoom) throw new Error('Chat room not found') + if (!chatRoom) { + throw new Error('Chat room not found') + } // create new one Logger.log(`chatRoom: ${chatRoom.id}`) const newCollaborationSession = await this.prisma.collaborationSession.create({ @@ -198,21 +218,29 @@ export class CollaborationSessionSchema extends PothosSchema { liveKitToken: t.field({ type: 'String', resolve: async (_, _args, ctx: SchemaContext) => { - if (ctx.isSubscription) throw new Error('Not allowed') - if (!ctx.http?.me?.id) throw new Error('User not found') + if (ctx.isSubscription) { + throw new Error('Not allowed') + } + if (!ctx.http?.me?.id) { + throw new Error('User not found') + } // check if participantId is in meetingRoomCollaborators const meetingRoomCollaborator = await this.prisma.meetingRoomCollaborator.findFirst({ where: { userId: ctx.http.me.id, }, }) - if (!meetingRoomCollaborator) throw new Error('Meeting room collaborator not found') + if (!meetingRoomCollaborator) { + throw new Error('Meeting room collaborator not found') + } const meetingRoom = await this.prisma.meetingRoom.findUnique({ where: { id: meetingRoomCollaborator.meetingRoomId, }, }) - if (!meetingRoom) throw new Error('Meeting room not found') + if (!meetingRoom) { + throw new Error('Meeting room not found') + } const token = await this.liveKitService.createToken(ctx.http.me, meetingRoom.id) return token }, @@ -235,8 +263,12 @@ export class CollaborationSessionSchema extends PothosSchema { }, description: 'Update the active document ID for a collaboration session.', resolve: async (_query, _root, args, ctx, _info) => { - if (ctx.isSubscription) throw new Error('Not allowed') - if (!ctx.http.me) throw new Error('Cannot get your info') + if (ctx.isSubscription) { + throw new Error('Not allowed') + } + if (!ctx.http.me) { + throw new Error('Cannot get your info') + } // check permission const collaborationSession = await this.prisma.collaborationSession.findUnique({ where: { @@ -246,9 +278,12 @@ export class CollaborationSessionSchema extends PothosSchema { scheduleDate: true, }, }) - if (!collaborationSession) throw new Error('Collaboration session not found') - if (!collaborationSession.scheduleDate.participantIds.includes(ctx.http.me.id)) + if (!collaborationSession) { + throw new Error('Collaboration session not found') + } + if (!collaborationSession.scheduleDate.participantIds.includes(ctx.http.me.id)) { throw new Error('User not allowed') + } const updatedCollaborationSession = await this.prisma.collaborationSession.update({ where: { id: args.collaborationSessionId, @@ -275,14 +310,20 @@ export class CollaborationSessionSchema extends PothosSchema { }), }, subscribe: async (_parent, args, ctx) => { - if (!ctx.isSubscription) throw new Error('Not allowed') - if (!ctx.websocket.me) throw new Error('Cannot get your info') + if (!ctx.isSubscription) { + throw new Error('Not allowed') + } + if (!ctx.websocket.me) { + throw new Error('Cannot get your info') + } const collaborationSession = await this.prisma.collaborationSession.findUnique({ where: { id: args.collaborationSessionId, }, }) - if (!collaborationSession) throw new Error('Collaboration session not found') + if (!collaborationSession) { + throw new Error('Collaboration session not found') + } return ctx.websocket.pubSub.asyncIterableIterator(`collaborationSessionUpdated:${collaborationSession.id}`) }, resolve: async (payload: CollaborationSession) => payload, diff --git a/src/Document/document.schema.ts b/src/Document/document.schema.ts index 968791d..55fb8b8 100644 --- a/src/Document/document.schema.ts +++ b/src/Document/document.schema.ts @@ -94,8 +94,12 @@ export class DocumentSchema extends PothosSchema { type: [this.document()], args: this.builder.generator.findManyArgs('Document'), resolve: async (query, _parent, args, ctx: SchemaContext) => { - if (ctx.isSubscription) throw new Error('Not allowed') - if (!ctx.http?.me?.id) throw new Error('User not found') + if (ctx.isSubscription) { + throw new Error('Not allowed') + } + if (!ctx.http?.me?.id) { + throw new Error('User not found') + } return await this.prisma.document.findMany({ ...query, orderBy: args.orderBy ?? undefined, @@ -133,9 +137,13 @@ export class DocumentSchema extends PothosSchema { type: this.document(), args: {}, resolve: async (query, _args, ctx, _info) => { - if (ctx.isSubscription) throw new Error('Not allowed') + if (ctx.isSubscription) { + throw new Error('Not allowed') + } const userId = ctx.http?.me?.id - if (!userId) throw new Error('User not found') + if (!userId) { + throw new Error('User not found') + } // const fileUrl = await this.minio.getFileUrl('document', 'document', 'document') // if (!fileUrl) throw new Error('File not found') const document = await this.prisma.document.create({ @@ -156,10 +164,18 @@ export class DocumentSchema extends PothosSchema { pageIndex: t.arg({ type: 'Int', required: true }), }, resolve: async (_, args, ctx: SchemaContext) => { - if (ctx.isSubscription) throw new Error('Not allowed') - if (!ctx.http?.me?.id) throw new Error('User not found') - if (!args.documentId) throw new Error('Document id not found') - if (args.pageIndex === undefined || args.pageIndex === null) throw new Error('Page index not found') + if (ctx.isSubscription) { + throw new Error('Not allowed') + } + if (!ctx.http?.me?.id) { + throw new Error('User not found') + } + if (!args.documentId) { + throw new Error('Document id not found') + } + if (args.pageIndex === undefined || args.pageIndex === null) { + throw new Error('Page index not found') + } let delta = null try { delta = await this.minio.getDocumentPage(args.documentId, args.pageIndex) @@ -197,9 +213,13 @@ export class DocumentSchema extends PothosSchema { }), }, resolve: async (query, _parent, args, ctx: SchemaContext) => { - if (ctx.isSubscription) throw new Error('Not allowed') + if (ctx.isSubscription) { + throw new Error('Not allowed') + } const userId = ctx.http?.me?.id - if (!userId) throw new Error('Unauthorized') + if (!userId) { + throw new Error('Unauthorized') + } return await this.prisma.document.create({ ...query, data: { @@ -225,12 +245,16 @@ export class DocumentSchema extends PothosSchema { }), }, resolve: async (_, args, ctx: SchemaContext) => { - if (ctx.isSubscription) throw new Error('Not allowed') + if (ctx.isSubscription) { + throw new Error('Not allowed') + } const { http: { pubSub }, } = ctx const senderId = ctx.http?.me?.id - if (!senderId) throw new Error('User not found') + if (!senderId) { + throw new Error('User not found') + } pubSub.publish(`${DocumentEvent.CHANGED}.${args.data.documentId}`, { ...args.data, senderId, @@ -245,14 +269,24 @@ export class DocumentSchema extends PothosSchema { data: t.arg({ type: this.documentDeltaInput(), required: true }), }, resolve: async (_, args, ctx: SchemaContext) => { - if (ctx.isSubscription) throw new Error('Not allowed') + if (ctx.isSubscription) { + throw new Error('Not allowed') + } const senderId = ctx.http?.me?.id - if (!args.data.documentId) throw new Error('Document id not found') - if (!senderId) throw new Error('User not found') - if (args.data.pageIndex === undefined || args.data.pageIndex === null) throw new Error('Page index not found') + if (!args.data.documentId) { + throw new Error('Document id not found') + } + if (!senderId) { + throw new Error('User not found') + } + if (args.data.pageIndex === undefined || args.data.pageIndex === null) { + throw new Error('Page index not found') + } // save delta to minio const delta = args.data.delta - if (!delta) throw new Error('Delta not found') + if (!delta) { + throw new Error('Delta not found') + } await this.minio.upsertDocumentPage(args.data.documentId, args.data.pageIndex, delta) const totalPage = await this.minio.countDocumentPages(args.data.documentId) return { @@ -283,8 +317,12 @@ export class DocumentSchema extends PothosSchema { }), }, resolve: async (query, _parent, args, ctx: SchemaContext) => { - if (ctx.isSubscription) throw new Error('Not allowed') - if (!ctx.http?.me?.id) throw new Error('Unauthorized') + if (ctx.isSubscription) { + throw new Error('Not allowed') + } + if (!ctx.http?.me?.id) { + throw new Error('Unauthorized') + } // check if user is owner or collaborator const document = await this.prisma.document.findUnique({ where: { id: args.documentId }, @@ -292,7 +330,9 @@ export class DocumentSchema extends PothosSchema { collaborators: true, }, }) - if (!document) throw new Error('Document not found') + if (!document) { + throw new Error('Document not found') + } if ( !document.isPublic && !document.collaborators.some((c) => c.userId === ctx.http?.me?.id && c.writable) && @@ -316,13 +356,19 @@ export class DocumentSchema extends PothosSchema { writable: t.arg({ type: 'Boolean', required: true }), }, resolve: async (_, __, args, ctx: SchemaContext) => { - if (ctx.isSubscription) throw new Error('Not allowed') + if (ctx.isSubscription) { + throw new Error('Not allowed') + } // check if ctx user is owner of document const document = await this.prisma.document.findUnique({ where: { id: args.documentId }, }) - if (!document) throw new Error('Document not found') - if (document.ownerId !== ctx.http?.me?.id) throw new Error('User is not owner of document') + if (!document) { + throw new Error('Document not found') + } + if (document.ownerId !== ctx.http?.me?.id) { + throw new Error('User is not owner of document') + } return await this.prisma.documentCollaborator.create({ data: { documentId: args.documentId, @@ -340,13 +386,19 @@ export class DocumentSchema extends PothosSchema { userId: t.arg({ type: 'String', required: true }), }, resolve: async (_, __, args, ctx: SchemaContext) => { - if (ctx.isSubscription) throw new Error('Not allowed') + if (ctx.isSubscription) { + throw new Error('Not allowed') + } // check if ctx user is owner of document const document = await this.prisma.document.findUnique({ where: { id: args.documentId }, }) - if (!document) throw new Error('Document not found') - if (document.ownerId !== ctx.http?.me?.id) throw new Error('User is not owner of document') + if (!document) { + throw new Error('Document not found') + } + if (document.ownerId !== ctx.http?.me?.id) { + throw new Error('User is not owner of document') + } return await this.prisma.documentCollaborator.delete({ where: { documentId_userId: { documentId: args.documentId, userId: args.userId } }, }) @@ -361,13 +413,19 @@ export class DocumentSchema extends PothosSchema { writable: t.arg({ type: 'Boolean', required: true }), }, resolve: async (_, __, args, ctx: SchemaContext) => { - if (ctx.isSubscription) throw new Error('Not allowed') + if (ctx.isSubscription) { + throw new Error('Not allowed') + } // check if ctx user is owner of document const document = await this.prisma.document.findUnique({ where: { id: args.documentId }, }) - if (!document) throw new Error('Document not found') - if (document.ownerId !== ctx.http?.me?.id) throw new Error('User is not owner of document') + if (!document) { + throw new Error('Document not found') + } + if (document.ownerId !== ctx.http?.me?.id) { + throw new Error('User is not owner of document') + } return await this.prisma.documentCollaborator.update({ where: { documentId_userId: { documentId: args.documentId, userId: args.userId } }, data: { readable: args.readable, writable: args.writable }, @@ -386,7 +444,9 @@ export class DocumentSchema extends PothosSchema { }), }, subscribe: async (_, args, ctx: SchemaContext) => { - if (!ctx.isSubscription) throw new Error('Not allowed') + if (!ctx.isSubscription) { + throw new Error('Not allowed') + } const { websocket: { pubSub }, } = ctx @@ -398,13 +458,16 @@ export class DocumentSchema extends PothosSchema { collaborators: true, }, }) - if (!document) throw new Error('Document not found') + if (!document) { + throw new Error('Document not found') + } if (!document.isPublic) { if ( document.ownerId !== ctx.websocket?.me?.id && !document.collaborators.some((c) => c.userId === ctx.websocket?.me?.id && c.writable && c.readable) - ) + ) { throw new Error('User is not owner or collaborator of document') + } } return pubSub.asyncIterableIterator([ `${DocumentEvent.CHANGED}.${documentId}`, @@ -416,7 +479,9 @@ export class DocumentSchema extends PothosSchema { ]) as unknown as AsyncIterable }, resolve: async (payload: DocumentDelta, _args, ctx: SchemaContext) => { - if (!ctx.isSubscription) throw new Error('Not allowed') + if (!ctx.isSubscription) { + throw new Error('Not allowed') + } if (!payload.requestSync) { // using randomize sync mechanism to avoid performance issue const random = Math.random() diff --git a/src/MeetingRoom/meetingroom.schema.ts b/src/MeetingRoom/meetingroom.schema.ts index c55f1f8..bc2febc 100644 --- a/src/MeetingRoom/meetingroom.schema.ts +++ b/src/MeetingRoom/meetingroom.schema.ts @@ -76,19 +76,25 @@ export class MeetingRoomSchema extends PothosSchema { }), }, resolve: async (_query, _parent, args, ctx: SchemaContext) => { - if (ctx.isSubscription) throw new Error('Not allowed') + if (ctx.isSubscription) { + throw new Error('Not allowed') + } const collaborationSession = await this.prisma.collaborationSession.findUnique({ where: { scheduleDateId: args.scheduleDateId, }, }) - if (!collaborationSession) throw new Error('Collaboration session not found') + if (!collaborationSession) { + throw new Error('Collaboration session not found') + } const meetingRoom = await this.prisma.meetingRoom.findUnique({ where: { collaborationSessionId: collaborationSession.id, }, }) - if (meetingRoom) return meetingRoom + if (meetingRoom) { + return meetingRoom + } return await this.prisma.meetingRoom.create({ data: { collaborationSessionId: collaborationSession.id, @@ -106,19 +112,28 @@ export class MeetingRoomSchema extends PothosSchema { }), }, resolve: async (_, args, ctx: SchemaContext) => { - if (ctx.isSubscription) throw new Error('Not allowed') - if (!ctx.http.me) throw new Error('Unauthorized') + if (ctx.isSubscription) { + throw new Error('Not allowed') + } + if (!ctx.http.me) { + throw new Error('Unauthorized') + } const meetingRoom = await this.prisma.meetingRoom.findUnique({ where: { collaborationSessionId: args.collaborationSessionId }, }) - if (!meetingRoom) throw new Error('Meeting room not found') + if (!meetingRoom) { + throw new Error('Meeting room not found') + } // check if user is collaborator of collaboration session const collaborationSession = await this.prisma.collaborationSession.findUnique({ where: { id: meetingRoom.collaborationSessionId }, }) - if (!collaborationSession) throw new Error('Collaboration session not found') - if (!collaborationSession.collaboratorsIds.includes(ctx.http.me.id)) + if (!collaborationSession) { + throw new Error('Collaboration session not found') + } + if (!collaborationSession.collaboratorsIds.includes(ctx.http.me.id)) { throw new Error('User is not collaborator') + } // create new token const token = await this.livekitService.createToken(ctx.http.me, meetingRoom.id) return { @@ -144,8 +159,12 @@ export class MeetingRoomSchema extends PothosSchema { }), }, resolve: async (query, _parent, args, ctx: SchemaContext) => { - if (ctx.isSubscription) throw new Error('Not allowed') - if (!ctx.http.me) throw new Error('Unauthorized') + if (ctx.isSubscription) { + throw new Error('Not allowed') + } + if (!ctx.http.me) { + throw new Error('Unauthorized') + } return await this.prisma.meetingRoom.create({ ...query, data: args.input, @@ -166,8 +185,12 @@ export class MeetingRoomSchema extends PothosSchema { }), }, resolve: async (query, _parent, args, ctx: SchemaContext) => { - if (ctx.isSubscription) throw new Error('Not allowed') - if (!ctx.http.me) throw new Error('Unauthorized') + if (ctx.isSubscription) { + throw new Error('Not allowed') + } + if (!ctx.http.me) { + throw new Error('Unauthorized') + } return await this.prisma.meetingRoom.update({ ...query, where: { diff --git a/src/Message/message.schema.ts b/src/Message/message.schema.ts index 1aceb23..8b66fe4 100644 --- a/src/Message/message.schema.ts +++ b/src/Message/message.schema.ts @@ -194,7 +194,9 @@ export class MessageSchema extends PothosSchema { }), }, subscribe: (_, args, ctx: SchemaContext) => { - if (!ctx.isSubscription) throw new Error('Not allowed') + if (!ctx.isSubscription) { + throw new Error('Not allowed') + } const { websocket: { pubSub }, } = ctx diff --git a/src/Order/order.schema.ts b/src/Order/order.schema.ts index f1d3549..b4e170d 100644 --- a/src/Order/order.schema.ts +++ b/src/Order/order.schema.ts @@ -117,8 +117,12 @@ export class OrderSchema extends PothosSchema { description: 'Retrieve a list of completed orders', args: this.builder.generator.findManyArgs('Order'), resolve: async (query, _root, args, ctx, _info) => { - if (ctx.isSubscription) throw new Error('Orders cannot be retrieved in subscription context') - if (!ctx.http.me) throw new Error('Unauthorized') + if (ctx.isSubscription) { + throw new Error('Orders cannot be retrieved in subscription context') + } + if (!ctx.http.me) { + throw new Error('Unauthorized') + } // return orders where user is the one who made the order and status is PAID and schedule.dates is in the past return await this.prisma.order.findMany({ ...query, diff --git a/src/PersonalMilestone/personalmilestone.schema.ts b/src/PersonalMilestone/personalmilestone.schema.ts index 4af4fac..079071b 100644 --- a/src/PersonalMilestone/personalmilestone.schema.ts +++ b/src/PersonalMilestone/personalmilestone.schema.ts @@ -65,8 +65,12 @@ export class PersonalMilestoneSchema extends PothosSchema { 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.isSubscription) throw new Error('Not allowed') - if (!ctx.http.me) throw new Error('Cannot get your info') + if (ctx.isSubscription) { + throw new Error('Not allowed') + } + if (!ctx.http.me) { + throw new Error('Cannot get your info') + } return this.prisma.personalMilestone.findUnique({ where: args.where, }) @@ -77,8 +81,12 @@ export class PersonalMilestoneSchema extends PothosSchema { args: this.builder.generator.findManyArgs('PersonalMilestone'), description: 'Retrieve multiple personal milestones.', resolve: async (_query, _root, args, ctx, _info) => { - if (ctx.isSubscription) throw new Error('Not allowed') - if (!ctx.http.me) throw new Error('Cannot get your info') + if (ctx.isSubscription) { + throw new Error('Not allowed') + } + if (!ctx.http.me) { + throw new Error('Cannot get your info') + } return this.prisma.personalMilestone.findMany({ where: args.filter ?? undefined, orderBy: args.orderBy ?? undefined, diff --git a/src/Quiz/quiz.schema.ts b/src/Quiz/quiz.schema.ts index 9cbfb1a..1c6c4c2 100644 --- a/src/Quiz/quiz.schema.ts +++ b/src/Quiz/quiz.schema.ts @@ -135,8 +135,12 @@ export class QuizSchema extends PothosSchema { 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') + 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 } }) }, }), @@ -144,8 +148,12 @@ export class QuizSchema extends PothosSchema { 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') + 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, @@ -167,9 +175,15 @@ export class QuizSchema extends PothosSchema { }), }, 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') + 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, @@ -193,8 +207,12 @@ export class QuizSchema extends PothosSchema { }), }, 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 (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, @@ -218,15 +236,25 @@ export class QuizSchema extends PothosSchema { }), }, 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') - if (!args.data.quiz?.connect?.id) throw new Error('Quiz ID is required') + 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') + } + if (!args.data.quiz?.connect?.id) { + throw new Error('Quiz ID is required') + } // query the quiz to get the questions const quiz = await this.prisma.quiz.findUnique({ where: { id: args.data.quiz.connect.id }, }) - if (!quiz) throw new Error('Quiz not found') + if (!quiz) { + throw new Error('Quiz not found') + } return await this.prisma.quizAttempt.create({ ...query, data: { diff --git a/src/RefundTicket/refundticket.schema.ts b/src/RefundTicket/refundticket.schema.ts index d0b2785..5c1abcd 100644 --- a/src/RefundTicket/refundticket.schema.ts +++ b/src/RefundTicket/refundticket.schema.ts @@ -156,14 +156,21 @@ export class RefundTicketSchema extends PothosSchema { const diffTime = Math.abs(now.diff(orderDate).toMillis()) const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24)) let refundAmount = 0 - if (diffDays < 1) refundAmount = order.total - else if (diffDays < 3) refundAmount = order.total * 0.5 - if (refundAmount === 0) throw new Error('Cannot refund after 3 days') + if (diffDays < 1) { + refundAmount = order.total + } else if (diffDays < 3) { + refundAmount = order.total * 0.5 + } + if (refundAmount === 0) { + throw new Error('Cannot refund after 3 days') + } // create refund ticket // get bank name from bank bin from banks.json // biome-ignore lint/suspicious/noExplicitAny: const bank = banks.data.find((bank: any) => bank.bin === ctx.http.me?.bankBin) - if (!bank) throw new Error('Bank not found') + if (!bank) { + throw new Error('Bank not found') + } const refundTicket = await this.prisma.refundTicket.create({ data: { orderId: order.id, diff --git a/src/Service/service.schema.ts b/src/Service/service.schema.ts index 5e75372..a8ecc4b 100644 --- a/src/Service/service.schema.ts +++ b/src/Service/service.schema.ts @@ -118,8 +118,12 @@ export class ServiceSchema extends PothosSchema { description: 'Whether the user has already provided feedback for the service.', nullable: true, resolve: async (service, _args, ctx) => { - if (ctx.isSubscription) return null - if (!ctx.http.me) return false + if (ctx.isSubscription) { + return null + } + if (!ctx.http.me) { + return false + } const serviceFeedbacks = await this.prisma.serviceFeedback.findMany({ where: { serviceId: service.id, diff --git a/src/ServiceFeedback/servicefeedback.schema.ts b/src/ServiceFeedback/servicefeedback.schema.ts index 574ce90..1b725fd 100644 --- a/src/ServiceFeedback/servicefeedback.schema.ts +++ b/src/ServiceFeedback/servicefeedback.schema.ts @@ -90,10 +90,16 @@ export class ServiceFeedbackSchema extends PothosSchema { }, description: 'Create a new service feedback.', resolve: async (_, _root, args, ctx, _info) => { - if (ctx.isSubscription) throw new Error('Not allowed') - if (!ctx.http?.me) throw new Error('Unauthorized') + if (ctx.isSubscription) { + throw new Error('Not allowed') + } + if (!ctx.http?.me) { + throw new Error('Unauthorized') + } // allow only when user is CUSTOMER and order is completed - if (ctx.http?.me?.role !== Role.CUSTOMER) throw new Error('Unauthorized') + if (ctx.http?.me?.role !== Role.CUSTOMER) { + throw new Error('Unauthorized') + } Logger.log(`args: ${JSON.stringify(args)}`) const order = await this.prisma.order.findFirst({ where: { @@ -109,13 +115,23 @@ export class ServiceFeedbackSchema extends PothosSchema { }, }, }) - if (!order) throw new Error('Order not found') - if (order.userId !== ctx.http?.me?.id) throw new Error('Unauthorized') - if (order.status !== OrderStatus.PAID) throw new Error('Order not completed') + if (!order) { + throw new Error('Order not found') + } + if (order.userId !== ctx.http?.me?.id) { + throw new Error('Unauthorized') + } + if (order.status !== OrderStatus.PAID) { + throw new Error('Order not completed') + } // validate rating - if (args.rating < 0 || args.rating > 5) throw new Error('Invalid rating') + if (args.rating < 0 || args.rating > 5) { + throw new Error('Invalid rating') + } // validate comments - if (args.comments && args.comments.length > 1024) throw new Error('Comments too long') + if (args.comments && args.comments.length > 1024) { + throw new Error('Comments too long') + } return await this.prisma.serviceFeedback.create({ data: { userId: ctx.http?.me?.id, diff --git a/src/User/user.schema.ts b/src/User/user.schema.ts index e5a75eb..0465926 100644 --- a/src/User/user.schema.ts +++ b/src/User/user.schema.ts @@ -185,9 +185,13 @@ export class UserSchema extends PothosSchema { take: t.arg({ type: 'Int', required: false }), }, resolve: async (_parent, args, ctx) => { - if (ctx.isSubscription) throw new Error('Not allowed') + if (ctx.isSubscription) { + throw new Error('Not allowed') + } const me = ctx.http.me - if (!me) throw new Error('User not found') + if (!me) { + throw new Error('User not found') + } // get chat rooms that the user is a part of const chatRooms = await this.prisma.chatRoom.findMany({ @@ -212,7 +216,9 @@ export class UserSchema extends PothosSchema { }, }) - if (!lastMessage) return null + if (!lastMessage) { + return null + } const sender = lastMessage.senderId ? await this.prisma.user.findUnique({ @@ -257,7 +263,9 @@ export class UserSchema extends PothosSchema { ...query, where: args.where, }) - if (!user) throw new Error('User not found') + if (!user) { + throw new Error('User not found') + } return user }, }), @@ -540,7 +548,9 @@ export class UserSchema extends PothosSchema { userScopedMessage: t.field({ type: this.messageSchema.message(), subscribe: async (_, _args, ctx: SchemaContext) => { - if (!ctx.isSubscription) throw new Error('Not allowed') + if (!ctx.isSubscription) { + throw new Error('Not allowed') + } const { websocket: { pubSub }, } = ctx diff --git a/src/Workshop/workshop.schema.ts b/src/Workshop/workshop.schema.ts index 9e4bde8..460ba30 100644 --- a/src/Workshop/workshop.schema.ts +++ b/src/Workshop/workshop.schema.ts @@ -134,15 +134,25 @@ export class WorkshopSchema extends PothosSchema { }, description: 'Create a new workshop.', resolve: async (query, _root, args, ctx, _info) => { - if (ctx.isSubscription) throw new Error('Workshops cannot be created in subscription context') - if (!ctx.http.me) throw new Error('User is not authenticated to create a workshop') - if (ctx.http.me.role !== Role.CENTER_OWNER) throw new Error('Only center owners can create workshops') - if (!args.input.service.connect) throw new Error('Service is required to create a workshop') + if (ctx.isSubscription) { + throw new Error('Workshops cannot be created in subscription context') + } + if (!ctx.http.me) { + throw new Error('User is not authenticated to create a workshop') + } + if (ctx.http.me.role !== Role.CENTER_OWNER) { + throw new Error('Only center owners can create workshops') + } + if (!args.input.service.connect) { + throw new Error('Service is required to create a workshop') + } // check if service is active const service = await this.prisma.service.findUnique({ where: { id: args.input.service.connect.id }, }) - if (!service || !service.isActive) throw new Error('Service is not active') + if (!service || !service.isActive) { + throw new Error('Service is not active') + } const workshop = await this.prisma.workshop.create({ ...query, diff --git a/src/WorkshopMeetingRoom/workshopmeetingroom.schema.ts b/src/WorkshopMeetingRoom/workshopmeetingroom.schema.ts index 328cc25..717845b 100644 --- a/src/WorkshopMeetingRoom/workshopmeetingroom.schema.ts +++ b/src/WorkshopMeetingRoom/workshopmeetingroom.schema.ts @@ -68,14 +68,20 @@ export class WorkshopMeetingRoomSchema extends PothosSchema { }), }, resolve: async (_, args, ctx) => { - if (ctx.isSubscription) throw new Error('Not allowed') - if (!ctx.http?.me) throw new Error('Unauthorized') + if (ctx.isSubscription) { + throw new Error('Not allowed') + } + if (!ctx.http?.me) { + throw new Error('Unauthorized') + } const meetingRoom = await this.prisma.workshopMeetingRoom.findUnique({ where: { workshopId: args.workshopId, }, }) - if (!meetingRoom) throw new Error('Meeting room not found') + if (!meetingRoom) { + throw new Error('Meeting room not found') + } const serverUrl = this.livekitService.getServerUrl() return { id: meetingRoom.id, diff --git a/src/WorkshopSubscription/workshopsubscription.schema.ts b/src/WorkshopSubscription/workshopsubscription.schema.ts index 1e354bc..2dc17c8 100644 --- a/src/WorkshopSubscription/workshopsubscription.schema.ts +++ b/src/WorkshopSubscription/workshopsubscription.schema.ts @@ -59,7 +59,9 @@ export class WorkshopSubscriptionSchema extends PothosSchema { args: this.builder.generator.findManyArgs('WorkshopSubscription'), description: 'Retrieve a list of workshop subscriptions with optional filtering, ordering, and pagination.', resolve: async (query, _root, args, ctx) => { - if (ctx.isSubscription) throw new Error('Workshops cannot be retrieved in subscription context') + if (ctx.isSubscription) { + throw new Error('Workshops cannot be retrieved in subscription context') + } return await this.prisma.workshopSubscription.findMany({ ...query, skip: args.skip ?? undefined, @@ -73,8 +75,12 @@ export class WorkshopSubscriptionSchema extends PothosSchema { type: [this.workshopSubscription()], description: 'Retrieve a list of workshops that the current user is subscribed to.', resolve: async (query, _root, _args, ctx, _info) => { - if (ctx.isSubscription) throw new Error('Workshops cannot be retrieved in subscription context') - if (!ctx.http.me) throw new Error('User is not authenticated') + if (ctx.isSubscription) { + throw new Error('Workshops cannot be retrieved in subscription context') + } + if (!ctx.http.me) { + throw new Error('User is not authenticated') + } return await this.prisma.workshopSubscription.findMany({ ...query, where: { @@ -94,21 +100,31 @@ export class WorkshopSubscriptionSchema extends PothosSchema { }), }, resolve: async (_query, _root, args, ctx) => { - if (ctx.isSubscription) throw new Error('Not allowed in subscription') + if (ctx.isSubscription) { + throw new Error('Not allowed in subscription') + } const userId = ctx.http.me?.id // retrieve the workshop const workshop = await this.prisma.workshop.findUnique({ where: { id: args.workshopId }, }) - if (!workshop) throw new Error('Workshop not found') - if (!userId) throw new Error('User not authenticated') + if (!workshop) { + throw new Error('Workshop not found') + } + if (!userId) { + throw new Error('User not authenticated') + } // check if workshop is in the future - if (workshop.date < DateTimeUtils.now().toJSDate()) throw new Error('Workshop has already started or is over') + if (workshop.date < DateTimeUtils.now().toJSDate()) { + throw new Error('Workshop has already started or is over') + } // check if user is already subscribed to the workshop const existingSubscription = await this.prisma.workshopSubscription.findFirst({ where: { userId, workshopId: args.workshopId }, }) - if (existingSubscription) throw new Error('User already subscribed to workshop') + if (existingSubscription) { + throw new Error('User already subscribed to workshop') + } // create the workshop subscription return await this.prisma.workshopSubscription.create({ data: {