# 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<T>(text: string, params?: any[]): Promise<T[]>

// 단일 행 조회
async function queryOne<T>(text: string, params?: any[]): Promise<T | null>

// 트랜잭션
async function transaction<T>(callback: (client: PoolClient) => Promise<T>): Promise<T>

// 연결 풀 상태
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<T>(CacheKeys.TABLE_LIST);
if (cachedData) {
  return cachedData;
}

// DB 조회
const data = await query<T>('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

