import { NestFactory, Reflector } from '@nestjs/core'; import { AppModule } from './app.module'; import { ValidationPipe } from '@nestjs/common'; import { JwtAuthGuard } from './common/guards/jwt-auth.guard'; import { AllExceptionsFilter } from './common/filters/all-exceptions.filter'; import { LoggingInterceptor } from './common/interceptors/logging.interceptor'; import { TransformInterceptor } from './common/interceptors/transform.interceptor'; import { types } from 'pg'; // PostgreSQL numeric/decimal 타입을 JavaScript number로 자동 변환 // 1700 = numeric type OID types.setTypeParser(1700, parseFloat); async function bootstrap() { const app = await NestFactory.create(AppModule); // CORS 추가 app.enableCors({ origin: (origin, callback) => { // origin이 없는 경우 (서버 간 요청, Postman 등) 허용 if (!origin) return callback(null, true); const allowedPatterns = [ /^http:\/\/localhost:\d+$/, // localhost 모든 포트 /^http:\/\/127\.0\.0\.1:\d+$/, // 127.0.0.1 모든 포트 /^http:\/\/192\.168\.11\.\d+:\d+$/, // 192.168.11.* 대역 /^https?:\/\/.*\.turbosoft\.kr$/, // *.turbosoft.kr ]; const isAllowed = allowedPatterns.some(pattern => pattern.test(origin)); callback(null, isAllowed); }, credentials: true, }); // ValidationPipe 추가 (Body 파싱과 Dto 유효성 global 설정) app.useGlobalPipes( new ValidationPipe({ transform: true, whitelist: false, // nested object를 위해 whitelist 비활성화 transformOptions: { enableImplicitConversion: true, }, }), ); // 전역 필터 적용 - 모든 예외를 잡아서 일관된 형식으로 응답 app.useGlobalFilters(new AllExceptionsFilter()); // 전역 인터셉터 적용 app.useGlobalInterceptors( new LoggingInterceptor(), // 요청/응답 로깅 new TransformInterceptor(), // 일관된 응답 변환 (success, data, timestamp) //backend\src\common\interceptors\transform.interceptor.ts 구현체 ); // 전역 JWT 인증 가드 적용 (@Public 데코레이터가 있는 엔드포인트는 제외) const reflector = app.get(Reflector); app.useGlobalGuards(new JwtAuthGuard(reflector)); await app.listen(process.env.PORT ?? 4000); // 로컬 개발환경 //await app.listen(process.env.PORT ?? 4000, '0.0.0.0'); // 모든 네트워크 외부 바인딩 } bootstrap();