# 외부 커넥션 관리 시스템 구현 계획서

## 📋 프로젝트 개요

### 목적

- 제어관리 시스템에서 외부 데이터베이스에 접근할 수 있도록 DB 접속 정보를 중앙 관리
- 관리자가 외부 DB 연결 설정을 쉽게 등록, 수정, 삭제, 테스트할 수 있는 시스템 구축

### 주요 기능

- 외부 DB 접속 정보 CRUD 관리
- 다양한 DB 타입 지원 (MySQL, PostgreSQL, Oracle, SQL Server, SQLite)
- 연결 테스트 기능
- 비밀번호 암호화 저장
- 회사별 접속 정보 관리

## 🗄️ 데이터베이스 설계

### 테이블: `external_db_connections`

```sql
CREATE TABLE external_db_connections (
    id SERIAL PRIMARY KEY,
    connection_name VARCHAR(100) NOT NULL,
    description TEXT,

    -- DB 연결 정보
    db_type VARCHAR(20) NOT NULL,  -- mysql, postgresql, oracle, mssql, sqlite
    host VARCHAR(255) NOT NULL,
    port INTEGER NOT NULL,
    database_name VARCHAR(100) NOT NULL,
    username VARCHAR(100) NOT NULL,
    password TEXT NOT NULL,        -- 암호화된 비밀번호

    -- 고급 설정
    connection_timeout INTEGER DEFAULT 30,
    query_timeout INTEGER DEFAULT 60,
    max_connections INTEGER DEFAULT 10,
    ssl_enabled CHAR(1) DEFAULT 'N',
    ssl_cert_path VARCHAR(500),
    connection_options JSONB,      -- 추가 연결 옵션

    -- 관리 정보
    company_code VARCHAR(20) DEFAULT '*',
    is_active CHAR(1) DEFAULT 'Y',
    created_date TIMESTAMP DEFAULT NOW(),
    created_by VARCHAR(50),
    updated_date TIMESTAMP DEFAULT NOW(),
    updated_by VARCHAR(50)
);

-- 인덱스
CREATE INDEX idx_external_db_connections_company ON external_db_connections(company_code);
CREATE INDEX idx_external_db_connections_active ON external_db_connections(is_active);
CREATE INDEX idx_external_db_connections_type ON external_db_connections(db_type);
```

### 샘플 데이터

```sql
INSERT INTO external_db_connections (
    connection_name, description, db_type, host, port,
    database_name, username, password, company_code
) VALUES
(
    '영업팀 MySQL',
    '영업팀에서 사용하는 고객 데이터베이스',
    'mysql',
    'sales-db.company.com',
    3306,
    'sales_db',
    'sales_user',
    'encrypted_password_here',
    'COMP001'
),
(
    '재무팀 PostgreSQL',
    '재무 데이터 및 회계 정보',
    'postgresql',
    'finance-db.company.com',
    5432,
    'finance_db',
    'finance_user',
    'encrypted_password_here',
    'COMP001'
);
```

## 🔧 백엔드 구현

### 1. Prisma 모델 정의

```typescript
// prisma/schema.prisma
model external_db_connections {
  id                   Int       @id @default(autoincrement())
  connection_name      String    @db.VarChar(100)
  description          String?   @db.Text
  db_type              String    @db.VarChar(20)
  host                 String    @db.VarChar(255)
  port                 Int
  database_name        String    @db.VarChar(100)
  username             String    @db.VarChar(100)
  password             String    @db.Text
  connection_timeout   Int?      @default(30)
  query_timeout        Int?      @default(60)
  max_connections      Int?      @default(10)
  ssl_enabled          String    @default("N") @db.Char(1)
  ssl_cert_path        String?   @db.VarChar(500)
  connection_options   Json?
  company_code         String    @default("*") @db.VarChar(20)
  is_active            String    @default("Y") @db.Char(1)
  created_date         DateTime? @default(now()) @db.Timestamp(6)
  created_by           String?   @db.VarChar(50)
  updated_date         DateTime? @default(now()) @updatedAt @db.Timestamp(6)
  updated_by           String?   @db.VarChar(50)

  @@index([company_code])
  @@index([is_active])
  @@index([db_type])
}
```

### 2. 타입 정의

```typescript
// backend-node/src/types/externalDbTypes.ts
export interface ExternalDbConnection {
  id?: number;
  connection_name: string;
  description?: string;
  db_type: "mysql" | "postgresql" | "oracle" | "mssql" | "sqlite";
  host: string;
  port: number;
  database_name: string;
  username: string;
  password: string;
  connection_timeout?: number;
  query_timeout?: number;
  max_connections?: number;
  ssl_enabled?: string;
  ssl_cert_path?: string;
  connection_options?: Record<string, unknown>;
  company_code: string;
  is_active: string;
  created_date?: Date;
  created_by?: string;
  updated_date?: Date;
  updated_by?: string;
}

export interface ExternalDbConnectionFilter {
  db_type?: string;
  is_active?: string;
  company_code?: string;
  search?: string;
}

export interface ConnectionTestRequest {
  id?: number;
  connection_name?: string;
  db_type: string;
  host: string;
  port: number;
  database_name: string;
  username: string;
  password: string;
  connection_timeout?: number;
  ssl_enabled?: string;
  ssl_cert_path?: string;
}

export interface ConnectionTestResult {
  success: boolean;
  message: string;
  connection_time?: number;
  server_version?: string;
  error_details?: string;
}

export const DB_TYPE_OPTIONS = [
  { value: "mysql", label: "MySQL" },
  { value: "postgresql", label: "PostgreSQL" },
  { value: "oracle", label: "Oracle" },
  { value: "mssql", label: "SQL Server" },
  { value: "sqlite", label: "SQLite" },
];

export const DB_TYPE_DEFAULTS = {
  mysql: { port: 3306, driver: "mysql2" },
  postgresql: { port: 5432, driver: "pg" },
  oracle: { port: 1521, driver: "oracledb" },
  mssql: { port: 1433, driver: "mssql" },
  sqlite: { port: 0, driver: "sqlite3" },
};
```

### 3. 서비스 계층

```typescript
// backend-node/src/services/externalDbConnectionService.ts
export class ExternalDbConnectionService {
  // CRUD 메서드들
  static async getConnections(filter: ExternalDbConnectionFilter);
  static async getConnectionById(id: number);
  static async createConnection(data: ExternalDbConnection);
  static async updateConnection(
    id: number,
    data: Partial<ExternalDbConnection>
  );
  static async deleteConnection(id: number); // 논리 삭제
  static async testConnection(connectionData: ConnectionTestRequest);

  // 유틸리티 메서드들
  private static encryptPassword(password: string): string;
  private static decryptPassword(encryptedPassword: string): string;
  private static validateConnectionData(data: ExternalDbConnection): void;
}
```

### 4. API 라우트

```typescript
// backend-node/src/routes/externalDbConnectionRoutes.ts
// GET    /api/external-db-connections     - 목록 조회
// GET    /api/external-db-connections/:id - 상세 조회
// POST   /api/external-db-connections     - 새 연결 생성
// PUT    /api/external-db-connections/:id - 연결 수정
// DELETE /api/external-db-connections/:id - 연결 삭제 (논리삭제)
// POST   /api/external-db-connections/test - 연결 테스트
```

## 🎨 프론트엔드 구현

### 1. API 클라이언트

```typescript
// frontend/lib/api/externalDbConnection.ts
export class ExternalDbConnectionAPI {
  static async getConnections(filter?: ExternalDbConnectionFilter);
  static async getConnectionById(id: number);
  static async createConnection(data: ExternalDbConnection);
  static async updateConnection(
    id: number,
    data: Partial<ExternalDbConnection>
  );
  static async deleteConnection(id: number);
  static async testConnection(connectionData: ConnectionTestRequest);
}
```

### 2. 메인 페이지

```typescript
// frontend/app/(main)/admin/external-connections/page.tsx
- 연결 목록 테이블 (리스트형)
- 검색 및 필터링 (DB 타입, 상태, 회사)
- 새 연결 추가 버튼
- 각 행별 편집/삭제/테스트 버튼
```

### 3. 연결 설정 모달

```typescript
// frontend/components/admin/ExternalDbConnectionModal.tsx
- 기본 정보 입력 (연결명, 설명)
- DB 연결 정보 (타입, 호스트, 포트, DB명, 계정)
- 고급 설정 (타임아웃, SSL 등) - 접기/펼치기
- 연결 테스트 버튼
- 저장/취소 버튼
```

### 4. 연결 테스트 다이얼로그

```typescript
// frontend/components/admin/ConnectionTestDialog.tsx
- 테스트 진행 상태 표시
- 연결 결과 (성공/실패, 응답시간, 서버 버전)
- 오류 상세 정보 표시
```

## 🔒 보안 구현

### 1. 비밀번호 암호화

```typescript
// backend-node/src/utils/passwordEncryption.ts
export class PasswordEncryption {
  private static readonly ALGORITHM = "aes-256-gcm";
  private static readonly SECRET_KEY = process.env.DB_PASSWORD_SECRET;

  static encrypt(password: string): string;
  static decrypt(encryptedPassword: string): string;
}
```

### 2. 환경 변수 설정

```env
# .env
DB_PASSWORD_SECRET=your-super-secret-encryption-key-here
```

### 3. 접근 권한 제어

- 관리자 권한만 접근 가능
- 회사별 데이터 분리
- API 호출 시 인증 토큰 검증

## 📅 구현 일정

### Phase 1: 데이터베이스 및 백엔드 (2-3일)

- [ ] 데이터베이스 테이블 생성
- [ ] Prisma 모델 정의
- [ ] 타입 정의 작성
- [ ] 서비스 계층 구현
- [ ] API 라우트 구현
- [ ] 비밀번호 암호화 구현

### Phase 2: 프론트엔드 기본 구현 (2-3일)

- [ ] API 클라이언트 작성
- [ ] 메인 페이지 구현 (리스트)
- [ ] 연결 설정 모달 구현
- [ ] 기본 CRUD 기능 구현

### Phase 3: 고급 기능 및 테스트 (1-2일)

- [ ] 연결 테스트 기능 구현
- [ ] 고급 설정 옵션 구현
- [ ] 에러 처리 및 검증 강화
- [ ] UI/UX 개선

### Phase 4: 통합 및 배포 (1일)

- [ ] 메뉴 등록
- [ ] 권한 설정
- [ ] 전체 테스트
- [ ] 문서화 완료

## 🧪 테스트 계획

### 1. 단위 테스트

- 비밀번호 암호화/복호화
- 연결 데이터 검증
- API 엔드포인트 테스트

### 2. 통합 테스트

- 실제 DB 연결 테스트 (다양한 DB 타입)
- 프론트엔드-백엔드 연동 테스트
- 권한 및 보안 테스트

### 3. 사용자 테스트

- 관리자 시나리오 테스트
- UI/UX 사용성 테스트
- 오류 상황 처리 테스트

## 🚀 배포 및 운영

### 1. 환경 설정

- 프로덕션 환경 암호화 키 설정
- DB 접속 권한 최소화
- 로그 모니터링 설정

### 2. 모니터링

- 외부 DB 연결 상태 모니터링
- 연결 풀 사용률 모니터링
- 쿼리 성능 모니터링

### 3. 백업 및 복구

- 연결 설정 정보 백업
- 암호화 키 관리
- 장애 복구 절차

## 📚 참고사항

### 1. 지원 DB 드라이버

- MySQL: `mysql2`
- PostgreSQL: `pg`
- Oracle: `oracledb`
- SQL Server: `mssql`
- SQLite: `sqlite3`

### 2. 연결 풀 관리

- 각 DB별 연결 풀 생성
- 최대 연결 수 제한
- 유휴 연결 정리

### 3. 확장 가능성

- NoSQL DB 지원 (MongoDB, Redis)
- API 연결 지원
- 파일 시스템 연결 지원

---

**작성일**: 2024년 12월 17일  
**작성자**: AI Assistant  
**버전**: 1.0


