Refactor code structure and dependencies

- Remove unused files and modules
- Update submodule URL for epess-database
- Update DATABASE_URL in compose.yaml
- Update CI workflow to fetch submodules during checkout and fix GITHUB_TOKEN issue
- Enable strict mode in tsconfig.json
- Add UsersService and UsersResolver in users module
- Remove AppService and AppController
- Update main.ts to remove unused imports and log statement
- Add PrismaModule and PrismaService
- Add PrismaContextMiddleware
- Update GraphQL module to use schema and PrismaService
- Update package.json dependencies and devDependencies
This commit is contained in:
2024-09-27 06:21:04 +07:00
parent 8fe5e62870
commit 258a35d364
23 changed files with 4751 additions and 894 deletions

View File

@@ -0,0 +1,28 @@
import SchemaBuilder from '@pothos/core';
import PrismaPlugin from '@pothos/plugin-prisma';
import PrismaUtils from '@pothos/plugin-prisma-utils';
import { DateTimeResolver } from 'graphql-scalars';
import { PrismaService } from '../prisma/prisma.service';
import type PrismaTypes from '@pothos/plugin-prisma/generated';
import { getDatamodel } from '@pothos/plugin-prisma/generated';
export const prisma = new PrismaService();
export const builder = new SchemaBuilder<{
Scalars: {
DateTime: {
Input: Date;
Output: Date;
};
};
PrismaTypes: PrismaTypes;
}>({
plugins: [PrismaPlugin, PrismaUtils],
prisma: {
client: prisma,
exposeDescriptions: true,
filterConnectionTotalCount: true,
onUnusedQuery: process.env.NODE_ENV === 'production' ? null : 'warn',
dmmf: getDatamodel(),
},
});
builder.addScalarType('DateTime', DateTimeResolver, {});

View File

@@ -1,48 +1,18 @@
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';
const subOperationHandler = (message: any, params: any, webSocket: any) => {
console.log('onOperation');
return params;
};
import { PrismaService } from '../prisma/prisma.service';
import { schema } from './schema';
@Module({
imports: [
GraphQLModule.forRoot<ApolloDriverConfig>({
driver: ApolloDriver, // Specify the driver
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: [
{
endpoint: '/graphql',
query: `# Welcome to the EPESS GraphQL API
`,
},
],
},
introspection: true,
driver: ApolloDriver,
schema: schema,
debug: true,
allowBatchedHttpRequests: true,
introspection: true,
}),
],
providers: [PrismaService],
})
export class GraphqlModule {}

View File

@@ -1,28 +0,0 @@
import SchemaBuilder from '@pothos/core';
import { PrismaClient, Prisma } from '@prisma/client';
import PrismaPlugin from '@pothos/plugin-prisma';
import type PrismaTypes from '../types/pothos.type';
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;

View File

@@ -1,18 +0,0 @@
import { Test, TestingModule } from '@nestjs/testing';
import { GraphqlService } from './graphql.service';
describe('GraphqlService', () => {
let service: GraphqlService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [GraphqlService],
}).compile();
service = module.get<GraphqlService>(GraphqlService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
});

117
src/graphql/schema.ts Normal file
View File

@@ -0,0 +1,117 @@
import { builder, prisma } from './graphql.builder';
builder.prismaObject('User', {
fields: (t) => ({
id: t.exposeID('id'),
name: t.exposeString('name'),
email: t.exposeString('email'),
phoneNumber: t.exposeString('phoneNumber'),
role: t.exposeString('role'),
createdAt: t.expose('createdAt', {
type: 'DateTime',
}),
updatedAt: t.expose('updatedAt', {
type: 'DateTime',
}),
order: t.relation('orders'),
serviceFeedbacks: t.relation('serviceFeedbacks'),
documents: t.relation('documents'),
sendingMessage: t.relation('sendingMessage'),
Service: t.relation('Service'),
center: t.relation('center'),
customerChatRoom: t.relation('customerChatRoom'),
centerStaffChatRoom: t.relation('centerStaffChatRoom'),
CenterStaff: t.relation('CenterStaff'),
WorkshopSubscription: t.relation('WorkshopSubscription'),
}),
});
builder.prismaObject('Order', {
fields: (t) => ({
id: t.exposeID('id'),
userId: t.exposeID('userId'),
}),
});
builder.prismaObject('ServiceFeedback', {
fields: (t) => ({
id: t.exposeID('id'),
userId: t.exposeID('userId'),
}),
});
builder.prismaObject('UploadedDocument', {
name: 'documents',
fields: (t) => ({
id: t.exposeID('id'),
userId: t.exposeID('userId'),
}),
});
builder.prismaObject('Message', {
name: 'sendingMessage',
fields: (t) => ({
id: t.exposeID('id'),
userId: t.exposeID('senderId'),
}),
});
builder.prismaObject('Service', {
fields: (t) => ({
id: t.exposeID('id'),
userId: t.exposeID('userId'),
}),
});
builder.prismaObject('Center', {
fields: (t) => ({
id: t.exposeID('id'),
userId: t.exposeID('centerOwnerId'),
}),
});
builder.prismaObject('ChatRoom', {
fields: (t) => ({
id: t.exposeID('id'),
}),
});
builder.prismaObject('CenterStaff', {
fields: (t) => ({
staffId: t.exposeID('staffId'),
centerId: t.exposeID('centerId'),
serviceId: t.exposeID('serviceId'),
}),
});
builder.prismaObject('WorkshopSubscription', {
fields: (t) => ({
userId: t.exposeID('userId'),
workshopId: t.exposeID('workshopId'),
user: t.relation('user'),
workshop: t.relation('workshop'),
}),
});
builder.prismaObject('Workshop', {
fields: (t) => ({
id: t.exposeID('id'),
}),
});
// Query section
builder.queryType({
fields: (t) => ({
users: t.prismaField({
type: ['User'], // Return type is a list of 'User'
resolve: (query, root, args, ctx, info) => {
return prisma.user.findMany({
...query,
// Include related posts in the query
});
},
}),
}),
});
export const schema = builder.toSchema();