# 외부 커넥션 관리 시스템 구현 계획서 ## 📋 프로젝트 개요 ### 목적 - 제어관리 시스템에서 외부 데이터베이스에 접근할 수 있도록 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; 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 ); 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 ); 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