2025-09-25 11:04:16 +09:00
|
|
|
// 배치관리 전용 API 클라이언트 (기존 소스와 완전 분리)
|
|
|
|
|
// 작성일: 2024-12-24
|
|
|
|
|
|
|
|
|
|
import { apiClient } from "./client";
|
|
|
|
|
|
|
|
|
|
// 배치관리 전용 타입 정의
|
|
|
|
|
export interface BatchConnectionInfo {
|
|
|
|
|
type: 'internal' | 'external';
|
|
|
|
|
id?: number;
|
|
|
|
|
name: string;
|
|
|
|
|
db_type?: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface BatchColumnInfo {
|
|
|
|
|
column_name: string;
|
|
|
|
|
data_type: string;
|
|
|
|
|
is_nullable?: string;
|
|
|
|
|
column_default?: string | null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface BatchTableInfo {
|
|
|
|
|
table_name: string;
|
|
|
|
|
columns: BatchColumnInfo[];
|
|
|
|
|
description?: string | null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface BatchApiResponse<T = unknown> {
|
|
|
|
|
success: boolean;
|
|
|
|
|
data?: T;
|
|
|
|
|
message?: string;
|
|
|
|
|
error?: string;
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-26 17:29:20 +09:00
|
|
|
class BatchManagementAPIClass {
|
|
|
|
|
private static readonly BASE_PATH = "/batch-management";
|
2025-09-25 11:04:16 +09:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 사용 가능한 커넥션 목록 조회
|
|
|
|
|
*/
|
|
|
|
|
static async getAvailableConnections(): Promise<BatchConnectionInfo[]> {
|
|
|
|
|
try {
|
|
|
|
|
const response = await apiClient.get<BatchApiResponse<BatchConnectionInfo[]>>(
|
|
|
|
|
`${this.BASE_PATH}/connections`
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (!response.data.success) {
|
|
|
|
|
throw new Error(response.data.message || "커넥션 목록 조회에 실패했습니다.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return response.data.data || [];
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error("커넥션 목록 조회 오류:", error);
|
|
|
|
|
throw error;
|
|
|
|
|
}
|
2025-09-26 17:29:20 +09:00
|
|
|
}
|
2025-09-25 11:04:16 +09:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 특정 커넥션의 테이블 목록 조회
|
|
|
|
|
*/
|
|
|
|
|
static async getTablesFromConnection(
|
|
|
|
|
connectionType: 'internal' | 'external',
|
|
|
|
|
connectionId?: number
|
|
|
|
|
): Promise<string[]> {
|
|
|
|
|
try {
|
|
|
|
|
let url = `${this.BASE_PATH}/connections/${connectionType}`;
|
|
|
|
|
if (connectionType === 'external' && connectionId) {
|
|
|
|
|
url += `/${connectionId}`;
|
|
|
|
|
}
|
|
|
|
|
url += '/tables';
|
|
|
|
|
|
2025-09-26 17:29:20 +09:00
|
|
|
const response = await apiClient.get<BatchApiResponse<string[]>>(url);
|
2025-09-25 11:04:16 +09:00
|
|
|
|
|
|
|
|
if (!response.data.success) {
|
|
|
|
|
throw new Error(response.data.message || "테이블 목록 조회에 실패했습니다.");
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-26 17:29:20 +09:00
|
|
|
return response.data.data || [];
|
2025-09-25 11:04:16 +09:00
|
|
|
} catch (error) {
|
|
|
|
|
console.error("테이블 목록 조회 오류:", error);
|
|
|
|
|
throw error;
|
|
|
|
|
}
|
2025-09-26 17:29:20 +09:00
|
|
|
}
|
2025-09-25 11:04:16 +09:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 특정 테이블의 컬럼 정보 조회
|
|
|
|
|
*/
|
|
|
|
|
static async getTableColumns(
|
|
|
|
|
connectionType: 'internal' | 'external',
|
|
|
|
|
tableName: string,
|
|
|
|
|
connectionId?: number
|
|
|
|
|
): Promise<BatchColumnInfo[]> {
|
|
|
|
|
try {
|
|
|
|
|
let url = `${this.BASE_PATH}/connections/${connectionType}`;
|
|
|
|
|
if (connectionType === 'external' && connectionId) {
|
|
|
|
|
url += `/${connectionId}`;
|
|
|
|
|
}
|
2025-09-26 17:29:20 +09:00
|
|
|
url += `/tables/${encodeURIComponent(tableName)}/columns`;
|
|
|
|
|
|
|
|
|
|
console.log("🔍 컬럼 조회 API 호출:", { url, connectionType, connectionId, tableName });
|
2025-09-25 11:04:16 +09:00
|
|
|
|
|
|
|
|
const response = await apiClient.get<BatchApiResponse<BatchColumnInfo[]>>(url);
|
|
|
|
|
|
2025-09-26 17:29:20 +09:00
|
|
|
console.log("🔍 컬럼 조회 API 응답:", response.data);
|
|
|
|
|
|
2025-09-25 11:04:16 +09:00
|
|
|
if (!response.data.success) {
|
|
|
|
|
throw new Error(response.data.message || "컬럼 정보 조회에 실패했습니다.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return response.data.data || [];
|
|
|
|
|
} catch (error) {
|
2025-09-26 17:29:20 +09:00
|
|
|
console.error("❌ 컬럼 정보 조회 오류:", error);
|
2025-09-25 11:04:16 +09:00
|
|
|
throw error;
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-09-25 14:25:18 +09:00
|
|
|
|
2025-09-26 17:29:20 +09:00
|
|
|
/**
|
|
|
|
|
* REST API 데이터 미리보기
|
|
|
|
|
*/
|
|
|
|
|
static async previewRestApiData(
|
|
|
|
|
apiUrl: string,
|
|
|
|
|
apiKey: string,
|
|
|
|
|
endpoint: string,
|
|
|
|
|
method: 'GET' = 'GET'
|
|
|
|
|
): Promise<{
|
|
|
|
|
fields: string[];
|
|
|
|
|
samples: any[];
|
|
|
|
|
totalCount: number;
|
|
|
|
|
}> {
|
|
|
|
|
try {
|
|
|
|
|
const response = await apiClient.post<BatchApiResponse<{
|
|
|
|
|
fields: string[];
|
|
|
|
|
samples: any[];
|
|
|
|
|
totalCount: number;
|
|
|
|
|
}>>(`${this.BASE_PATH}/rest-api/preview`, {
|
|
|
|
|
apiUrl,
|
|
|
|
|
apiKey,
|
|
|
|
|
endpoint,
|
|
|
|
|
method
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (!response.data.success) {
|
|
|
|
|
throw new Error(response.data.message || "REST API 미리보기에 실패했습니다.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return response.data.data || { fields: [], samples: [], totalCount: 0 };
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error("REST API 미리보기 오류:", error);
|
|
|
|
|
throw error;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* REST API 배치 저장
|
|
|
|
|
*/
|
|
|
|
|
static async saveRestApiBatch(batchData: {
|
|
|
|
|
batchName: string;
|
|
|
|
|
batchType: string;
|
|
|
|
|
cronSchedule: string;
|
|
|
|
|
description?: string;
|
|
|
|
|
apiMappings: any[];
|
|
|
|
|
}): Promise<{ success: boolean; message: string; data?: any; }> {
|
|
|
|
|
try {
|
|
|
|
|
const response = await apiClient.post<BatchApiResponse<any>>(
|
|
|
|
|
`${this.BASE_PATH}/rest-api/save`, batchData
|
|
|
|
|
);
|
|
|
|
|
return {
|
|
|
|
|
success: response.data.success,
|
|
|
|
|
message: response.data.message || "",
|
|
|
|
|
data: response.data.data
|
|
|
|
|
};
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error("REST API 배치 저장 오류:", error);
|
|
|
|
|
throw error;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const BatchManagementAPI = BatchManagementAPIClass;
|