diff --git a/package-lock.json b/package-lock.json index 803bd1b..267a385 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,6 +23,7 @@ "@nestjs/core": "^11.1.14", "@nestjs/graphql": "^13.2.4", "@nestjs/platform-express": "^11.0.1", + "@nestjs/serve-static": "^5.0.4", "@prisma/adapter-pg": "^7.4.2", "@prisma/client": "^7.4.2", "axios": "^1.13.6", @@ -50,6 +51,7 @@ "@types/node": "^22.10.7", "@types/pg": "^8.18.0", "@types/supertest": "^6.0.2", + "dotenv": "^17.3.1", "eslint": "^9.18.0", "eslint-config-prettier": "^10.0.1", "eslint-plugin-prettier": "^5.2.2", @@ -4367,6 +4369,33 @@ "tslib": "^2.1.0" } }, + "node_modules/@nestjs/serve-static": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@nestjs/serve-static/-/serve-static-5.0.4.tgz", + "integrity": "sha512-3kO1M9D3vsPyWPFardxIjUYeuolS58PnhCoBTkS7t3BrdZFZCKHnBZ15js+UOzOR2Q6HmD7ssGjLd0DVYVdvOw==", + "license": "MIT", + "dependencies": { + "path-to-regexp": "8.3.0" + }, + "peerDependencies": { + "@fastify/static": "^8.0.4", + "@nestjs/common": "^11.0.2", + "@nestjs/core": "^11.0.2", + "express": "^5.0.1", + "fastify": "^5.2.1" + }, + "peerDependenciesMeta": { + "@fastify/static": { + "optional": true + }, + "express": { + "optional": true + }, + "fastify": { + "optional": true + } + } + }, "node_modules/@nestjs/testing": { "version": "11.1.14", "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-11.1.14.tgz", @@ -7292,6 +7321,19 @@ } } }, + "node_modules/c12/node_modules/dotenv": { + "version": "16.6.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", + "devOptional": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, "node_modules/call-bind": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", @@ -8195,9 +8237,10 @@ } }, "node_modules/dotenv": { - "version": "16.6.1", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", - "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", + "version": "17.3.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.3.1.tgz", + "integrity": "sha512-IO8C/dzEb6O3F9/twg6ZLXz164a2fhTnEWb95H23Dm4OuN+92NmEAlTrupP9VW6Jm3sO26tQlqyvyi4CsnY9GA==", + "dev": true, "license": "BSD-2-Clause", "engines": { "node": ">=12" @@ -8221,6 +8264,18 @@ "url": "https://dotenvx.com" } }, + "node_modules/dotenv-expand/node_modules/dotenv": { + "version": "16.6.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", diff --git a/package.json b/package.json index bfbde88..7b82cf2 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ "@nestjs/core": "^11.1.14", "@nestjs/graphql": "^13.2.4", "@nestjs/platform-express": "^11.0.1", + "@nestjs/serve-static": "^5.0.4", "@prisma/adapter-pg": "^7.4.2", "@prisma/client": "^7.4.2", "axios": "^1.13.6", @@ -61,6 +62,7 @@ "@types/node": "^22.10.7", "@types/pg": "^8.18.0", "@types/supertest": "^6.0.2", + "dotenv": "^17.3.1", "eslint": "^9.18.0", "eslint-config-prettier": "^10.0.1", "eslint-plugin-prettier": "^5.2.2", diff --git a/src/app.module.ts b/src/app.module.ts index af881b9..d419fcb 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -7,13 +7,28 @@ import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo'; import { join } from 'path'; import { StorageModule } from './common/storage/storage.module'; import { graphqlUploadExpress } from 'graphql-upload-ts'; - +import { ServeStaticModule } from '@nestjs/serve-static'; +import { BullModule } from '@nestjs/bullmq'; +import { ConfigService } from '@nestjs/config'; @Module({ imports: [ ConfigModule.forRoot({ isGlobal: true, }), + ServeStaticModule.forRoot({ + rootPath: join(process.cwd(), 'public'), + exclude: ['/graphql'], + }), + BullModule.forRootAsync({ + inject: [ConfigService], + useFactory: (configService: ConfigService) => ({ + connection: { + host: configService.get('REDIS_HOST'), + port: configService.get('REDIS_PORT'), + }, + }), + }), GraphQLModule.forRoot({ driver: ApolloDriver, autoSchemaFile: join(process.cwd(), 'src/schema.gql'), @@ -22,9 +37,11 @@ import { graphqlUploadExpress } from 'graphql-upload-ts'; // Needed for uploads in Apollo v4 csrfPrevention: false, }), - - - PrismaModule, CasesModule, StorageModule,], + + PrismaModule, + CasesModule, + StorageModule, + ], controllers: [], providers: [], }) diff --git a/src/main.ts b/src/main.ts index f76bc8d..5e39f28 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,8 +1,26 @@ +import 'reflect-metadata'; import { NestFactory } from '@nestjs/core'; +import { ValidationPipe, Logger } from '@nestjs/common'; +import { ConfigService } from '@nestjs/config'; import { AppModule } from './app.module'; async function bootstrap() { const app = await NestFactory.create(AppModule); - await app.listen(process.env.PORT ?? 3000); + const logger = new Logger('Bootstrap'); + + const configService = app.get(ConfigService); + + app.enableCors(); + + app.useGlobalPipes(new ValidationPipe({ + whitelist: true, + transform: true, + forbidNonWhitelisted: true, + })); + + const port = configService.get('PORT') || 3000; + await app.listen(port); + logger.log(`🚀 Application running on http://localhost:${port}`); + logger.log(`📊 GraphQL Playground: http://localhost:${port}/graphql`); } bootstrap();