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

528 lines
12 KiB
TypeScript
Raw Normal View History

2025-10-20 10:55:33 +09:00
/**
* API
*/
import {
FlowDefinition,
CreateFlowDefinitionRequest,
UpdateFlowDefinitionRequest,
FlowStep,
CreateFlowStepRequest,
UpdateFlowStepRequest,
FlowStepConnection,
CreateFlowConnectionRequest,
FlowStepDataCount,
FlowStepDataList,
MoveDataRequest,
MoveBatchDataRequest,
FlowAuditLog,
ApiResponse,
} from "@/types/flow";
2025-10-24 16:39:54 +09:00
// API URL 동적 설정
const getApiBaseUrl = (): string => {
// 1. 환경변수가 있으면 우선 사용
if (process.env.NEXT_PUBLIC_API_URL) {
return process.env.NEXT_PUBLIC_API_URL;
}
// 2. 클라이언트 사이드에서 동적 설정
if (typeof window !== "undefined") {
const currentHost = window.location.hostname;
// 프로덕션 환경: v1.vexplor.com → api.vexplor.com
if (currentHost === "v1.vexplor.com") {
return "https://api.vexplor.com/api";
}
// 로컬 개발환경
if (currentHost === "localhost" || currentHost === "127.0.0.1") {
return "http://localhost:8080/api";
}
}
// 3. 기본값
return "/api";
};
const API_BASE = getApiBaseUrl();
2025-10-20 10:55:33 +09:00
2025-10-21 14:21:29 +09:00
// 토큰 가져오기
function getAuthToken(): string | null {
if (typeof window === "undefined") return null;
return localStorage.getItem("authToken") || sessionStorage.getItem("authToken");
}
2025-10-27 16:40:59 +09:00
// 인증 헤더 생성 헬퍼
function getAuthHeaders(): HeadersInit {
const token = getAuthToken();
const headers: HeadersInit = {
"Content-Type": "application/json",
};
2025-10-27 16:40:59 +09:00
if (token) {
headers["Authorization"] = `Bearer ${token}`;
}
return headers;
}
2025-10-20 10:55:33 +09:00
// ============================================
// 플로우 정의 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, {
2025-10-27 16:40:59 +09:00
headers: getAuthHeaders(),
2025-10-20 10:55:33 +09:00
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}`, {
2025-10-27 16:40:59 +09:00
headers: getAuthHeaders(),
2025-10-20 10:55:33 +09:00
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",
2025-10-27 16:40:59 +09:00
headers: getAuthHeaders(),
2025-10-20 10:55:33 +09:00
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",
2025-10-27 16:40:59 +09:00
headers: getAuthHeaders(),
2025-10-20 10:55:33 +09:00
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",
2025-10-27 16:40:59 +09:00
headers: getAuthHeaders(),
2025-10-20 10:55:33 +09:00
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`, {
2025-10-27 16:40:59 +09:00
headers: getAuthHeaders(),
2025-10-20 10:55:33 +09:00
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",
2025-10-27 16:40:59 +09:00
headers: getAuthHeaders(),
2025-10-20 10:55:33 +09:00
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",
2025-10-27 16:40:59 +09:00
headers: getAuthHeaders(),
2025-10-20 10:55:33 +09:00
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",
2025-10-27 16:40:59 +09:00
headers: getAuthHeaders(),
2025-10-20 10:55:33 +09:00
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}`, {
2025-10-27 16:40:59 +09:00
headers: getAuthHeaders(),
2025-10-20 10:55:33 +09:00
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",
2025-10-27 16:40:59 +09:00
headers: getAuthHeaders(),
2025-10-20 10:55:33 +09:00
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",
2025-10-27 16:40:59 +09:00
headers: getAuthHeaders(),
2025-10-20 10:55:33 +09:00
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`, {
2025-10-27 16:40:59 +09:00
headers: getAuthHeaders(),
2025-10-20 10:55:33 +09:00
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}`, {
2025-10-27 16:40:59 +09:00
headers: getAuthHeaders(),
2025-10-20 10:55:33 +09:00
credentials: "include",
});
return await response.json();
} catch (error: any) {
return {
success: false,
error: error.message,
};
}
}
/**
*
*/
export async function getStepColumnLabels(
flowId: number,
stepId: number,
): Promise<ApiResponse<Record<string, string>>> {
try {
const response = await fetch(`${API_BASE}/flow/${flowId}/step/${stepId}/column-labels`, {
headers: getAuthHeaders(),
credentials: "include",
});
return await response.json();
} catch (error: any) {
return {
success: false,
error: error.message,
};
}
}
2025-10-20 10:55:33 +09:00
/**
*
*/
export async function getAllStepCounts(flowId: number): Promise<ApiResponse<FlowStepDataCount[]>> {
try {
const response = await fetch(`${API_BASE}/flow/${flowId}/steps/counts`, {
2025-10-27 16:40:59 +09:00
headers: getAuthHeaders(),
2025-10-20 10:55:33 +09:00
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",
2025-10-27 16:40:59 +09:00
headers: getAuthHeaders(),
2025-10-20 10:55:33 +09:00
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 {
2025-10-20 15:53:00 +09:00
const response = await fetch(`${API_BASE}/flow/move-batch`, {
2025-10-20 10:55:33 +09:00
method: "POST",
2025-10-27 16:40:59 +09:00
headers: getAuthHeaders(),
2025-10-20 10:55:33 +09:00
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}`, {
2025-10-27 16:40:59 +09:00
headers: getAuthHeaders(),
2025-10-20 10:55:33 +09:00
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}`, {
2025-10-27 16:40:59 +09:00
headers: getAuthHeaders(),
2025-10-20 10:55:33 +09:00
credentials: "include",
});
return await response.json();
} catch (error: any) {
return {
success: false,
error: error.message,
};
}
}