fix(backend): 운영 점검 반영 — CORS 콤마 목록·운영 Swagger 닫기·마이그레이션 로그·업로드 디렉터리 확인

- CORS_ORIGIN 을 문자열 통째로 비교해 예시 파일 안내대로 콤마로 여러 개를 주면 어느 것도 맞지 않았고,
  운영에서도 localhost 두 곳이 늘 허용됐다 → 콤마 목록으로 읽고 localhost 는 개발·테스트에서만 더한다
- Swagger 가 운영에서도 공개돼 API 전체 구조가 드러났다 → 개발·테스트에서만 연다
- 운영은 DB 로그를 끄면서 기동 때 적용한 마이그레이션 기록도 남지 않았다 → migration 로그만 남긴다
- 업로드 디렉터리에 쓸 수 없어도 기동돼 첫 업로드에서야 500 이 났다 → 기동할 때 확인해 멈춘다

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-12 00:04:05 +09:00
parent f60654bed6
commit cffc5a5d06
7 changed files with 71 additions and 31 deletions
+2 -1
View File
@@ -80,7 +80,8 @@ export function buildDatabaseOptions(): DataSourceOptions {
database: process.env.DB_NAME ?? DEV_DB_DEFAULTS.database,
synchronize: shouldSynchronize(),
migrationsRun: shouldRunMigrations(),
logging: !isProduction,
// 운영은 쿼리를 남기지 않는다(양·민감정보). 기동 때 적용한 마이그레이션만 남겨 배포 기록으로 쓴다
logging: isProduction ? ['migration'] : true,
// 컬럼은 snake_case, 엔티티 속성은 camelCase
namingStrategy: new SnakeNamingStrategy(),
extra: { ...POOL_OPTIONS },
+15 -1
View File
@@ -1,4 +1,18 @@
import { parsePositiveInt } from './env';
import { parseCommaList, parsePositiveInt } from './env';
describe('parseCommaList', () => {
it('콤마로 나누고 앞뒤 공백을 지운다', () => {
expect(
parseCommaList('https://a.com, https://b.com ,https://c.com'),
).toEqual(['https://a.com', 'https://b.com', 'https://c.com']);
});
it('값이 없거나 빈 칸뿐이면 빈 목록이다 (compose 미정의 변수 대응)', () => {
expect(parseCommaList(undefined)).toEqual([]);
expect(parseCommaList('')).toEqual([]);
expect(parseCommaList(' , ,')).toEqual([]);
});
});
describe('parsePositiveInt', () => {
it('정상적인 양의 정수 문자열을 숫자로 변환한다', () => {
+8
View File
@@ -5,6 +5,14 @@
* `Number('')` 는 0 이므로 `??` 만으로는 기본값이 적용되지 않는다 — 이 함수로 방어한다.
*/
/** 콤마로 나눈 목록 — 앞뒤 공백과 빈 칸은 버린다 (값이 없으면 빈 목록) */
export function parseCommaList(value: string | undefined): string[] {
return (value ?? '')
.split(',')
.map((v) => v.trim())
.filter((v) => v !== '');
}
/**
* 환경변수를 양의 정수로 파싱한다.
* 값이 없거나(undefined·빈 문자열) 숫자가 아니거나 0 이하면 기본값을 반환한다.