ERP-node/docs/external-connection-managem...

11 KiB

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

📋 프로젝트 개요

목적

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

주요 기능

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

🗄️ 데이터베이스 설계

테이블: external_db_connections

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

샘플 데이터

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 모델 정의

// 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. 타입 정의

// 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. 서비스 계층

// 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 라우트

// 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 클라이언트

// 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. 메인 페이지

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

3. 연결 설정 모달

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

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

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

🔒 보안 구현

1. 비밀번호 암호화

// 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
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