// 배치관리 API 클라이언트 (새로운 API로 업데이트) // 작성일: 2024-12-24 import { apiClient } from "./client"; export interface BatchConfig { id?: number; batch_name: string; description?: string; cron_schedule: string; is_active?: string; company_code?: string; created_date?: Date; created_by?: string; updated_date?: Date; updated_by?: string; batch_mappings?: BatchMapping[]; } export interface BatchMapping { id?: number; batch_config_id?: number; // FROM 정보 from_connection_type: 'internal' | 'external'; from_connection_id?: number; from_table_name: string; from_column_name: string; from_column_type?: string; // TO 정보 to_connection_type: 'internal' | 'external'; to_connection_id?: number; to_table_name: string; to_column_name: string; to_column_type?: string; mapping_order?: number; created_date?: Date; created_by?: string; } export interface BatchConfigFilter { batch_name?: string; is_active?: string; company_code?: string; search?: string; } export interface BatchJob { id: number; job_name: string; job_type: string; description?: string; cron_schedule: string; is_active: string; last_execution?: Date; next_execution?: Date; status?: string; created_date?: Date; created_by?: string; } export interface ConnectionInfo { type: 'internal' | 'external'; id?: number; name: string; db_type?: string; } export interface ColumnInfo { column_name: string; data_type: string; is_nullable?: boolean; column_default?: string; } export interface TableInfo { table_name: string; columns: ColumnInfo[]; description?: string | null; } export interface BatchMappingRequest { batchName: string; description?: string; cronSchedule: string; mappings: BatchMapping[]; isActive?: boolean; } export interface ApiResponse { success: boolean; data?: T; message?: string; error?: string; } export class BatchAPI { private static readonly BASE_PATH = ""; /** * 배치 설정 목록 조회 */ static async getBatchConfigs(filter: BatchConfigFilter = {}): Promise<{ success: boolean; data: BatchConfig[]; pagination?: { page: number; limit: number; total: number; totalPages: number; }; message?: string; }> { try { const params = new URLSearchParams(); if (filter.is_active) params.append("is_active", filter.is_active); if (filter.company_code) params.append("company_code", filter.company_code); if (filter.search) params.append("search", filter.search); if (filter.page) params.append("page", filter.page.toString()); if (filter.limit) params.append("limit", filter.limit.toString()); const response = await apiClient.get<{ success: boolean; data: BatchConfig[]; pagination?: { page: number; limit: number; total: number; totalPages: number; }; message?: string; }>(`/batch-configs?${params.toString()}`); return response.data; } catch (error) { console.error("배치 설정 목록 조회 오류:", error); return { success: false, data: [], message: error instanceof Error ? error.message : "배치 설정 목록 조회에 실패했습니다." }; } } /** * 특정 배치 설정 조회 (별칭) */ static async getBatchConfig(id: number): Promise { return this.getBatchConfigById(id); } /** * 특정 배치 설정 조회 */ static async getBatchConfigById(id: number): Promise { try { const response = await apiClient.get>( `/batch-management/batch-configs/${id}`, ); if (!response.data.success) { throw new Error(response.data.message || "배치 설정 조회에 실패했습니다."); } if (!response.data.data) { throw new Error("배치 설정을 찾을 수 없습니다."); } return response.data.data; } catch (error) { console.error("배치 설정 조회 오류:", error); throw error; } } /** * 배치 설정 생성 */ static async createBatchConfig(data: BatchMappingRequest): Promise { try { const response = await apiClient.post>( `/batch-configs`, data, ); if (!response.data.success) { throw new Error(response.data.message || "배치 설정 생성에 실패했습니다."); } if (!response.data.data) { throw new Error("배치 설정 생성 결과를 받을 수 없습니다."); } return response.data.data; } catch (error) { console.error("배치 설정 생성 오류:", error); throw error; } } /** * 배치 설정 수정 */ static async updateBatchConfig( id: number, data: Partial ): Promise { try { const response = await apiClient.put>( `/batch-management/batch-configs/${id}`, data, ); if (!response.data.success) { throw new Error(response.data.message || "배치 설정 수정에 실패했습니다."); } if (!response.data.data) { throw new Error("배치 설정 수정 결과를 받을 수 없습니다."); } return response.data.data; } catch (error) { console.error("배치 설정 수정 오류:", error); throw error; } } /** * 배치 설정 삭제 */ static async deleteBatchConfig(id: number): Promise { try { const response = await apiClient.delete>( `/batch-configs/${id}`, ); if (!response.data.success) { throw new Error(response.data.message || "배치 설정 삭제에 실패했습니다."); } } catch (error) { console.error("배치 설정 삭제 오류:", error); throw error; } } /** * 사용 가능한 커넥션 목록 조회 */ static async getConnections(): Promise { try { console.log("[BatchAPI] getAvailableConnections 호출 시작"); console.log("[BatchAPI] API URL:", `/batch-management/connections`); const response = await apiClient.get>( `/batch-management/connections`, ); console.log("[BatchAPI] API 응답:", response); console.log("[BatchAPI] 응답 데이터:", response.data); if (!response.data.success) { console.error("[BatchAPI] API 응답 실패:", response.data); throw new Error(response.data.message || "커넥션 목록 조회에 실패했습니다."); } const result = response.data.data || []; console.log("[BatchAPI] 최종 결과:", result); return result; } catch (error) { console.error("[BatchAPI] 커넥션 목록 조회 오류:", error); console.error("[BatchAPI] 오류 상세:", { message: error instanceof Error ? error.message : 'Unknown error', stack: error instanceof Error ? error.stack : undefined }); throw error; } } /** * 특정 커넥션의 테이블 목록 조회 */ static async getTablesFromConnection( connection: ConnectionInfo ): Promise { try { let url = `/batch-management/connections/${connection.type}`; if (connection.type === 'external' && connection.id) { url += `/${connection.id}`; } url += '/tables'; const response = await apiClient.get>(url); if (!response.data.success) { throw new Error(response.data.message || "테이블 목록 조회에 실패했습니다."); } // TableInfo[]에서 table_name만 추출하여 string[]로 변환 const tables = response.data.data || []; return tables.map(table => table.table_name); } catch (error) { console.error("테이블 목록 조회 오류:", error); throw error; } } /** * 특정 테이블의 컬럼 정보 조회 */ static async getTableColumns( connection: ConnectionInfo, tableName: string ): Promise { try { let url = `/batch-management/connections/${connection.type}`; if (connection.type === 'external' && connection.id) { url += `/${connection.id}`; } url += `/tables/${tableName}/columns`; const response = await apiClient.get>(url); if (!response.data.success) { throw new Error(response.data.message || "컬럼 정보 조회에 실패했습니다."); } return response.data.data || []; } catch (error) { console.error("컬럼 정보 조회 오류:", error); throw error; } } /** * 배치 작업 목록 조회 */ static async getBatchJobs(): Promise { try { const response = await apiClient.get>('/batch-management/jobs'); if (!response.data.success) { throw new Error(response.data.message || "배치 작업 목록 조회에 실패했습니다."); } return response.data.data || []; } catch (error) { console.error("배치 작업 목록 조회 오류:", error); throw error; } } /** * 배치 수동 실행 */ static async executeBatchConfig(batchId: number): Promise<{ success: boolean; message?: string; data?: { batchId: string; totalRecords: number; successRecords: number; failedRecords: number; duration: number; }; }> { try { const response = await apiClient.post<{ success: boolean; message?: string; data?: { batchId: string; totalRecords: number; successRecords: number; failedRecords: number; duration: number; }; }>(`/batch-management/batch-configs/${batchId}/execute`); return response.data; } catch (error) { console.error("배치 실행 오류:", error); throw error; } } } // BatchJob export 추가 (이미 위에서 interface로 정의됨) export { BatchJob };