diff --git a/src/graphql/graphql.module.ts b/src/graphql/graphql.module.ts index b676452..c1dd724 100644 --- a/src/graphql/graphql.module.ts +++ b/src/graphql/graphql.module.ts @@ -1,13 +1,35 @@ import { Module } from '@nestjs/common'; import { GraphQLModule } from '@nestjs/graphql'; import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo'; -import { schema } from './graphql.schema'; // Assuming you have schema defined in a separate file +const subOperationHandler = (message: any, params: any, webSocket: any) => { + console.log('onOperation'); + return params; +}; @Module({ imports: [ GraphQLModule.forRoot({ driver: ApolloDriver, // Specify the driver - schema, // Your Pothos-generated schema + buildSchemaOptions: { + numberScalarMode: 'integer', + }, + subscriptions: { + 'subscriptions-transport-ws': { + keepAlive: 5000, + path: '/graphql-sub', + onOperation: (message: any, params: any, webSocket: any) => { + subOperationHandler(message, params, webSocket); + return params; + }, + onConnect: (connectionParams: any, webSocket: any) => { + console.log('onConnect'); + return connectionParams; + }, + onDisconnect: (webSocket: any) => { + console.log('onDisconnect'); + }, + }, + }, playground: { workspaceName: 'EPESS', tabs: [ diff --git a/src/graphql/graphql.schema.ts b/src/graphql/graphql.schema.ts index 58f2be9..0f7ca6c 100644 --- a/src/graphql/graphql.schema.ts +++ b/src/graphql/graphql.schema.ts @@ -1,3 +1,28 @@ -import { builder } from '../types/pothos.type'; +import SchemaBuilder from '@pothos/core'; +import { PrismaClient, Prisma } from '@prisma/client'; +import PrismaPlugin from '@pothos/plugin-prisma'; +import type PrismaTypes from '../types/pothos.type'; -export const schema = builder.toSchema(); +const prisma = new PrismaClient({}); + +const readOnlyPrisma = new PrismaClient({ + datasources: { + db: { + url: process.env.READ_ONLY_REPLICA_URL, + }, + }, +}); + +const builder = new SchemaBuilder<{ + Context: { user: { isAdmin: boolean } }; + PrismaTypes: PrismaTypes; +}>({ + plugins: [PrismaPlugin], + prisma: { + client: (ctx) => (ctx.user.isAdmin ? prisma : readOnlyPrisma), + // Because the prisma client is loaded dynamically, we need to explicitly provide the some information about the prisma schema + dmmf: Prisma.dmmf, + }, +}); + +export default builder; \ No newline at end of file diff --git a/src/types/pothos.type.ts b/src/types/pothos.type.ts index ea083d9..39e4cca 100644 --- a/src/types/pothos.type.ts +++ b/src/types/pothos.type.ts @@ -1,30 +1,593 @@ -import { PrismaClient } from '@prisma/client'; -import SchemaBuilder from '@pothos/core'; -import PrismaPlugin from '@pothos/plugin-prisma'; - -const prisma = new PrismaClient(); - -export const builder = new SchemaBuilder({ - plugins: [PrismaPlugin], - prisma: { - client: prisma, - }, -}); - -// Define a basic query type -builder.queryType({ - fields: (t) => ({ - hello: t.string({ - resolve: () => 'Hello, world!', - }), - }), -}); - -// Define a basic mutation type -builder.mutationType({ - fields: (t) => ({ - exampleMutation: t.boolean({ - resolve: () => true, - }), - }), -}); +/* eslint-disable */ +import type { Prisma, User, Center, CenterStaff, Service, ServiceAndCategory, Category, ServiceFeedback, Milestone, Schedule, ChatRoom, Message, Order, RefundTicket, Payment, Workshop, WorkshopSubscription, WorkshopOrganization, UploadedDocument, ServiceMeetingRoom, WorkshopMeetingRoom } from "@prisma/client"; +export default interface PrismaTypes { + User: { + Name: "User"; + Shape: User; + Include: Prisma.UserInclude; + Select: Prisma.UserSelect; + OrderBy: Prisma.UserOrderByWithRelationInput; + WhereUnique: Prisma.UserWhereUniqueInput; + Where: Prisma.UserWhereInput; + Create: {}; + Update: {}; + RelationName: "orders" | "serviceFeedbacks" | "documents" | "sendingMessage" | "Service" | "center" | "customerChatRoom" | "centerStaffChatRoom" | "CenterStaff" | "WorkshopSubscription"; + ListRelations: "orders" | "serviceFeedbacks" | "documents" | "sendingMessage" | "Service" | "customerChatRoom" | "centerStaffChatRoom" | "WorkshopSubscription"; + Relations: { + orders: { + Shape: Order[]; + Name: "Order"; + Nullable: false; + }; + serviceFeedbacks: { + Shape: ServiceFeedback[]; + Name: "ServiceFeedback"; + Nullable: false; + }; + documents: { + Shape: UploadedDocument[]; + Name: "UploadedDocument"; + Nullable: false; + }; + sendingMessage: { + Shape: Message[]; + Name: "Message"; + Nullable: false; + }; + Service: { + Shape: Service[]; + Name: "Service"; + Nullable: false; + }; + center: { + Shape: Center | null; + Name: "Center"; + Nullable: true; + }; + customerChatRoom: { + Shape: ChatRoom[]; + Name: "ChatRoom"; + Nullable: false; + }; + centerStaffChatRoom: { + Shape: ChatRoom[]; + Name: "ChatRoom"; + Nullable: false; + }; + CenterStaff: { + Shape: CenterStaff | null; + Name: "CenterStaff"; + Nullable: true; + }; + WorkshopSubscription: { + Shape: WorkshopSubscription[]; + Name: "WorkshopSubscription"; + Nullable: false; + }; + }; + }; + Center: { + Name: "Center"; + Shape: Center; + Include: Prisma.CenterInclude; + Select: Prisma.CenterSelect; + OrderBy: Prisma.CenterOrderByWithRelationInput; + WhereUnique: Prisma.CenterWhereUniqueInput; + Where: Prisma.CenterWhereInput; + Create: {}; + Update: {}; + RelationName: "services" | "centerOwner" | "chatRoom" | "CenterStaff"; + ListRelations: "services" | "chatRoom" | "CenterStaff"; + Relations: { + services: { + Shape: Service[]; + Name: "Service"; + Nullable: false; + }; + centerOwner: { + Shape: User; + Name: "User"; + Nullable: false; + }; + chatRoom: { + Shape: ChatRoom[]; + Name: "ChatRoom"; + Nullable: false; + }; + CenterStaff: { + Shape: CenterStaff[]; + Name: "CenterStaff"; + Nullable: false; + }; + }; + }; + CenterStaff: { + Name: "CenterStaff"; + Shape: CenterStaff; + Include: Prisma.CenterStaffInclude; + Select: Prisma.CenterStaffSelect; + OrderBy: Prisma.CenterStaffOrderByWithRelationInput; + WhereUnique: Prisma.CenterStaffWhereUniqueInput; + Where: Prisma.CenterStaffWhereInput; + Create: {}; + Update: {}; + RelationName: "staff" | "center" | "service" | "createdWorkshop"; + ListRelations: "createdWorkshop"; + Relations: { + staff: { + Shape: User; + Name: "User"; + Nullable: false; + }; + center: { + Shape: Center; + Name: "Center"; + Nullable: false; + }; + service: { + Shape: Service; + Name: "Service"; + Nullable: false; + }; + createdWorkshop: { + Shape: Workshop[]; + Name: "Workshop"; + Nullable: false; + }; + }; + }; + Service: { + Name: "Service"; + Shape: Service; + Include: Prisma.ServiceInclude; + Select: Prisma.ServiceSelect; + OrderBy: Prisma.ServiceOrderByWithRelationInput; + WhereUnique: Prisma.ServiceWhereUniqueInput; + Where: Prisma.ServiceWhereInput; + Create: {}; + Update: {}; + RelationName: "managedBy" | "feedbacks" | "order" | "center" | "workshop" | "milestone" | "schedule" | "serviceAndCategory" | "workshopOrganization" | "user"; + ListRelations: "managedBy" | "feedbacks" | "order" | "workshop" | "milestone" | "schedule" | "serviceAndCategory" | "workshopOrganization"; + Relations: { + managedBy: { + Shape: CenterStaff[]; + Name: "CenterStaff"; + Nullable: false; + }; + feedbacks: { + Shape: ServiceFeedback[]; + Name: "ServiceFeedback"; + Nullable: false; + }; + order: { + Shape: Order[]; + Name: "Order"; + Nullable: false; + }; + center: { + Shape: Center; + Name: "Center"; + Nullable: false; + }; + workshop: { + Shape: Workshop[]; + Name: "Workshop"; + Nullable: false; + }; + milestone: { + Shape: Milestone[]; + Name: "Milestone"; + Nullable: false; + }; + schedule: { + Shape: Schedule[]; + Name: "Schedule"; + Nullable: false; + }; + serviceAndCategory: { + Shape: ServiceAndCategory[]; + Name: "ServiceAndCategory"; + Nullable: false; + }; + workshopOrganization: { + Shape: WorkshopOrganization[]; + Name: "WorkshopOrganization"; + Nullable: false; + }; + user: { + Shape: User | null; + Name: "User"; + Nullable: true; + }; + }; + }; + ServiceAndCategory: { + Name: "ServiceAndCategory"; + Shape: ServiceAndCategory; + Include: Prisma.ServiceAndCategoryInclude; + Select: Prisma.ServiceAndCategorySelect; + OrderBy: Prisma.ServiceAndCategoryOrderByWithRelationInput; + WhereUnique: Prisma.ServiceAndCategoryWhereUniqueInput; + Where: Prisma.ServiceAndCategoryWhereInput; + Create: {}; + Update: {}; + RelationName: "service" | "category"; + ListRelations: never; + Relations: { + service: { + Shape: Service; + Name: "Service"; + Nullable: false; + }; + category: { + Shape: Category; + Name: "Category"; + Nullable: false; + }; + }; + }; + Category: { + Name: "Category"; + Shape: Category; + Include: Prisma.CategoryInclude; + Select: Prisma.CategorySelect; + OrderBy: Prisma.CategoryOrderByWithRelationInput; + WhereUnique: Prisma.CategoryWhereUniqueInput; + Where: Prisma.CategoryWhereInput; + Create: {}; + Update: {}; + RelationName: "serviceAndCategory"; + ListRelations: "serviceAndCategory"; + Relations: { + serviceAndCategory: { + Shape: ServiceAndCategory[]; + Name: "ServiceAndCategory"; + Nullable: false; + }; + }; + }; + ServiceFeedback: { + Name: "ServiceFeedback"; + Shape: ServiceFeedback; + Include: Prisma.ServiceFeedbackInclude; + Select: Prisma.ServiceFeedbackSelect; + OrderBy: Prisma.ServiceFeedbackOrderByWithRelationInput; + WhereUnique: Prisma.ServiceFeedbackWhereUniqueInput; + Where: Prisma.ServiceFeedbackWhereInput; + Create: {}; + Update: {}; + RelationName: "user" | "service"; + ListRelations: never; + Relations: { + user: { + Shape: User; + Name: "User"; + Nullable: false; + }; + service: { + Shape: Service; + Name: "Service"; + Nullable: false; + }; + }; + }; + Milestone: { + Name: "Milestone"; + Shape: Milestone; + Include: Prisma.MilestoneInclude; + Select: Prisma.MilestoneSelect; + OrderBy: Prisma.MilestoneOrderByWithRelationInput; + WhereUnique: Prisma.MilestoneWhereUniqueInput; + Where: Prisma.MilestoneWhereInput; + Create: {}; + Update: {}; + RelationName: "service"; + ListRelations: never; + Relations: { + service: { + Shape: Service; + Name: "Service"; + Nullable: false; + }; + }; + }; + Schedule: { + Name: "Schedule"; + Shape: Schedule; + Include: Prisma.ScheduleInclude; + Select: Prisma.ScheduleSelect; + OrderBy: Prisma.ScheduleOrderByWithRelationInput; + WhereUnique: Prisma.ScheduleWhereUniqueInput; + Where: Prisma.ScheduleWhereInput; + Create: {}; + Update: {}; + RelationName: "service"; + ListRelations: never; + Relations: { + service: { + Shape: Service; + Name: "Service"; + Nullable: false; + }; + }; + }; + ChatRoom: { + Name: "ChatRoom"; + Shape: ChatRoom; + Include: Prisma.ChatRoomInclude; + Select: Prisma.ChatRoomSelect; + OrderBy: Prisma.ChatRoomOrderByWithRelationInput; + WhereUnique: Prisma.ChatRoomWhereUniqueInput; + Where: Prisma.ChatRoomWhereInput; + Create: {}; + Update: {}; + RelationName: "message" | "customer" | "center" | "centerStaff" | "meetingRoom"; + ListRelations: "message"; + Relations: { + message: { + Shape: Message[]; + Name: "Message"; + Nullable: false; + }; + customer: { + Shape: User; + Name: "User"; + Nullable: false; + }; + center: { + Shape: Center; + Name: "Center"; + Nullable: false; + }; + centerStaff: { + Shape: User | null; + Name: "User"; + Nullable: true; + }; + meetingRoom: { + Shape: ServiceMeetingRoom | null; + Name: "ServiceMeetingRoom"; + Nullable: true; + }; + }; + }; + Message: { + Name: "Message"; + Shape: Message; + Include: Prisma.MessageInclude; + Select: Prisma.MessageSelect; + OrderBy: Prisma.MessageOrderByWithRelationInput; + WhereUnique: Prisma.MessageWhereUniqueInput; + Where: Prisma.MessageWhereInput; + Create: {}; + Update: {}; + RelationName: "sender" | "chatRoom"; + ListRelations: never; + Relations: { + sender: { + Shape: User; + Name: "User"; + Nullable: false; + }; + chatRoom: { + Shape: ChatRoom; + Name: "ChatRoom"; + Nullable: false; + }; + }; + }; + Order: { + Name: "Order"; + Shape: Order; + Include: Prisma.OrderInclude; + Select: Prisma.OrderSelect; + OrderBy: Prisma.OrderOrderByWithRelationInput; + WhereUnique: Prisma.OrderWhereUniqueInput; + Where: Prisma.OrderWhereInput; + Create: {}; + Update: {}; + RelationName: "user" | "payment" | "service" | "refundTicket"; + ListRelations: never; + Relations: { + user: { + Shape: User; + Name: "User"; + Nullable: false; + }; + payment: { + Shape: Payment; + Name: "Payment"; + Nullable: false; + }; + service: { + Shape: Service; + Name: "Service"; + Nullable: false; + }; + refundTicket: { + Shape: RefundTicket | null; + Name: "RefundTicket"; + Nullable: true; + }; + }; + }; + RefundTicket: { + Name: "RefundTicket"; + Shape: RefundTicket; + Include: Prisma.RefundTicketInclude; + Select: Prisma.RefundTicketSelect; + OrderBy: Prisma.RefundTicketOrderByWithRelationInput; + WhereUnique: Prisma.RefundTicketWhereUniqueInput; + Where: Prisma.RefundTicketWhereInput; + Create: {}; + Update: {}; + RelationName: "order"; + ListRelations: never; + Relations: { + order: { + Shape: Order; + Name: "Order"; + Nullable: false; + }; + }; + }; + Payment: { + Name: "Payment"; + Shape: Payment; + Include: Prisma.PaymentInclude; + Select: Prisma.PaymentSelect; + OrderBy: Prisma.PaymentOrderByWithRelationInput; + WhereUnique: Prisma.PaymentWhereUniqueInput; + Where: Prisma.PaymentWhereInput; + Create: {}; + Update: {}; + RelationName: "Order"; + ListRelations: never; + Relations: { + Order: { + Shape: Order | null; + Name: "Order"; + Nullable: true; + }; + }; + }; + Workshop: { + Name: "Workshop"; + Shape: Workshop; + Include: Prisma.WorkshopInclude; + Select: Prisma.WorkshopSelect; + OrderBy: Prisma.WorkshopOrderByWithRelationInput; + WhereUnique: Prisma.WorkshopWhereUniqueInput; + Where: Prisma.WorkshopWhereInput; + Create: {}; + Update: {}; + RelationName: "service" | "workshopOrganization" | "workshopSubscription" | "staff"; + ListRelations: "workshopOrganization" | "workshopSubscription"; + Relations: { + service: { + Shape: Service; + Name: "Service"; + Nullable: false; + }; + workshopOrganization: { + Shape: WorkshopOrganization[]; + Name: "WorkshopOrganization"; + Nullable: false; + }; + workshopSubscription: { + Shape: WorkshopSubscription[]; + Name: "WorkshopSubscription"; + Nullable: false; + }; + staff: { + Shape: CenterStaff; + Name: "CenterStaff"; + Nullable: false; + }; + }; + }; + WorkshopSubscription: { + Name: "WorkshopSubscription"; + Shape: WorkshopSubscription; + Include: Prisma.WorkshopSubscriptionInclude; + Select: Prisma.WorkshopSubscriptionSelect; + OrderBy: Prisma.WorkshopSubscriptionOrderByWithRelationInput; + WhereUnique: Prisma.WorkshopSubscriptionWhereUniqueInput; + Where: Prisma.WorkshopSubscriptionWhereInput; + Create: {}; + Update: {}; + RelationName: "user" | "workshop"; + ListRelations: never; + Relations: { + user: { + Shape: User; + Name: "User"; + Nullable: false; + }; + workshop: { + Shape: Workshop; + Name: "Workshop"; + Nullable: false; + }; + }; + }; + WorkshopOrganization: { + Name: "WorkshopOrganization"; + Shape: WorkshopOrganization; + Include: Prisma.WorkshopOrganizationInclude; + Select: Prisma.WorkshopOrganizationSelect; + OrderBy: Prisma.WorkshopOrganizationOrderByWithRelationInput; + WhereUnique: Prisma.WorkshopOrganizationWhereUniqueInput; + Where: Prisma.WorkshopOrganizationWhereInput; + Create: {}; + Update: {}; + RelationName: "workshop" | "service"; + ListRelations: never; + Relations: { + workshop: { + Shape: Workshop; + Name: "Workshop"; + Nullable: false; + }; + service: { + Shape: Service; + Name: "Service"; + Nullable: false; + }; + }; + }; + UploadedDocument: { + Name: "UploadedDocument"; + Shape: UploadedDocument; + Include: Prisma.UploadedDocumentInclude; + Select: Prisma.UploadedDocumentSelect; + OrderBy: Prisma.UploadedDocumentOrderByWithRelationInput; + WhereUnique: Prisma.UploadedDocumentWhereUniqueInput; + Where: Prisma.UploadedDocumentWhereInput; + Create: {}; + Update: {}; + RelationName: "user"; + ListRelations: never; + Relations: { + user: { + Shape: User; + Name: "User"; + Nullable: false; + }; + }; + }; + ServiceMeetingRoom: { + Name: "ServiceMeetingRoom"; + Shape: ServiceMeetingRoom; + Include: Prisma.ServiceMeetingRoomInclude; + Select: Prisma.ServiceMeetingRoomSelect; + OrderBy: Prisma.ServiceMeetingRoomOrderByWithRelationInput; + WhereUnique: Prisma.ServiceMeetingRoomWhereUniqueInput; + Where: Prisma.ServiceMeetingRoomWhereInput; + Create: {}; + Update: {}; + RelationName: "chattingRoom"; + ListRelations: never; + Relations: { + chattingRoom: { + Shape: ChatRoom; + Name: "ChatRoom"; + Nullable: false; + }; + }; + }; + WorkshopMeetingRoom: { + Name: "WorkshopMeetingRoom"; + Shape: WorkshopMeetingRoom; + Include: never; + Select: Prisma.WorkshopMeetingRoomSelect; + OrderBy: Prisma.WorkshopMeetingRoomOrderByWithRelationInput; + WhereUnique: Prisma.WorkshopMeetingRoomWhereUniqueInput; + Where: Prisma.WorkshopMeetingRoomWhereInput; + Create: {}; + Update: {}; + RelationName: never; + ListRelations: never; + Relations: {}; + }; +} \ No newline at end of file diff --git a/src/types/user.type.ts b/src/types/user.type.ts index 4d5caa5..e69de29 100644 --- a/src/types/user.type.ts +++ b/src/types/user.type.ts @@ -1,30 +0,0 @@ -import { builder } from '../types/pothos.type'; -import { PrismaService } from '../prisma/prisma.service'; -import { Module } from '@nestjs/common'; -import { PrismaModule } from '../prisma/prisma.module'; - -@Module({ - imports: [PrismaModule], -}) -export class UserSchema { - constructor(private prisma: PrismaService) { - // Define the User GraphQL object type based on Prisma schema - builder.prismaObject('User' as never, { - fields: (t) => ({ - id: t.exposeInt('id' as never), - name: t.exposeString('name' as never), - email: t.exposeString('email' as never), - }), - }); - - // Define the "users" query that resolves using Prisma - builder.queryField('users', (t) => - t.prismaField({ - type: ['User' as never], - resolve: async () => { - return this.prisma.user.findMany() as any; - }, - }), - ); - } -}