ERP-node/frontend/lib/api/flow.ts

464 lines
10 KiB
TypeScript

/**
* 플로우 관리 API 클라이언트
*/
import {
FlowDefinition,
CreateFlowDefinitionRequest,
UpdateFlowDefinitionRequest,
FlowStep,
CreateFlowStepRequest,
UpdateFlowStepRequest,
FlowStepConnection,
CreateFlowConnectionRequest,
FlowStepDataCount,
FlowStepDataList,
MoveDataRequest,
MoveBatchDataRequest,
FlowAuditLog,
ApiResponse,
} from "@/types/flow";
const API_BASE = process.env.NEXT_PUBLIC_API_URL || "/api";
// ============================================
// 플로우 정의 API
// ============================================
/**
* 플로우 정의 목록 조회
*/
export async function getFlowDefinitions(params?: {
tableName?: string;
isActive?: boolean;
}): Promise<ApiResponse<FlowDefinition[]>> {
try {
const queryParams = new URLSearchParams();
if (params?.tableName) queryParams.append("tableName", params.tableName);
if (params?.isActive !== undefined) queryParams.append("isActive", String(params.isActive));
const url = `${API_BASE}/flow/definitions${queryParams.toString() ? `?${queryParams.toString()}` : ""}`;
const response = await fetch(url, {
credentials: "include",
});
return await response.json();
} catch (error: any) {
return {
success: false,
error: error.message,
};
}
}
/**
* 플로우 정의 상세 조회
*/
export async function getFlowDefinition(id: number): Promise<ApiResponse<FlowDefinition>> {
try {
const response = await fetch(`${API_BASE}/flow/definitions/${id}`, {
credentials: "include",
});
return await response.json();
} catch (error: any) {
return {
success: false,
error: error.message,
};
}
}
/**
* 플로우 정의 상세 조회 (별칭)
*/
export const getFlowById = getFlowDefinition;
/**
* 플로우 정의 생성
*/
export async function createFlowDefinition(data: CreateFlowDefinitionRequest): Promise<ApiResponse<FlowDefinition>> {
try {
const response = await fetch(`${API_BASE}/flow/definitions`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
credentials: "include",
body: JSON.stringify(data),
});
return await response.json();
} catch (error: any) {
return {
success: false,
error: error.message,
};
}
}
/**
* 플로우 정의 수정
*/
export async function updateFlowDefinition(
id: number,
data: UpdateFlowDefinitionRequest,
): Promise<ApiResponse<FlowDefinition>> {
try {
const response = await fetch(`${API_BASE}/flow/definitions/${id}`, {
method: "PUT",
headers: {
"Content-Type": "application/json",
},
credentials: "include",
body: JSON.stringify(data),
});
return await response.json();
} catch (error: any) {
return {
success: false,
error: error.message,
};
}
}
/**
* 플로우 정의 삭제
*/
export async function deleteFlowDefinition(id: number): Promise<ApiResponse<{ success: boolean }>> {
try {
const response = await fetch(`${API_BASE}/flow/definitions/${id}`, {
method: "DELETE",
credentials: "include",
});
return await response.json();
} catch (error: any) {
return {
success: false,
error: error.message,
};
}
}
// ============================================
// 플로우 단계 API
// ============================================
/**
* 플로우 단계 목록 조회
*/
export async function getFlowSteps(flowId: number): Promise<ApiResponse<FlowStep[]>> {
try {
const response = await fetch(`${API_BASE}/flow/definitions/${flowId}/steps`, {
credentials: "include",
});
return await response.json();
} catch (error: any) {
return {
success: false,
error: error.message,
};
}
}
/**
* 플로우 단계 생성
*/
export async function createFlowStep(flowId: number, data: CreateFlowStepRequest): Promise<ApiResponse<FlowStep>> {
try {
const response = await fetch(`${API_BASE}/flow/definitions/${flowId}/steps`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
credentials: "include",
body: JSON.stringify(data),
});
return await response.json();
} catch (error: any) {
return {
success: false,
error: error.message,
};
}
}
/**
* 플로우 단계 수정
*/
export async function updateFlowStep(stepId: number, data: UpdateFlowStepRequest): Promise<ApiResponse<FlowStep>> {
try {
const response = await fetch(`${API_BASE}/flow/steps/${stepId}`, {
method: "PUT",
headers: {
"Content-Type": "application/json",
},
credentials: "include",
body: JSON.stringify(data),
});
return await response.json();
} catch (error: any) {
return {
success: false,
error: error.message,
};
}
}
/**
* 플로우 단계 삭제
*/
export async function deleteFlowStep(stepId: number): Promise<ApiResponse<{ success: boolean }>> {
try {
const response = await fetch(`${API_BASE}/flow/steps/${stepId}`, {
method: "DELETE",
credentials: "include",
});
return await response.json();
} catch (error: any) {
return {
success: false,
error: error.message,
};
}
}
// ============================================
// 플로우 연결 API
// ============================================
/**
* 플로우 연결 목록 조회
*/
export async function getFlowConnections(flowId: number): Promise<ApiResponse<FlowStepConnection[]>> {
try {
const response = await fetch(`${API_BASE}/flow/connections/${flowId}`, {
credentials: "include",
});
return await response.json();
} catch (error: any) {
return {
success: false,
error: error.message,
};
}
}
/**
* 플로우 연결 생성
*/
export async function createFlowConnection(
data: CreateFlowConnectionRequest,
): Promise<ApiResponse<FlowStepConnection>> {
try {
const response = await fetch(`${API_BASE}/flow/connections`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
credentials: "include",
body: JSON.stringify(data),
});
return await response.json();
} catch (error: any) {
return {
success: false,
error: error.message,
};
}
}
/**
* 플로우 연결 삭제
*/
export async function deleteFlowConnection(connectionId: number): Promise<ApiResponse<{ success: boolean }>> {
try {
const response = await fetch(`${API_BASE}/flow/connections/${connectionId}`, {
method: "DELETE",
credentials: "include",
});
return await response.json();
} catch (error: any) {
return {
success: false,
error: error.message,
};
}
}
// ============================================
// 플로우 실행 API
// ============================================
/**
* 특정 단계의 데이터 카운트 조회
*/
export async function getStepDataCount(flowId: number, stepId: number): Promise<ApiResponse<FlowStepDataCount>> {
try {
const response = await fetch(`${API_BASE}/flow/${flowId}/step/${stepId}/count`, {
credentials: "include",
});
return await response.json();
} catch (error: any) {
return {
success: false,
error: error.message,
};
}
}
/**
* 특정 단계의 데이터 리스트 조회 (페이징)
*/
export async function getStepDataList(
flowId: number,
stepId: number,
page: number = 1,
pageSize: number = 20,
): Promise<ApiResponse<FlowStepDataList>> {
try {
const response = await fetch(`${API_BASE}/flow/${flowId}/step/${stepId}/list?page=${page}&pageSize=${pageSize}`, {
credentials: "include",
});
return await response.json();
} catch (error: any) {
return {
success: false,
error: error.message,
};
}
}
/**
* 모든 단계의 데이터 카운트 조회
*/
export async function getAllStepCounts(flowId: number): Promise<ApiResponse<FlowStepDataCount[]>> {
try {
const response = await fetch(`${API_BASE}/flow/${flowId}/steps/counts`, {
credentials: "include",
});
return await response.json();
} catch (error: any) {
return {
success: false,
error: error.message,
};
}
}
/**
* 데이터 이동
*/
export async function moveData(data: MoveDataRequest): Promise<ApiResponse<{ success: boolean }>> {
try {
const response = await fetch(`${API_BASE}/flow/move`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
credentials: "include",
body: JSON.stringify(data),
});
return await response.json();
} catch (error: any) {
return {
success: false,
error: error.message,
};
}
}
/**
* 데이터를 다음 스텝으로 이동 (편의 함수)
*/
export async function moveDataToNextStep(
flowId: number,
currentStepId: number,
dataId: number,
): Promise<ApiResponse<{ success: boolean }>> {
return moveData({
flowId,
currentStepId,
dataId,
});
}
/**
* 배치 데이터 이동
*/
export async function moveBatchData(
data: MoveBatchDataRequest,
): Promise<ApiResponse<{ success: boolean; results: any[] }>> {
try {
const response = await fetch(`${API_BASE}/flow/move/batch`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
credentials: "include",
body: JSON.stringify(data),
});
return await response.json();
} catch (error: any) {
return {
success: false,
error: error.message,
};
}
}
// ============================================
// 오딧 로그 API
// ============================================
/**
* 특정 레코드의 오딧 로그 조회
*/
export async function getAuditLogs(flowId: number, recordId: string): Promise<ApiResponse<FlowAuditLog[]>> {
try {
const response = await fetch(`${API_BASE}/flow/audit/${flowId}/${recordId}`, {
credentials: "include",
});
return await response.json();
} catch (error: any) {
return {
success: false,
error: error.message,
};
}
}
/**
* 플로우 전체 오딧 로그 조회
*/
export async function getFlowAuditLogs(flowId: number, limit: number = 100): Promise<ApiResponse<FlowAuditLog[]>> {
try {
const response = await fetch(`${API_BASE}/flow/audit/${flowId}?limit=${limit}`, {
credentials: "include",
});
return await response.json();
} catch (error: any) {
return {
success: false,
error: error.message,
};
}
}