import { Global, type MiddlewareConsumer, Module, type NestModule, RequestMethod } from '@nestjs/common'; import { APP_FILTER } from '@nestjs/core'; import { EventEmitterModule } from '@nestjs/event-emitter'; import { makeCounterProvider } from '@willsoto/nestjs-prometheus'; import { EventBusService } from './infrastructure/event-bus.service'; import { GlobalExceptionFilter } from './infrastructure/filters/global-exception.filter'; import { LoggerService } from './infrastructure/logger.service'; import { CorrelationIdMiddleware } from './infrastructure/middleware/correlation-id.middleware'; import { CsrfMiddleware } from './infrastructure/middleware/csrf.middleware'; import { RequestLoggingMiddleware } from './infrastructure/middleware/request-logging.middleware'; import { SanitizeInputMiddleware } from './infrastructure/middleware/sanitize-input.middleware'; import { PrismaService } from './infrastructure/prisma.service'; import { RedisService } from './infrastructure/redis.service'; import { CacheService, CACHE_HIT_TOTAL, CACHE_MISS_TOTAL } from './infrastructure/cache.service'; @Global() @Module({ imports: [EventEmitterModule.forRoot()], providers: [ PrismaService, RedisService, CacheService, LoggerService, EventBusService, makeCounterProvider({ name: CACHE_HIT_TOTAL, help: 'Total number of cache hits', labelNames: ['resource'], }), makeCounterProvider({ name: CACHE_MISS_TOTAL, help: 'Total number of cache misses', labelNames: ['resource'], }), { provide: APP_FILTER, useClass: GlobalExceptionFilter, }, ], exports: [PrismaService, RedisService, CacheService, LoggerService, EventBusService], }) export class SharedModule implements NestModule { configure(consumer: MiddlewareConsumer): void { consumer .apply(CorrelationIdMiddleware, SanitizeInputMiddleware, RequestLoggingMiddleware) .forRoutes('*'); if (process.env['NODE_ENV'] !== 'test') { consumer .apply(CsrfMiddleware) .exclude( { path: 'payments/callback/(.*)', method: RequestMethod.POST }, { path: 'auth/login', method: RequestMethod.POST }, { path: 'auth/register', method: RequestMethod.POST }, { path: 'auth/refresh', method: RequestMethod.POST }, { path: 'auth/exchange-token', method: RequestMethod.POST }, { path: 'auth/logout', method: RequestMethod.POST }, ) .forRoutes('*'); } } }