Files
vexplor/docs/external-connection-management-plan.md

412 lines
11 KiB
Markdown
Raw Normal View History

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