// 배치관리 컨트롤러 // 작성일: 2024-12-24 import { Request, Response } from "express"; import { BatchService } from "../services/batchService"; import { BatchConfigFilter, BatchMappingRequest } from "../types/batchTypes"; export interface AuthenticatedRequest extends Request { user?: { userId: string; username: string; companyCode: string; }; } export class BatchController { /** * 배치 설정 목록 조회 * GET /api/batch-configs */ static async getBatchConfigs(req: AuthenticatedRequest, res: Response) { try { const filter: BatchConfigFilter = { is_active: req.query.is_active as string, company_code: req.query.company_code as string, search: req.query.search as string, }; // 빈 값 제거 Object.keys(filter).forEach((key) => { if (!filter[key as keyof BatchConfigFilter]) { delete filter[key as keyof BatchConfigFilter]; } }); const result = await BatchService.getBatchConfigs(filter); if (result.success) { return res.status(200).json(result); } else { return res.status(400).json(result); } } catch (error) { console.error("배치 설정 목록 조회 오류:", error); return res.status(500).json({ success: false, message: "서버 내부 오류가 발생했습니다.", error: error instanceof Error ? error.message : "알 수 없는 오류", }); } } /** * 특정 배치 설정 조회 * GET /api/batch-configs/:id */ static async getBatchConfigById(req: AuthenticatedRequest, res: Response) { try { const id = parseInt(req.params.id); if (isNaN(id)) { return res.status(400).json({ success: false, message: "유효하지 않은 배치 설정 ID입니다.", }); } const result = await BatchService.getBatchConfigById(id); if (result.success) { return res.status(200).json(result); } else { return res.status(404).json(result); } } catch (error) { console.error("배치 설정 조회 오류:", error); return res.status(500).json({ success: false, message: "서버 내부 오류가 발생했습니다.", error: error instanceof Error ? error.message : "알 수 없는 오류", }); } } /** * 배치 설정 생성 * POST /api/batch-configs */ static async createBatchConfig(req: AuthenticatedRequest, res: Response) { try { const data: BatchMappingRequest = req.body; // 필수 필드 검증 if (!data.batch_name || !data.cron_schedule || !data.mappings) { return res.status(400).json({ success: false, message: "필수 필드가 누락되었습니다. (batch_name, cron_schedule, mappings)", }); } const result = await BatchService.createBatchConfig( data, req.user?.userId ); if (result.success) { return res.status(201).json(result); } else { return res.status(400).json(result); } } catch (error) { console.error("배치 설정 생성 오류:", error); return res.status(500).json({ success: false, message: "서버 내부 오류가 발생했습니다.", error: error instanceof Error ? error.message : "알 수 없는 오류", }); } } /** * 배치 설정 수정 * PUT /api/batch-configs/:id */ static async updateBatchConfig(req: AuthenticatedRequest, res: Response) { try { const id = parseInt(req.params.id); const data: Partial = req.body; if (isNaN(id)) { return res.status(400).json({ success: false, message: "유효하지 않은 배치 설정 ID입니다.", }); } const result = await BatchService.updateBatchConfig( id, data, req.user?.userId ); if (result.success) { return res.status(200).json(result); } else { return res.status(400).json(result); } } catch (error) { console.error("배치 설정 수정 오류:", error); return res.status(500).json({ success: false, message: "서버 내부 오류가 발생했습니다.", error: error instanceof Error ? error.message : "알 수 없는 오류", }); } } /** * 배치 설정 삭제 * DELETE /api/batch-configs/:id */ static async deleteBatchConfig(req: AuthenticatedRequest, res: Response) { try { const id = parseInt(req.params.id); if (isNaN(id)) { return res.status(400).json({ success: false, message: "유효하지 않은 배치 설정 ID입니다.", }); } const result = await BatchService.deleteBatchConfig( id, req.user?.userId ); if (result.success) { return res.status(200).json(result); } else { return res.status(404).json(result); } } catch (error) { console.error("배치 설정 삭제 오류:", error); return res.status(500).json({ success: false, message: "서버 내부 오류가 발생했습니다.", error: error instanceof Error ? error.message : "알 수 없는 오류", }); } } /** * 사용 가능한 커넥션 목록 조회 * GET /api/batch-configs/connections */ static async getAvailableConnections(req: AuthenticatedRequest, res: Response) { try { const result = await BatchService.getAvailableConnections(); if (result.success) { return res.status(200).json(result); } else { return res.status(400).json(result); } } catch (error) { console.error("커넥션 목록 조회 오류:", error); return res.status(500).json({ success: false, message: "서버 내부 오류가 발생했습니다.", error: error instanceof Error ? error.message : "알 수 없는 오류", }); } } /** * 특정 커넥션의 테이블 목록 조회 * GET /api/batch-configs/connections/:type/tables * GET /api/batch-configs/connections/:type/:id/tables */ static async getTablesFromConnection(req: AuthenticatedRequest, res: Response) { try { const connectionType = req.params.type as 'internal' | 'external'; const connectionId = req.params.id ? parseInt(req.params.id) : undefined; if (connectionType !== 'internal' && connectionType !== 'external') { return res.status(400).json({ success: false, message: "유효하지 않은 커넥션 타입입니다. (internal 또는 external)", }); } if (connectionType === 'external' && (!connectionId || isNaN(connectionId))) { return res.status(400).json({ success: false, message: "외부 커넥션의 경우 유효한 커넥션 ID가 필요합니다.", }); } const result = await BatchService.getTablesFromConnection( connectionType, connectionId ); if (result.success) { return res.status(200).json(result); } else { return res.status(400).json(result); } } catch (error) { console.error("테이블 목록 조회 오류:", error); return res.status(500).json({ success: false, message: "서버 내부 오류가 발생했습니다.", error: error instanceof Error ? error.message : "알 수 없는 오류", }); } } /** * 특정 테이블의 컬럼 정보 조회 * GET /api/batch-configs/connections/:type/tables/:tableName/columns * GET /api/batch-configs/connections/:type/:id/tables/:tableName/columns */ static async getTableColumns(req: AuthenticatedRequest, res: Response) { try { const connectionType = req.params.type as 'internal' | 'external'; const connectionId = req.params.id ? parseInt(req.params.id) : undefined; const tableName = req.params.tableName; if (connectionType !== 'internal' && connectionType !== 'external') { return res.status(400).json({ success: false, message: "유효하지 않은 커넥션 타입입니다. (internal 또는 external)", }); } if (connectionType === 'external' && (!connectionId || isNaN(connectionId))) { return res.status(400).json({ success: false, message: "외부 커넥션의 경우 유효한 커넥션 ID가 필요합니다.", }); } if (!tableName) { return res.status(400).json({ success: false, message: "테이블명이 필요합니다.", }); } const result = await BatchService.getTableColumns( connectionType, tableName, connectionId ); if (result.success) { return res.status(200).json(result); } else { return res.status(400).json(result); } } catch (error) { console.error("컬럼 정보 조회 오류:", error); return res.status(500).json({ success: false, message: "서버 내부 오류가 발생했습니다.", error: error instanceof Error ? error.message : "알 수 없는 오류", }); } } }