import { Request, Response } from "express"; import { FlowExternalDbConnectionService } from "../services/flowExternalDbConnectionService"; import { CreateFlowExternalDbConnectionRequest, UpdateFlowExternalDbConnectionRequest, } from "../types/flow"; import logger from "../utils/logger"; /** * 플로우 전용 외부 DB 연결 컨트롤러 */ export class FlowExternalDbConnectionController { private service: FlowExternalDbConnectionService; constructor() { this.service = new FlowExternalDbConnectionService(); } /** * GET /api/flow/external-db-connections * 모든 외부 DB 연결 목록 조회 */ async getAll(req: Request, res: Response): Promise { try { const activeOnly = req.query.activeOnly === "true"; const connections = await this.service.findAll(activeOnly); res.json({ success: true, data: connections, message: `${connections.length}개의 외부 DB 연결을 조회했습니다`, }); } catch (error: any) { logger.error("외부 DB 연결 목록 조회 오류:", error); res.status(500).json({ success: false, message: "외부 DB 연결 목록 조회 중 오류가 발생했습니다", error: error.message, }); } } /** * GET /api/flow/external-db-connections/:id * 특정 외부 DB 연결 조회 */ async getById(req: Request, res: Response): Promise { try { const id = parseInt(req.params.id); if (isNaN(id)) { res.status(400).json({ success: false, message: "유효하지 않은 연결 ID입니다", }); return; } const connection = await this.service.findById(id); if (!connection) { res.status(404).json({ success: false, message: "외부 DB 연결을 찾을 수 없습니다", }); return; } res.json({ success: true, data: connection, }); } catch (error: any) { logger.error("외부 DB 연결 조회 오류:", error); res.status(500).json({ success: false, message: "외부 DB 연결 조회 중 오류가 발생했습니다", error: error.message, }); } } /** * POST /api/flow/external-db-connections * 새 외부 DB 연결 생성 */ async create(req: Request, res: Response): Promise { try { const request: CreateFlowExternalDbConnectionRequest = req.body; // 필수 필드 검증 if ( !request.name || !request.dbType || !request.host || !request.port || !request.databaseName || !request.username || !request.password ) { res.status(400).json({ success: false, message: "필수 필드가 누락되었습니다", }); return; } const userId = (req as any).user?.userId || "system"; const connection = await this.service.create(request, userId); logger.info( `외부 DB 연결 생성: ${connection.name} (ID: ${connection.id})` ); res.status(201).json({ success: true, data: connection, message: "외부 DB 연결이 생성되었습니다", }); } catch (error: any) { logger.error("외부 DB 연결 생성 오류:", error); res.status(500).json({ success: false, message: "외부 DB 연결 생성 중 오류가 발생했습니다", error: error.message, }); } } /** * PUT /api/flow/external-db-connections/:id * 외부 DB 연결 수정 */ async update(req: Request, res: Response): Promise { try { const id = parseInt(req.params.id); if (isNaN(id)) { res.status(400).json({ success: false, message: "유효하지 않은 연결 ID입니다", }); return; } const request: UpdateFlowExternalDbConnectionRequest = req.body; const userId = (req as any).user?.userId || "system"; const connection = await this.service.update(id, request, userId); if (!connection) { res.status(404).json({ success: false, message: "외부 DB 연결을 찾을 수 없습니다", }); return; } logger.info(`외부 DB 연결 수정: ${connection.name} (ID: ${id})`); res.json({ success: true, data: connection, message: "외부 DB 연결이 수정되었습니다", }); } catch (error: any) { logger.error("외부 DB 연결 수정 오류:", error); res.status(500).json({ success: false, message: "외부 DB 연결 수정 중 오류가 발생했습니다", error: error.message, }); } } /** * DELETE /api/flow/external-db-connections/:id * 외부 DB 연결 삭제 */ async delete(req: Request, res: Response): Promise { try { const id = parseInt(req.params.id); if (isNaN(id)) { res.status(400).json({ success: false, message: "유효하지 않은 연결 ID입니다", }); return; } const success = await this.service.delete(id); if (!success) { res.status(404).json({ success: false, message: "외부 DB 연결을 찾을 수 없습니다", }); return; } logger.info(`외부 DB 연결 삭제: ID ${id}`); res.json({ success: true, message: "외부 DB 연결이 삭제되었습니다", }); } catch (error: any) { logger.error("외부 DB 연결 삭제 오류:", error); res.status(500).json({ success: false, message: "외부 DB 연결 삭제 중 오류가 발생했습니다", error: error.message, }); } } /** * POST /api/flow/external-db-connections/:id/test * 외부 DB 연결 테스트 */ async testConnection(req: Request, res: Response): Promise { try { const id = parseInt(req.params.id); if (isNaN(id)) { res.status(400).json({ success: false, message: "유효하지 않은 연결 ID입니다", }); return; } const result = await this.service.testConnection(id); if (result.success) { logger.info(`외부 DB 연결 테스트 성공: ID ${id}`); res.json({ success: true, message: result.message, }); } else { logger.warn(`외부 DB 연결 테스트 실패: ID ${id} - ${result.message}`); res.status(400).json({ success: false, message: result.message, }); } } catch (error: any) { logger.error("외부 DB 연결 테스트 오류:", error); res.status(500).json({ success: false, message: "외부 DB 연결 테스트 중 오류가 발생했습니다", error: error.message, }); } } /** * GET /api/flow/external-db-connections/:id/tables * 외부 DB의 테이블 목록 조회 */ async getTables(req: Request, res: Response): Promise { try { const id = parseInt(req.params.id); if (isNaN(id)) { res.status(400).json({ success: false, message: "유효하지 않은 연결 ID입니다", }); return; } const result = await this.service.getTables(id); if (result.success) { res.json(result); } else { res.status(400).json(result); } } catch (error: any) { logger.error("외부 DB 테이블 목록 조회 오류:", error); res.status(500).json({ success: false, message: "외부 DB 테이블 목록 조회 중 오류가 발생했습니다", error: error.message, }); } } /** * GET /api/flow/external-db-connections/:id/tables/:tableName/columns * 외부 DB 특정 테이블의 컬럼 목록 조회 */ async getTableColumns(req: Request, res: Response): Promise { try { const id = parseInt(req.params.id); const tableName = req.params.tableName; if (isNaN(id)) { res.status(400).json({ success: false, message: "유효하지 않은 연결 ID입니다", }); return; } if (!tableName) { res.status(400).json({ success: false, message: "테이블명이 필요합니다", }); return; } const result = await this.service.getTableColumns(id, tableName); if (result.success) { res.json(result); } else { res.status(400).json(result); } } catch (error: any) { logger.error("외부 DB 컬럼 목록 조회 오류:", error); res.status(500).json({ success: false, message: "외부 DB 컬럼 목록 조회 중 오류가 발생했습니다", error: error.message, }); } } }