# WACE ERP 백엔드 아키텍처 상세 분석 > **작성일**: 2026-02-06 > **분석 대상**: ERP-node/backend-node > **Stack**: Node.js + Express + TypeScript + PostgreSQL Raw Query --- ## 📋 목차 1. [전체 디렉토리 구조](#1-전체-디렉토리-구조) 2. [API 라우트 목록 및 역할](#2-api-라우트-목록-및-역할) 3. [인증/인가 워크플로우](#3-인증인가-워크플로우) 4. [비즈니스 도메인별 모듈 분류](#4-비즈니스-도메인별-모듈-분류) 5. [미들웨어 스택 구성](#5-미들웨어-스택-구성) 6. [서비스 레이어 패턴](#6-서비스-레이어-패턴) 7. [멀티테넌시 구현 방식](#7-멀티테넌시-구현-방식) 8. [에러 핸들링 전략](#8-에러-핸들링-전략) 9. [파일 업로드/다운로드 처리](#9-파일-업로드다운로드-처리) 10. [외부 연동](#10-외부-연동) 11. [배치/스케줄 처리](#11-배치스케줄-처리) 12. [컨트롤러/서비스 상세 역할](#12-컨트롤러서비스-상세-역할) --- ## 1. 전체 디렉토리 구조 ``` backend-node/ ├── src/ │ ├── app.ts # Express 앱 진입점, 라우트 등록, 미들웨어 설정 │ ├── config/ │ │ └── environment.ts # 환경변수 관리 (PORT, DB, JWT, CORS 등) │ ├── controllers/ # 69개 컨트롤러 (요청 처리 및 응답) │ ├── services/ # 87개 서비스 (비즈니스 로직) │ ├── routes/ # 77개 라우터 (엔드포인트 정의) │ ├── middleware/ # 4개 미들웨어 (인증, 권한, 에러 핸들링) │ ├── database/ # DB 연결 풀, 커넥터, 마이그레이션 │ ├── utils/ # 16개 유틸리티 (JWT, 암호화, 로거 등) │ ├── types/ # 26개 TypeScript 타입 정의 │ ├── interfaces/ # 인터페이스 정의 │ └── tests/ # 테스트 파일 ├── scripts/ # 배치 및 유틸리티 스크립트 ├── data/ # JSON 기반 설정 데이터 ├── uploads/ # 파일 업로드 디렉토리 └── package.json # 의존성 관리 ``` ### 주요 특징 - **Layered Architecture**: Controller → Service → Database 3계층 구조 - **TypeScript Strict Mode**: 타입 안전성 보장 - **Raw Query 기반**: Prisma → PostgreSQL Raw Query 전환 완료 - **Connection Pool**: pg 라이브러리 기반 연결 풀 관리 - **마이크로서비스 지향**: 도메인별 명확한 분리 --- ## 2. API 라우트 목록 및 역할 ### 2.1 인증 및 관리자 (Auth & Admin) | 엔드포인트 | 메서드 | 역할 | 인증 | |-----------|--------|------|------| | `/api/auth/login` | POST | 로그인 (JWT 토큰 발급) | ❌ | | `/api/auth/signup` | POST | 회원가입 (공차중계) | ❌ | | `/api/auth/me` | GET | 현재 사용자 정보 조회 | ✅ | | `/api/auth/logout` | POST | 로그아웃 | ✅ | | `/api/auth/refresh` | POST | JWT 토큰 갱신 | ✅ | | `/api/auth/switch-company` | POST | 관리자 전용: 회사 전환 | ✅ | | `/api/admin/menus` | GET | 메뉴 목록 조회 | ✅ | | `/api/admin/users` | GET/POST/PUT | 사용자 관리 (CRUD) | ✅ | | `/api/admin/companies` | GET/POST/PUT/DELETE | 회사 관리 (CRUD) | ✅ | | `/api/admin/departments` | GET | 부서 목록 조회 | ✅ | ### 2.2 테이블 및 데이터 관리 | 엔드포인트 | 메서드 | 역할 | 인증 | |-----------|--------|------|------| | `/api/table-management/tables` | GET | 테이블 목록 조회 | ✅ | | `/api/table-management/columns` | GET | 컬럼 정보 조회 | ✅ | | `/api/table-management/entity-joins` | GET/POST | 테이블 조인 설정 | ✅ | | `/api/data/*` | GET/POST/PUT/DELETE | 동적 테이블 데이터 CRUD | ✅ | | `/api/ddl/*` | POST | DDL 실행 (테이블 생성/수정/삭제) | ✅ (Super Admin) | ### 2.3 화면 및 폼 관리 | 엔드포인트 | 메서드 | 역할 | 인증 | |-----------|--------|------|------| | `/api/screen-management/*` | GET/POST/PUT/DELETE | 화면 메타데이터 관리 | ✅ | | `/api/screen-groups/*` | GET/POST/PUT/DELETE | 화면 그룹 관리 | ✅ | | `/api/dynamic-form/*` | GET/POST | 동적 폼 생성 및 렌더링 | ✅ | | `/api/admin/web-types` | GET/POST | 웹 컴포넌트 타입 표준 관리 | ✅ | | `/api/admin/button-actions` | GET/POST | 버튼 액션 표준 관리 | ✅ | | `/api/admin/template-standards` | GET/POST | 템플릿 표준 관리 | ✅ | | `/api/admin/component-standards` | GET/POST | 컴포넌트 표준 관리 | ✅ | ### 2.4 플로우 및 데이터플로우 | 엔드포인트 | 메서드 | 역할 | 인증 | |-----------|--------|------|------| | `/api/flow/definitions` | GET/POST/PUT/DELETE | 플로우 정의 관리 | ✅ | | `/api/flow/definitions/:id/steps` | GET/POST | 플로우 단계 관리 | ✅ | | `/api/flow/connections` | GET/POST/DELETE | 플로우 연결 관리 | ✅ | | `/api/flow/move` | POST | 데이터 이동 실행 | ✅ | | `/api/flow/audit/:flowId` | GET | 플로우 오딧 로그 조회 | ✅ | | `/api/dataflow/*` | GET/POST/PUT/DELETE | 데이터플로우 관계 관리 | ✅ | | `/api/dataflow-diagrams/*` | GET/POST/PUT/DELETE | 데이터플로우 다이어그램 | ✅ | | `/api/dataflow/execute` | POST | 데이터플로우 실행 | ✅ | ### 2.5 배치 관리 | 엔드포인트 | 메서드 | 역할 | 인증 | |-----------|--------|------|------| | `/api/batch-configs` | GET/POST/PUT/DELETE | 배치 설정 관리 | ✅ | | `/api/batch-configs/connections` | GET | 사용 가능한 커넥션 목록 | ✅ | | `/api/batch-configs/:id/execute` | POST | 배치 수동 실행 | ✅ | | `/api/batch-management/*` | GET/POST | 배치 실행 관리 | ✅ | | `/api/batch-execution-logs` | GET | 배치 실행 이력 조회 | ✅ | ### 2.6 외부 연동 | 엔드포인트 | 메서드 | 역할 | 인증 | |-----------|--------|------|------| | `/api/external-db-connections` | GET/POST/PUT/DELETE | 외부 DB 연결 관리 | ✅ | | `/api/external-db-connections/:id/test` | POST | 외부 DB 연결 테스트 | ✅ | | `/api/external-rest-api-connections` | GET/POST/PUT/DELETE | 외부 REST API 연결 | ✅ | | `/api/external-calls/*` | GET/POST | 외부 API 호출 설정 | ✅ | | `/api/multi-connection/query` | POST | 멀티 DB 통합 쿼리 | ✅ | ### 2.7 메일 관리 | 엔드포인트 | 메서드 | 역할 | 인증 | |-----------|--------|------|------| | `/api/mail/accounts` | GET/POST/PUT/DELETE | 메일 계정 관리 | ✅ | | `/api/mail/templates-file` | GET/POST/PUT/DELETE | 메일 템플릿 관리 | ✅ | | `/api/mail/send` | POST | 메일 발송 (단일/대량) | ✅ | | `/api/mail/sent` | GET | 발송 이력 조회 | ✅ | | `/api/mail/receive` | GET | 메일 수신함 조회 | ✅ | ### 2.8 기타 도메인 | 엔드포인트 | 메서드 | 역할 | 인증 | |-----------|--------|------|------| | `/api/dashboards/*` | GET/POST | 대시보드 관리 | ✅ | | `/api/admin/reports/*` | GET/POST | 리포트 생성 및 조회 | ✅ | | `/api/files/*` | POST | 파일 업로드/다운로드 | ✅ | | `/api/delivery/*` | GET/POST | 배송/화물 관리 | ✅ | | `/api/risk-alerts/*` | GET/POST | 리스크/알림 관리 | ✅ | | `/api/todos/*` | GET/POST/PUT/DELETE | To-Do 관리 | ✅ | | `/api/bookings/*` | GET/POST | 예약 관리 | ✅ | | `/api/digital-twin/*` | GET/POST | 디지털 트윈 (야드 관제) | ✅ | | `/api/schedule/*` | GET/POST | 스케줄 자동 생성 | ✅ | | `/api/work-history/*` | GET | 작업 이력 조회 | ✅ | | `/api/table-history/*` | GET | 테이블 변경 이력 조회 | ✅ | | `/api/roles/*` | GET/POST | 권한 그룹 관리 | ✅ | | `/api/numbering-rules/*` | GET/POST | 채번 규칙 관리 | ✅ | | `/api/entity-search/*` | GET | 엔티티 검색 | ✅ | | `/api/cascading-*` | GET/POST | 연쇄 드롭다운 관계 | ✅ | | `/api/category-tree/*` | GET/POST | 카테고리 트리 | ✅ | | `/api/vehicle/*` | GET/POST | 차량 운행 이력 | ✅ | | `/api/tax-invoice/*` | GET/POST | 세금계산서 관리 | ✅ | **총 77개 라우터 파일, 200개 이상의 엔드포인트 제공** --- ## 3. 인증/인가 워크플로우 ### 3.1 인증 메커니즘 ``` 로그인 요청 (userId, password) ↓ 1. AuthController.login() ↓ 2. AuthService.processLogin() ├─ 비밀번호 검증 (BCrypt + 마스터 패스워드) ├─ 사용자 정보 조회 (user_info 테이블) ├─ 로그인 로그 기록 (LOGIN_ACCESS_LOG) └─ JWT 토큰 생성 (JwtUtils.generateToken) ↓ 3. JWT 토큰 응답 ├─ accessToken (24시간 유효) ├─ refreshToken (7일 유효) └─ userInfo (userId, userName, companyCode, userType) ``` ### 3.2 JWT 토큰 구조 ```typescript // JWT Payload { userId: string; // 사용자 ID userName: string; // 사용자 이름 companyCode: string; // 회사 코드 (멀티테넌시 핵심) userType: string; // 사용자 유형 (SUPER_ADMIN, COMPANY_ADMIN, USER) userLang?: string; // 사용자 언어 iat: number; // 발급 시간 exp: number; // 만료 시간 } ``` ### 3.3 미들웨어 체인 ``` 1. refreshTokenIfNeeded (자동 토큰 갱신) ↓ 2. authenticateToken (JWT 검증 및 사용자 정보 설정) ↓ 3. 권한 미들웨어 (선택적) ├─ requireSuperAdmin (회사코드 '*' 필수) ├─ requireAdmin (회사관리자 이상) ├─ requireCompanyAccess (회사 데이터 접근 권한) ├─ requireDDLPermission (DDL 실행 권한) └─ requireUserManagement (사용자 관리 권한) ↓ 4. Controller 실행 ↓ 5. errorHandler (에러 발생 시) ``` ### 3.4 권한 레벨 (3단계) | 레벨 | companyCode | userType | 권한 범위 | |------|-------------|----------|----------| | **Super Admin** | `*` | `SUPER_ADMIN` | 전체 시스템 접근, DDL 실행, 회사 생성/삭제 | | **Company Admin** | 회사코드 | `COMPANY_ADMIN` | 자사 데이터 관리, 사용자 관리, 설정 변경 | | **일반 사용자** | 회사코드 | `USER` | 자사 데이터 조회/수정 (권한 범위 내) | ### 3.5 토큰 갱신 전략 - **자동 갱신**: 토큰이 1시간 이내 만료 시 응답 헤더(`X-New-Token`)에 새 토큰 포함 - **명시적 갱신**: `/api/auth/refresh` 엔드포인트 호출 - **만료 처리**: 만료된 토큰은 401 Unauthorized 응답 (`TOKEN_EXPIRED`) --- ## 4. 비즈니스 도메인별 모듈 분류 ### 4.1 관리자 영역 (Admin) **파일**: - `adminController.ts`, `adminService.ts`, `adminRoutes.ts` **주요 기능**: - 메뉴 관리 (CRUD, 복사, 상태 토글, 일괄 삭제) - 사용자 관리 (등록, 수정, 상태 변경, 비밀번호 초기화) - 회사 관리 (등록, 수정, 삭제, 조회) - 부서 관리 (조회, 사용자-부서 통합 저장) - 로케일 설정 (다국어 지원) - 테이블 스키마 조회 (엑셀 매핑용) **특징**: - 멀티테넌시 기반 회사별 데이터 격리 - Super Admin만 회사 생성/삭제 가능 - 사용자 변경 이력 추적 ### 4.2 테이블 및 데이터 관리 (Table Management & Data) **파일**: - `tableManagementController.ts`, `tableManagementService.ts` - `dataController.ts`, `dataService.ts` - `entityJoinController.ts`, `entityJoinService.ts` **주요 기능**: - 테이블 목록 조회 (PostgreSQL information_schema 활용) - 컬럼 정보 조회 (타입, 라벨, 제약조건, 참조 관계) - 동적 테이블 데이터 CRUD (Raw Query 기반) - 테이블 조인 설정 및 실행 (1:N, N:M 관계) - 컬럼 라벨 및 설정 관리 (table_type_columns) **특징**: - 캐시 기반 성능 최적화 (테이블/컬럼 정보) - 멀티테넌시 자동 필터링 (`company_code` 조건) - 코드 타입 컬럼 자동 처리 (공통 코드 연동) ### 4.3 화면 관리 (Screen Management) **파일**: - `screenManagementController.ts`, `screenManagementService.ts` - `screenGroupController.ts`, `screenEmbeddingController.ts` **주요 기능**: - 화면 메타데이터 관리 (테이블 연결, 컬럼 설정, 레이아웃) - 화면 그룹 관리 (폴더 구조) - 화면 임베딩 (부모-자식 화면 데이터 전달) - 동적 폼 생성 (JSON 기반 폼 설정 → React 컴포넌트) **특징**: - Low-Code 화면 구성 - 웹 컴포넌트 타입 표준 기반 렌더링 - 버튼 액션 표준 지원 (저장, 삭제, 조회, 커스텀) ### 4.4 플로우 관리 (Flow Management) **파일**: - `flowController.ts`, `flowService.ts` - `flowExecutionService.ts`, `flowStepService.ts` - `flowConnectionService.ts`, `flowDataMoveService.ts` **주요 기능**: - 플로우 정의 관리 (작업 흐름 설계) - 플로우 단계 관리 (스텝 생성, 수정, 삭제) - 플로우 연결 관리 (스텝 간 조건부 연결) - 데이터 이동 실행 (스텝 간 데이터 이동) - 오딧 로그 조회 (변경 이력 추적) **특징**: - 비주얼 워크플로우 엔진 - 조건부 분기 지원 - 배치 데이터 이동 지원 ### 4.5 데이터플로우 (Dataflow) **파일**: - `dataflowController.ts`, `dataflowService.ts` - `dataflowDiagramController.ts`, `dataflowDiagramService.ts` - `dataflowExecutionController.ts` **주요 기능**: - 테이블 관계 정의 (1:1, 1:N, N:M) - 데이터플로우 다이어그램 생성 (ERD 같은 시각화) - 데이터플로우 실행 (자동 데이터 동기화) - 관계 기반 데이터 조회 (조인 쿼리 자동 생성) **특징**: - 그래프 기반 데이터 관계 모델링 - 다이어그램별 관계 그룹화 ### 4.6 배치 관리 (Batch Management) **파일**: - `batchController.ts`, `batchService.ts` - `batchSchedulerService.ts`, `batchExecutionLogService.ts` - `batchExternalDbService.ts` **주요 기능**: - 배치 설정 관리 (CRUD) - Cron 기반 스케줄링 (node-cron) - 배치 수동/자동 실행 - 실행 이력 조회 (성공/실패 로그) - 외부 DB 연동 배치 지원 **특징**: - 실시간 스케줄러 업데이트 - 다중 DB 간 데이터 동기화 - 실행 시간 제한 및 오류 알림 ### 4.7 외부 연동 (External Integration) **파일**: - `externalDbConnectionController.ts`, `externalDbConnectionService.ts` - `externalRestApiConnectionController.ts`, `externalRestApiConnectionService.ts` - `externalCallController.ts`, `externalCallService.ts` - `multiConnectionQueryService.ts` **주요 기능**: - 외부 DB 연결 관리 (PostgreSQL, MySQL, MSSQL, Oracle, MariaDB) - 외부 REST API 연결 관리 - 멀티 DB 통합 쿼리 실행 - 연결 테스트 및 상태 확인 - 크레덴셜 암호화 저장 **특징**: - 5종 DB 지원 (PostgreSQL, MySQL, MSSQL, Oracle, MariaDB) - Connection Pool 기반 연결 관리 - 비밀번호 암호화 (AES-256-CBC) ### 4.8 메일 관리 (Mail Management) **파일**: - `mailAccountFileController.ts`, `mailAccountFileService.ts` - `mailTemplateFileController.ts`, `mailTemplateFileService.ts` - `mailSendSimpleController.ts`, `mailSendSimpleService.ts` - `mailSentHistoryController.ts`, `mailSentHistoryService.ts` - `mailReceiveBasicController.ts`, `mailReceiveBasicService.ts` **주요 기능**: - 메일 계정 관리 (SMTP/IMAP 설정) - 메일 템플릿 관리 (JSON 기반 컴포넌트 조합) - 메일 발송 (단일/대량, 첨부파일 지원) - 발송 이력 조회 (30일 자동 삭제) - 메일 수신함 조회 (IMAP) **특징**: - Nodemailer 기반 발송 - 템플릿 변수 치환 - 대량 발송 지원 (100건/배치) - 메일 예약 발송 ### 4.9 대시보드 (Dashboard) **파일**: - `DashboardController.ts`, `DashboardService.ts` **주요 기능**: - 대시보드 위젯 관리 (차트, 테이블, 카드) - 실시간 데이터 조회 (집계 쿼리) - 사용자별 대시보드 설정 **특징**: - JSON 기반 위젯 설정 - 캐시 기반 성능 최적화 ### 4.10 기타 도메인 **파일 및 주요 기능**: - **리포트**: 리포트 생성 및 조회 (`reportController.ts`, `reportService.ts`) - **파일**: 파일 업로드/다운로드 (`fileController.ts`, Multer) - **배송/화물**: 배송 관리, 화물 추적 (`deliveryController.ts`) - **리스크/알림**: 리스크 알림, 캐시 기반 자동 갱신 (`riskAlertController.ts`) - **To-Do**: 할 일 관리 (`todoController.ts`) - **예약**: 예약 요청 관리 (`bookingController.ts`) - **디지털 트윈**: 야드 관제, 3D 레이아웃 (`digitalTwinController.ts`) - **스케줄**: 스케줄 자동 생성 (`scheduleController.ts`) - **작업 이력**: 작업 로그 조회 (`workHistoryController.ts`) - **권한 그룹**: 권한 그룹 관리 (`roleController.ts`) - **채번 규칙**: 자동 채번 규칙 (`numberingRuleController.ts`) - **엔티티 검색**: 동적 엔티티 검색 (`entitySearchController.ts`) - **연쇄 드롭다운**: 조건부 드롭다운 (`cascadingController.ts` 시리즈) --- ## 5. 미들웨어 스택 구성 ### 5.1 미들웨어 실행 순서 (app.ts 기준) ``` 1. 프로세스 레벨 예외 처리 (unhandledRejection, uncaughtException) 2. 보안 헤더 (helmet) 3. 압축 (compression) 4. 바디 파싱 (express.json, express.urlencoded) 5. 정적 파일 서빙 (/uploads) 6. CORS (cors) 7. Rate Limiting (express-rate-limit) 8. 토큰 자동 갱신 (refreshTokenIfNeeded) 9. [라우트별 미들웨어] ├─ authenticateToken (모든 /api/* 라우트) ├─ 권한 미들웨어 (선택적) └─ 컨트롤러 실행 10. 404 핸들러 11. 에러 핸들러 (errorHandler) ``` ### 5.2 미들웨어 파일 #### `authMiddleware.ts` - **authenticateToken**: JWT 토큰 검증 및 사용자 정보 설정 - **optionalAuth**: 선택적 인증 (토큰 없어도 통과) - **requireAdmin**: 관리자 권한 필수 (userId === 'plm_admin') - **refreshTokenIfNeeded**: 토큰 자동 갱신 (1시간 이내 만료 시) - **checkAuthStatus**: 인증 상태 확인 (유효성 검사만) #### `permissionMiddleware.ts` - **requireSuperAdmin**: 슈퍼관리자 권한 필수 (companyCode === '*') - **requireAdmin**: 관리자 이상 권한 필수 (Super Admin + Company Admin) - **requireCompanyAccess**: 회사 데이터 접근 권한 체크 - **requireUserManagement**: 사용자 관리 권한 체크 - **requireCompanySettingsManagement**: 회사 설정 변경 권한 체크 - **requireCompanyManagement**: 회사 생성/삭제 권한 체크 - **requireDDLPermission**: DDL 실행 권한 체크 #### `superAdminMiddleware.ts` - **requireSuperAdmin**: 슈퍼관리자 권한 확인 (DDL 전용) - **validateDDLPermission**: DDL 실행 전 추가 보안 검증 (5초 간격 제한) - **isSuperAdmin**: 슈퍼관리자 여부 확인 유틸 함수 - **checkDDLPermission**: DDL 권한 체크 (미들웨어 없이 사용) #### `errorHandler.ts` - **AppError**: 커스텀 에러 클래스 (statusCode, isOperational) - **errorHandler**: 전역 에러 핸들러 (PostgreSQL, JWT 에러 처리) - **notFoundHandler**: 404 에러 핸들러 ### 5.3 보안 설정 ```typescript // helmet: 보안 헤더 설정 helmet({ contentSecurityPolicy: { directives: { 'frame-ancestors': ['self', 'http://localhost:9771', 'http://localhost:3000'] } } }) // Rate Limiting: 1분당 10,000 요청 (개발), 100 요청 (운영) rateLimit({ windowMs: 1 * 60 * 1000, max: process.env.NODE_ENV === 'development' ? 10000 : 100, skip: (req) => { // 헬스 체크, 자주 호출되는 API는 제외 return req.path === '/health' || req.path.includes('/table-management/') || req.path.includes('/external-db-connections/') } }) // CORS: 환경별 origin 설정 cors({ origin: process.env.NODE_ENV === 'development' ? true : ['http://localhost:9771', 'http://39.117.244.52:5555'], credentials: true }) ``` --- ## 6. 서비스 레이어 패턴 ### 6.1 서비스 레이어 구조 ``` Controller (요청 처리) ↓ Service (비즈니스 로직) ↓ Database (Raw Query 실행) ↓ PostgreSQL (데이터 저장소) ``` ### 6.2 데이터베이스 접근 방식 #### `db.ts` - Raw Query 매니저 ```typescript // 기본 쿼리 실행 async function query(text: string, params?: any[]): Promise // 단일 행 조회 async function queryOne(text: string, params?: any[]): Promise // 트랜잭션 async function transaction(callback: (client: PoolClient) => Promise): Promise // 연결 풀 상태 function getPoolStatus(): { totalCount, idleCount, waitingCount } ``` #### Connection Pool 설정 ```typescript new Pool({ host: dbConfig.host, port: dbConfig.port, database: dbConfig.database, user: dbConfig.user, password: dbConfig.password, // 연결 풀 설정 min: process.env.NODE_ENV === 'production' ? 5 : 2, max: process.env.NODE_ENV === 'production' ? 20 : 10, // 타임아웃 설정 connectionTimeoutMillis: 30000, // 30초 idleTimeoutMillis: 600000, // 10분 statement_timeout: 60000, // 60초 query_timeout: 60000, application_name: 'WACE-PLM-Backend' }) ``` ### 6.3 서비스 패턴 예시 #### 멀티테넌시 쿼리 패턴 ```typescript // Super Admin: 모든 데이터 조회 if (companyCode === '*') { query = 'SELECT * FROM table_name ORDER BY company_code'; params = []; } // 일반 사용자: 자사 데이터만 조회 (Super Admin 데이터 제외) else { query = ` SELECT * FROM table_name WHERE company_code = $1 AND company_code != '*' ORDER BY created_at DESC `; params = [companyCode]; } ``` #### 트랜잭션 패턴 ```typescript await transaction(async (client) => { // 1. 부모 레코드 삽입 const parent = await client.query( 'INSERT INTO parent_table (...) VALUES (...) RETURNING *', [...] ); // 2. 자식 레코드 삽입 await client.query( 'INSERT INTO child_table (parent_id, ...) VALUES ($1, ...) RETURNING *', [parent.rows[0].id, ...] ); return { success: true }; }); ``` #### 캐시 패턴 ```typescript // 캐시 조회 const cachedData = cache.get(CacheKeys.TABLE_LIST); if (cachedData) { return cachedData; } // DB 조회 const data = await query('SELECT ...'); // 캐시 저장 (10분 TTL) cache.set(CacheKeys.TABLE_LIST, data, 10 * 60 * 1000); return data; ``` ### 6.4 외부 DB 커넥터 패턴 ```typescript // DatabaseConnectorFactory.ts export class DatabaseConnectorFactory { static createConnector(dbType: string, config: ConnectionConfig): DatabaseConnector { switch (dbType) { case 'postgresql': return new PostgreSQLConnector(config); case 'mysql': return new MySQLConnector(config); case 'mssql': return new MSSQLConnector(config); case 'oracle': return new OracleConnector(config); case 'mariadb': return new MariaDBConnector(config); default: throw new Error(`Unsupported DB type: ${dbType}`); } } } // 사용 예시 const connector = DatabaseConnectorFactory.createConnector('mysql', config); await connector.connect(); const result = await connector.executeQuery('SELECT * FROM users'); await connector.disconnect(); ``` --- ## 7. 멀티테넌시 구현 방식 ### 7.1 핵심 원칙 **CRITICAL PROJECT RULES**: 1. **모든 쿼리는 company_code 필터 필수** 2. **req.user!.companyCode 사용 (클라이언트 전송 값 신뢰 금지)** 3. **Super Admin (company_code = '*')만 전체 데이터 조회** 4. **일반 사용자는 company_code = '*' 데이터 조회 불가** ### 7.2 쿼리 패턴 ```typescript const companyCode = req.user!.companyCode; // Super Admin: 모든 회사 데이터 조회 if (companyCode === '*') { query = 'SELECT * FROM users ORDER BY company_code'; params = []; } // 일반 사용자: 자사 데이터만 조회 (Super Admin 제외) else { query = ` SELECT * FROM users WHERE company_code = $1 AND company_code != '*' `; params = [companyCode]; } ``` ### 7.3 테이블 설계 ```sql -- 모든 비즈니스 테이블에 company_code 컬럼 필수 CREATE TABLE table_name ( id SERIAL PRIMARY KEY, company_code VARCHAR(50) NOT NULL, -- 회사 코드 ... INDEX idx_company_code (company_code) ); -- Super Admin 데이터: company_code = '*' -- 회사별 데이터: company_code = '회사코드' ``` ### 7.4 회사 전환 (Super Admin 전용) ```typescript // POST /api/auth/switch-company { targetCompanyCode: "ILSHIN" // 전환할 회사 코드 } // 응답 { success: true, token: "새로운 JWT 토큰", // companyCode가 변경된 토큰 userInfo: { companyCode: "ILSHIN", ... } } ``` ### 7.5 권한 체크 ```typescript // 회사 데이터 접근 권한 확인 export function canAccessCompanyData(user: PersonBean, targetCompanyCode: string): boolean { // Super Admin: 모든 회사 접근 가능 if (user.companyCode === '*') { return true; } // 일반 사용자: 자사만 접근 가능 return user.companyCode === targetCompanyCode; } ``` --- ## 8. 에러 핸들링 전략 ### 8.1 에러 핸들링 구조 ``` Controller (try-catch) ↓ 에러 발생 Service (throw error) ↓ errorHandler (미들웨어) ├─ PostgreSQL 에러 처리 ├─ JWT 에러 처리 ├─ 커스텀 에러 처리 (AppError) └─ 응답 전송 (JSON) ``` ### 8.2 커스텀 에러 클래스 ```typescript export class AppError extends Error { public statusCode: number; public isOperational: boolean; constructor(message: string, statusCode: number = 500) { super(message); this.statusCode = statusCode; this.isOperational = true; } } // 사용 예시 throw new AppError('중복된 데이터가 존재합니다.', 400); ``` ### 8.3 PostgreSQL 에러 처리 ```typescript // errorHandler.ts if (pgError.code === '23505') { // unique_violation error = new AppError('중복된 데이터가 존재합니다.', 400); } else if (pgError.code === '23503') { // foreign_key_violation error = new AppError('참조 무결성 제약 조건 위반입니다.', 400); } else if (pgError.code === '23502') { // not_null_violation error = new AppError('필수 입력값이 누락되었습니다.', 400); } ``` ### 8.4 에러 응답 형식 ```json { "success": false, "error": { "code": "UNIQUE_VIOLATION", "message": "중복된 데이터가 존재합니다.", "details": "사용자 ID가 이미 존재합니다.", "stack": "..." // 개발 환경에서만 포함 } } ``` ### 8.5 에러 로깅 ```typescript // logger.ts (Winston 기반) logger.error({ message: error.message, stack: error.stack, url: req.url, method: req.method, ip: req.ip, userAgent: req.get('User-Agent') }); ``` ### 8.6 프로세스 레벨 예외 처리 ```typescript // app.ts process.on('unhandledRejection', (reason, promise) => { logger.error('⚠️ Unhandled Promise Rejection:', reason); // 프로세스 종료하지 않고 로깅만 수행 }); process.on('uncaughtException', (error) => { logger.error('🔥 Uncaught Exception:', error); // 심각한 에러 시 graceful shutdown 고려 }); ``` --- ## 9. 파일 업로드/다운로드 처리 ### 9.1 파일 업로드 **파일**: `fileController.ts`, `fileRoutes.ts` ```typescript // Multer 설정 const storage = multer.diskStorage({ destination: (req, file, cb) => { cb(null, 'uploads/'); }, filename: (req, file, cb) => { const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9); cb(null, file.fieldname + '-' + uniqueSuffix + path.extname(file.originalname)); } }); const upload = multer({ storage, limits: { fileSize: 10 * 1024 * 1024 }, // 10MB fileFilter: (req, file, cb) => { // 허용된 확장자 체크 const allowedTypes = /jpeg|jpg|png|gif|pdf|doc|docx|xls|xlsx/; const extname = allowedTypes.test(path.extname(file.originalname).toLowerCase()); const mimetype = allowedTypes.test(file.mimetype); if (mimetype && extname) { return cb(null, true); } else { cb(new Error('허용되지 않는 파일 형식입니다.')); } } }); // 라우트 router.post('/upload', authenticateToken, upload.single('file'), uploadFile); router.post('/upload-multiple', authenticateToken, upload.array('files', 10), uploadMultipleFiles); ``` ### 9.2 파일 다운로드 ```typescript // 정적 파일 서빙 (app.ts) app.use('/uploads', (req, res, next) => { res.setHeader('Access-Control-Allow-Origin', '*'); res.setHeader('Cross-Origin-Resource-Policy', 'cross-origin'); res.setHeader('Cache-Control', 'public, max-age=3600'); next(); }, express.static(path.join(process.cwd(), 'uploads')) ); // 다운로드 엔드포인트 router.get('/download/:filename', authenticateToken, async (req, res) => { const filename = req.params.filename; const filePath = path.join(process.cwd(), 'uploads', filename); if (!fs.existsSync(filePath)) { return res.status(404).json({ error: '파일을 찾을 수 없습니다.' }); } res.download(filePath); }); ``` ### 9.3 화면별 파일 관리 **파일**: `screenFileController.ts`, `screenFileService.ts` ```typescript // 화면별 파일 업로드 router.post('/screens/:screenId/files', authenticateToken, upload.single('file'), uploadScreenFile); // 화면별 파일 목록 조회 router.get('/screens/:screenId/files', authenticateToken, getScreenFiles); // 파일 삭제 router.delete('/screens/:screenId/files/:fileId', authenticateToken, deleteScreenFile); ``` --- ## 10. 외부 연동 ### 10.1 외부 DB 연결 **지원 DB**: PostgreSQL, MySQL, MSSQL, Oracle, MariaDB **파일**: - `externalDbConnectionService.ts` - `PostgreSQLConnector.ts`, `MySQLConnector.ts`, `MSSQLConnector.ts`, `OracleConnector.ts`, `MariaDBConnector.ts` ```typescript // 외부 DB 연결 설정 { connection_name: "외부 ERP DB", db_type: "mysql", host: "192.168.0.100", port: 3306, database: "erp_db", username: "erp_user", password: "encrypted_password", // AES-256-CBC 암호화 company_code: "ILSHIN", is_active: "Y" } // 연결 테스트 POST /api/external-db-connections/:id/test { success: true, message: "연결 테스트 성공" } // 쿼리 실행 POST /api/external-db-connections/:id/query { query: "SELECT * FROM products WHERE category = ?", params: ["전자제품"] } ``` ### 10.2 외부 REST API 연결 **파일**: `externalRestApiConnectionService.ts` ```typescript // 외부 REST API 연결 설정 { connection_name: "날씨 API", base_url: "https://api.weather.com", auth_type: "bearer", // bearer, api-key, basic, oauth2 auth_credentials: { token: "encrypted_token" }, headers: { "Content-Type": "application/json" }, company_code: "ILSHIN" } // API 호출 POST /api/external-rest-api-connections/:id/call { method: "GET", endpoint: "/weather", params: { city: "Seoul" } } ``` ### 10.3 멀티 DB 통합 쿼리 **파일**: `multiConnectionQueryService.ts` ```typescript // 여러 DB에서 동시 쿼리 실행 POST /api/multi-connection/query { connections: [ { connectionId: 1, query: "SELECT * FROM orders WHERE status = 'pending'" }, { connectionId: 2, query: "SELECT * FROM inventory WHERE quantity < 10" } ] } // 응답 { success: true, results: [ { connectionId: 1, data: [...], rowCount: 15 }, { connectionId: 2, data: [...], rowCount: 8 } ] } ``` ### 10.4 Open API Proxy **파일**: `openApiProxyController.ts` ```typescript // 날씨 API GET /api/open-api/weather?city=Seoul // 환율 API GET /api/open-api/exchange-rate?from=USD&to=KRW ``` --- ## 11. 배치/스케줄 처리 ### 11.1 배치 스케줄러 **파일**: `batchSchedulerService.ts` ```typescript // 배치 설정 { batch_name: "일일 재고 동기화", batch_type: "external_db", // external_db, rest_api, internal cron_schedule: "0 2 * * *", // 매일 새벽 2시 source_connection_id: 1, source_query: "SELECT * FROM inventory", target_table: "inventory_sync", mapping: { product_id: "item_id", quantity: "stock_qty" }, is_active: "Y" } // 스케줄러 초기화 (서버 시작 시) await BatchSchedulerService.initializeScheduler(); // 배치 수동 실행 POST /api/batch-configs/:id/execute ``` ### 11.2 Cron 기반 자동 실행 ```typescript // node-cron 사용 const task = cron.schedule( config.cron_schedule, // "0 2 * * *" async () => { logger.info(`배치 실행 시작: ${config.batch_name}`); await executeBatchConfig(config); }, { timezone: 'Asia/Seoul' } ); // 스케줄 업데이트 await BatchSchedulerService.updateBatchSchedule(configId); // 스케줄 제거 await BatchSchedulerService.removeBatchSchedule(configId); ``` ### 11.3 배치 실행 로그 **파일**: `batchExecutionLogService.ts` ```typescript // 배치 실행 이력 { batch_config_id: 1, execution_status: "success", // success, failed, running start_time: "2024-12-24T02:00:00Z", end_time: "2024-12-24T02:05:23Z", rows_processed: 1523, rows_inserted: 1200, rows_updated: 300, rows_failed: 23, error_message: null, execution_log: "..." } // 배치 이력 조회 GET /api/batch-execution-logs?batch_config_id=1&page=1&limit=10 ``` ### 11.4 자동 스케줄 작업 **파일**: `app.ts` ```typescript // 메일 자동 삭제 (매일 새벽 2시) cron.schedule('0 2 * * *', async () => { logger.info('🗑️ 30일 지난 삭제된 메일 자동 삭제 시작...'); const deletedCount = await mailSentHistoryService.cleanupOldDeletedMails(); logger.info(`✅ 30일 지난 메일 ${deletedCount}개 자동 삭제 완료`); }); // 리스크/알림 자동 갱신 (10분 간격) const cacheService = RiskAlertCacheService.getInstance(); cacheService.startAutoRefresh(); ``` --- ## 12. 컨트롤러/서비스 상세 역할 ### 12.1 인증 및 관리자 #### `authController.ts` / `authService.ts` - **로그인**: 비밀번호 검증, JWT 토큰 발급, 로그인 로그 기록 - **회원가입**: 공차중계 사용자 등록 - **토큰 갱신**: accessToken, refreshToken 갱신 - **현재 사용자 정보**: JWT 기반 사용자 정보 조회 - **로그아웃**: 토큰 무효화 (클라이언트 측 처리) - **회사 전환**: Super Admin 전용 회사 전환 #### `adminController.ts` / `adminService.ts` - **메뉴 관리**: 메뉴 트리 조회, 메뉴 CRUD, 메뉴 복사, 상태 토글, 일괄 삭제 - **사용자 관리**: 사용자 목록, 사용자 CRUD, 상태 변경, 비밀번호 초기화, 변경 이력 - **회사 관리**: 회사 목록, 회사 CRUD (Super Admin 전용) - **부서 관리**: 부서 목록, 사용자-부서 통합 저장 - **로케일 설정**: 사용자 언어 설정 (ko, en) - **테이블 스키마**: 엑셀 업로드 컬럼 매핑용 스키마 조회 ### 12.2 테이블 및 데이터 #### `tableManagementController.ts` / `tableManagementService.ts` - **테이블 목록**: PostgreSQL information_schema 조회 - **컬럼 정보**: 컬럼 타입, 제약조건, 라벨, 참조 관계 - **컬럼 라벨 관리**: 다국어 라벨, 표시 순서, 표시 여부 - **컬럼 설정**: 입력 타입, 코드 카테고리, 필수 여부, 기본값 - **테이블 조회 설정**: 조회 컬럼, 정렬 순서, 필터 조건 - **캐시 관리**: 테이블/컬럼 정보 캐시 (10분 TTL) #### `dataController.ts` / `dataService.ts` - **동적 데이터 조회**: 테이블명 기반 데이터 조회 (페이지네이션, 필터, 정렬) - **동적 데이터 생성**: INSERT 쿼리 자동 생성 - **동적 데이터 수정**: UPDATE 쿼리 자동 생성 - **동적 데이터 삭제**: DELETE 쿼리 자동 생성 (논리 삭제 지원) - **멀티테넌시 자동 필터링**: company_code 자동 추가 #### `entityJoinController.ts` / `entityJoinService.ts` - **조인 설정 관리**: 테이블 간 조인 관계 설정 (1:N, N:M) - **조인 쿼리 실행**: 설정된 조인 관계 기반 데이터 조회 - **참조 데이터 캐싱**: 자주 사용되는 참조 데이터 캐시 ### 12.3 화면 관리 #### `screenManagementController.ts` / `screenManagementService.ts` - **화면 메타데이터 관리**: 화면 설정 (테이블, 컬럼, 레이아웃) - **화면 목록 조회**: 회사별, 화면 그룹별 필터링 - **화면 복사**: 화면 설정 복제 - **화면 삭제**: 논리 삭제 - **화면 설정 조회**: 화면 메타데이터 상세 조회 #### `dynamicFormController.ts` / `dynamicFormService.ts` - **동적 폼 생성**: JSON 기반 폼 설정 → React 컴포넌트 - **폼 유효성 검사**: 필수 입력, 데이터 타입, 길이 제한 - **폼 제출**: 데이터 저장 (INSERT/UPDATE) #### `buttonActionStandardController.ts` / `buttonActionStandardService.ts` - **버튼 액션 표준**: 저장, 삭제, 조회, 엑셀 다운로드, 커스텀 액션 - **버튼 액션 설정**: 액션 타입, 파라미터, 권한 설정 ### 12.4 플로우 및 데이터플로우 #### `flowController.ts` / `flowService.ts` - **플로우 정의**: 플로우 생성, 수정, 삭제, 조회 - **플로우 단계**: 단계 생성, 수정, 삭제, 순서 변경 - **플로우 연결**: 단계 간 연결 (조건부 분기) - **데이터 이동**: 단계 간 데이터 이동 (단일/배치) - **오딧 로그**: 플로우 실행 이력 조회 #### `dataflowController.ts` / `dataflowService.ts` - **테이블 관계 정의**: 테이블 간 관계 설정 (1:1, 1:N, N:M) - **데이터플로우 다이어그램**: ERD 같은 시각화 - **데이터플로우 실행**: 관계 기반 데이터 동기화 - **관계 조회**: 다이어그램별 관계 목록 ### 12.5 배치 관리 #### `batchController.ts` / `batchService.ts` - **배치 설정 관리**: 배치 CRUD - **배치 실행**: 수동 실행, 스케줄 실행 - **배치 이력**: 실행 로그, 성공/실패 통계 - **커넥션 조회**: 사용 가능한 외부 DB/API 목록 #### `batchSchedulerService.ts` - **스케줄러 초기화**: 서버 시작 시 활성 배치 등록 - **스케줄 등록**: Cron 표현식 기반 스케줄 등록 - **스케줄 업데이트**: 배치 설정 변경 시 스케줄 재등록 - **스케줄 제거**: 배치 삭제 시 스케줄 제거 #### `batchExternalDbService.ts` - **외부 DB 배치**: 외부 DB → 내부 DB 데이터 동기화 - **컬럼 매핑**: 소스-타겟 컬럼 매핑 - **데이터 변환**: 타입 변환, 값 변환 ### 12.6 외부 연동 #### `externalDbConnectionController.ts` / `externalDbConnectionService.ts` - **외부 DB 연결 관리**: 연결 CRUD - **연결 테스트**: 연결 유효성 검증 - **쿼리 실행**: 외부 DB 쿼리 실행 - **테이블 목록**: 외부 DB 테이블 목록 조회 - **컬럼 정보**: 외부 DB 컬럼 정보 조회 #### `externalRestApiConnectionController.ts` / `externalRestApiConnectionService.ts` - **REST API 연결 관리**: API 연결 CRUD - **API 호출**: 외부 API 호출 (GET, POST, PUT, DELETE) - **인증 처리**: Bearer, API Key, Basic, OAuth2 - **응답 캐싱**: API 응답 캐싱 (TTL 설정) #### `multiConnectionQueryService.ts` - **멀티 DB 통합 쿼리**: 여러 DB에서 동시 쿼리 실행 - **결과 병합**: 여러 DB 쿼리 결과 병합 - **오류 처리**: 부분 실패 시 에러 로그 기록 ### 12.7 메일 관리 #### `mailAccountFileController.ts` / `mailAccountFileService.ts` - **메일 계정 관리**: SMTP/IMAP 계정 CRUD - **계정 테스트**: 연결 유효성 검증 - **계정 상태**: 활성/비활성 상태 관리 #### `mailTemplateFileController.ts` / `mailTemplateFileService.ts` - **메일 템플릿 관리**: 템플릿 CRUD - **템플릿 컴포넌트**: JSON 기반 컴포넌트 조합 (헤더, 본문, 버튼, 푸터) - **변수 치환**: {변수명} 형태의 변수 치환 #### `mailSendSimpleController.ts` / `mailSendSimpleService.ts` - **메일 발송**: 단일 발송, 대량 발송 (100건/배치) - **첨부파일**: 다중 첨부파일 지원 - **참조/숨은참조**: CC, BCC 지원 - **발송 이력**: 발송 성공/실패 로그 기록 #### `mailSentHistoryController.ts` / `mailSentHistoryService.ts` - **발송 이력 조회**: 페이지네이션, 필터링, 검색 - **이력 삭제**: 논리 삭제 (30일 후 물리 삭제) - **자동 삭제**: Cron 기반 자동 삭제 (매일 새벽 2시) #### `mailReceiveBasicController.ts` / `mailReceiveBasicService.ts` - **메일 수신**: IMAP 기반 메일 수신 - **메일 목록**: 수신함 목록 조회 - **메일 읽기**: 메일 상세 조회, 첨부파일 다운로드 ### 12.8 대시보드 및 리포트 #### `DashboardController.ts` / `DashboardService.ts` - **대시보드 위젯**: 차트, 테이블, 카드 위젯 - **실시간 데이터**: 집계 쿼리 기반 실시간 데이터 조회 - **사용자 설정**: 사용자별 대시보드 레이아웃 저장 #### `reportController.ts` / `reportService.ts` - **리포트 생성**: 동적 리포트 생성 (PDF, Excel, Word) - **리포트 템플릿**: 템플릿 기반 리포트 생성 - **리포트 스케줄**: 정기 리포트 자동 생성 및 메일 발송 ### 12.9 기타 도메인 #### `deliveryController.ts` / `deliveryService.ts` - **배송 관리**: 배송 정보 등록, 조회, 수정 - **화물 추적**: 배송 상태 추적 #### `riskAlertController.ts` / `riskAlertService.ts` / `riskAlertCacheService.ts` - **리스크 알림**: 리스크 기준 설정, 알림 발생 - **자동 갱신**: 10분 간격 자동 갱신 (캐시 기반) #### `todoController.ts` / `todoService.ts` - **To-Do 관리**: 할 일 CRUD, 상태 변경 (대기, 진행, 완료) #### `bookingController.ts` / `bookingService.ts` - **예약 관리**: 예약 요청 CRUD, 승인/거부 #### `digitalTwinController.ts` / `digitalTwinLayoutController.ts` / `digitalTwinDataController.ts` - **디지털 트윈**: 야드 관제, 3D 레이아웃, 실시간 데이터 시각화 #### `scheduleController.ts` / `scheduleService.ts` - **스케줄 자동 생성**: 작업 스케줄 자동 생성 (규칙 기반) #### `workHistoryController.ts` / `workHistoryService.ts` - **작업 이력**: 작업 로그 조회, 필터링, 검색 #### `roleController.ts` / `roleService.ts` - **권한 그룹**: 권한 그룹 CRUD, 사용자-권한 매핑 #### `numberingRuleController.ts` / `numberingRuleService.ts` - **채번 규칙**: 자동 채번 규칙 설정 (접두사, 연번, 접미사) #### `entitySearchController.ts` / `entitySearchService.ts` - **엔티티 검색**: 동적 엔티티 검색 (테이블, 컬럼, 조건 기반) #### `cascadingController.ts` 시리즈 - **연쇄 드롭다운**: 조건부 드롭다운 관계 설정 - **자동 입력**: 연쇄 자동 입력 관계 설정 - **상호 배제**: 상호 배타적 선택 관계 설정 - **다단계 계층**: 계층 구조 관계 설정 --- ## 📊 통계 요약 | 구분 | 개수 | |------|------| | **컨트롤러** | 69개 | | **서비스** | 87개 | | **라우터** | 77개 | | **미들웨어** | 4개 | | **엔드포인트** | 200개 이상 | | **데이터베이스 커넥터** | 5종 (PostgreSQL, MySQL, MSSQL, Oracle, MariaDB) | | **유틸리티** | 16개 | | **타입 정의** | 26개 | --- ## 🔧 기술 스택 ```json { "런타임": "Node.js 20.10.0+", "언어": "TypeScript 5.3.3", "프레임워크": "Express 4.18.2", "데이터베이스": "PostgreSQL (pg 8.16.3)", "인증": "JWT (jsonwebtoken 9.0.2)", "암호화": "BCrypt (bcryptjs 2.4.3)", "로깅": "Winston 3.11.0", "스케줄링": "node-cron 4.2.1", "메일": "Nodemailer 6.10.1 + IMAP 0.8.19", "파일 업로드": "Multer 1.4.5", "보안": "Helmet 7.1.0", "외부 DB": "mysql2, mssql, oracledb", "캐싱": "In-Memory Cache (Map 기반)", "압축": "compression 1.7.4", "Rate Limiting": "express-rate-limit 7.1.5" } ``` --- ## 📁 핵심 파일 경로 ``` backend-node/ ├── src/ │ ├── app.ts # 앱 진입점 │ ├── config/environment.ts # 환경변수 설정 │ ├── database/ │ │ ├── db.ts # Raw Query 매니저 │ │ ├── DatabaseConnectorFactory.ts # DB 커넥터 팩토리 │ │ └── [DB]Connector.ts # 각 DB별 커넥터 │ ├── middleware/ │ │ ├── authMiddleware.ts # JWT 인증 │ │ ├── permissionMiddleware.ts # 권한 체크 │ │ ├── superAdminMiddleware.ts # Super Admin 체크 │ │ └── errorHandler.ts # 에러 핸들링 │ ├── utils/ │ │ ├── logger.ts # Winston 로거 │ │ ├── jwtUtils.ts # JWT 유틸 │ │ ├── encryptUtil.ts # BCrypt 암호화 │ │ ├── passwordEncryption.ts # AES 암호화 │ │ ├── cache.ts # 캐시 유틸 │ │ └── permissionUtils.ts # 권한 유틸 │ └── types/ │ ├── auth.ts # 인증 타입 │ ├── tableManagement.ts # 테이블 관리 타입 │ └── ... └── package.json # 의존성 관리 ``` --- ## 🚀 서버 시작 프로세스 ``` 1. dotenv 환경변수 로드 2. Express 앱 생성 3. 미들웨어 설정 (helmet, cors, compression, rate-limit) 4. 데이터베이스 연결 풀 초기화 5. 라우터 등록 (77개 라우터) 6. 에러 핸들러 등록 7. 서버 리스닝 (기본 포트: 8080) 8. 데이터베이스 마이그레이션 실행 9. 배치 스케줄러 초기화 10. 리스크/알림 자동 갱신 시작 11. 메일 자동 삭제 스케줄러 시작 ``` --- ## 🔒 보안 고려사항 1. **JWT 기반 인증**: 세션 없이 무상태(Stateless) 인증 2. **비밀번호 암호화**: BCrypt (12 rounds) 3. **외부 DB 크레덴셜 암호화**: AES-256-CBC 4. **SQL Injection 방지**: Parameterized Query 필수 5. **XSS 방지**: Helmet 보안 헤더 6. **CSRF 방지**: CORS 설정 + JWT 7. **Rate Limiting**: 1분당 요청 수 제한 8. **DDL 실행 제한**: Super Admin만 가능 + 5초 간격 제한 9. **멀티테넌시 격리**: company_code 자동 필터링 10. **에러 정보 노출 방지**: 운영 환경에서 스택 트레이스 숨김 --- ## 📝 추천 개선 사항 1. **API 문서화**: Swagger/OpenAPI 자동 생성 2. **단위 테스트**: Jest 기반 테스트 커버리지 확대 3. **Redis 캐싱**: In-Memory 캐시 → Redis 전환 4. **로그 중앙화**: Winston → ELK Stack 연동 5. **성능 모니터링**: APM 도구 연동 (New Relic, Datadog) 6. **Docker 컨테이너화**: Dockerfile 및 docker-compose 개선 7. **CI/CD 파이프라인**: GitHub Actions, Jenkins 연동 8. **API Rate Limiting 세분화**: 엔드포인트별 제한 설정 9. **WebSocket 지원**: 실시간 알림 및 데이터 업데이트 10. **GraphQL API**: REST API + GraphQL 병행 지원 --- **문서 작성자**: WACE 백엔드 전문가 **최종 수정일**: 2026-02-06 **버전**: 1.0.0