Files
genome2025/backend/src/main.ts

65 lines
2.4 KiB
TypeScript

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();