// 배치 관리 API 클라이언트 // 작성일: 2024-12-23 import { apiClient } from "./client"; export interface BatchJob { id?: number; job_name: string; description?: string; job_type: 'collection' | 'sync' | 'cleanup' | 'custom'; schedule_cron?: string; is_active: string; config_json?: Record; last_executed_at?: Date; next_execution_at?: Date; execution_count: number; success_count: number; failure_count: number; created_date?: Date; created_by?: string; updated_date?: Date; updated_by?: string; company_code: string; } export interface BatchJobFilter { job_name?: string; job_type?: string; is_active?: string; company_code?: string; search?: string; } export interface BatchExecution { id?: number; job_id: number; execution_status: 'pending' | 'running' | 'completed' | 'failed' | 'cancelled'; started_at?: Date; completed_at?: Date; execution_time_ms?: number; result_data?: Record; error_message?: string; log_details?: string; created_date?: Date; } export interface BatchMonitoring { total_jobs: number; active_jobs: number; running_jobs: number; failed_jobs_today: number; successful_jobs_today: number; recent_executions: BatchExecution[]; } export interface ApiResponse { success: boolean; data?: T; message?: string; error?: string; } export class BatchAPI { private static readonly BASE_PATH = "/batch"; /** * 배치 작업 목록 조회 */ static async getBatchJobs(filter: BatchJobFilter = {}): Promise { try { const params = new URLSearchParams(); if (filter.job_name) params.append("job_name", filter.job_name); if (filter.job_type) params.append("job_type", filter.job_type); 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); const response = await apiClient.get>( `${this.BASE_PATH}?${params.toString()}` ); if (!response.data.success) { throw new Error(response.data.message || "배치 작업 목록 조회에 실패했습니다."); } return response.data.data || []; } catch (error) { console.error("배치 작업 목록 조회 오류:", error); throw error; } } /** * 배치 작업 상세 조회 */ static async getBatchJobById(id: number): Promise { try { const response = await apiClient.get>(`${this.BASE_PATH}/${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 createBatchJob(data: BatchJob): Promise { try { const response = await apiClient.post>(this.BASE_PATH, 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 updateBatchJob(id: number, data: Partial): Promise { try { const response = await apiClient.put>(`${this.BASE_PATH}/${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 deleteBatchJob(id: number): Promise { try { const response = await apiClient.delete>(`${this.BASE_PATH}/${id}`); if (!response.data.success) { throw new Error(response.data.message || "배치 작업 삭제에 실패했습니다."); } } catch (error) { console.error("배치 작업 삭제 오류:", error); throw error; } } /** * 배치 작업 수동 실행 */ static async executeBatchJob(id: number): Promise { try { const response = await apiClient.post>(`${this.BASE_PATH}/${id}/execute`); 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 getBatchExecutions(jobId?: number): Promise { try { const params = new URLSearchParams(); if (jobId) params.append("job_id", jobId.toString()); const response = await apiClient.get>( `${this.BASE_PATH}/executions/list?${params.toString()}` ); if (!response.data.success) { throw new Error(response.data.message || "배치 실행 목록 조회에 실패했습니다."); } return response.data.data || []; } catch (error) { console.error("배치 실행 목록 조회 오류:", error); throw error; } } /** * 배치 모니터링 정보 조회 */ static async getBatchMonitoring(): Promise { try { const response = await apiClient.get>( `${this.BASE_PATH}/monitoring/status` ); 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 getSupportedJobTypes(): Promise> { try { const response = await apiClient.get }>>( `${this.BASE_PATH}/types/supported` ); if (!response.data.success) { throw new Error(response.data.message || "작업 타입 조회에 실패했습니다."); } return response.data.data?.types || []; } catch (error) { console.error("작업 타입 조회 오류:", error); throw error; } } /** * 스케줄 프리셋 조회 */ static async getSchedulePresets(): Promise> { try { const response = await apiClient.get }>>( `${this.BASE_PATH}/schedules/presets` ); if (!response.data.success) { throw new Error(response.data.message || "스케줄 프리셋 조회에 실패했습니다."); } return response.data.data?.presets || []; } catch (error) { console.error("스케줄 프리셋 조회 오류:", error); throw error; } } /** * 실행 상태 옵션 조회 */ static getExecutionStatusOptions() { return [ { value: 'pending', label: '대기 중' }, { value: 'running', label: '실행 중' }, { value: 'completed', label: '완료' }, { value: 'failed', label: '실패' }, { value: 'cancelled', label: '취소됨' }, ]; } }