Enhance batch management functionality by adding node flow execution support and improving batch configuration creation. Introduce new API endpoint for retrieving node flows and update existing batch services to handle execution types. Update frontend components to support new scheduling options and node flow selection.

This commit is contained in:
DDD1542
2026-03-19 15:07:07 +09:00
parent 7f781b0177
commit 43cf91e748
41 changed files with 4020 additions and 3155 deletions

View File

@@ -126,29 +126,41 @@ export class BatchManagementController {
*/
static async createBatchConfig(req: AuthenticatedRequest, res: Response) {
try {
const { batchName, description, cronSchedule, mappings, isActive } =
req.body;
const {
batchName, description, cronSchedule, mappings, isActive,
executionType, nodeFlowId, nodeFlowContext,
} = req.body;
const companyCode = req.user?.companyCode;
if (
!batchName ||
!cronSchedule ||
!mappings ||
!Array.isArray(mappings)
) {
if (!batchName || !cronSchedule) {
return res.status(400).json({
success: false,
message:
"필수 필드가 누락되었습니다. (batchName, cronSchedule, mappings)",
message: "필수 필드가 누락되었습니다. (batchName, cronSchedule)",
});
}
const batchConfig = await BatchService.createBatchConfig({
batchName,
description,
cronSchedule,
mappings,
isActive: isActive !== undefined ? isActive : true,
} as CreateBatchConfigRequest);
// 노드 플로우 타입은 매핑 없이 생성 가능
if (executionType !== "node_flow" && (!mappings || !Array.isArray(mappings))) {
return res.status(400).json({
success: false,
message: "매핑 타입은 mappings 배열이 필요합니다.",
});
}
const batchConfig = await BatchService.createBatchConfig(
{
batchName,
description,
cronSchedule,
mappings: mappings || [],
isActive: isActive === false || isActive === "N" ? "N" : "Y",
companyCode: companyCode || "",
executionType: executionType || "mapping",
nodeFlowId: nodeFlowId || null,
nodeFlowContext: nodeFlowContext || null,
} as CreateBatchConfigRequest,
req.user?.userId
);
return res.status(201).json({
success: true,
@@ -769,6 +781,55 @@ export class BatchManagementController {
}
}
/**
* 노드 플로우 목록 조회 (배치 설정에서 플로우 선택용)
* GET /api/batch-management/node-flows
*/
static async getNodeFlows(req: AuthenticatedRequest, res: Response) {
try {
const companyCode = req.user?.companyCode;
let flowQuery: string;
let flowParams: any[] = [];
if (companyCode === "*") {
flowQuery = `
SELECT flow_id, flow_name, flow_description AS description, company_code,
COALESCE(jsonb_array_length(
CASE WHEN flow_data IS NOT NULL AND flow_data::text != ''
THEN (flow_data::jsonb -> 'nodes')
ELSE '[]'::jsonb END
), 0) AS node_count
FROM node_flows
ORDER BY flow_name
`;
} else {
flowQuery = `
SELECT flow_id, flow_name, flow_description AS description, company_code,
COALESCE(jsonb_array_length(
CASE WHEN flow_data IS NOT NULL AND flow_data::text != ''
THEN (flow_data::jsonb -> 'nodes')
ELSE '[]'::jsonb END
), 0) AS node_count
FROM node_flows
WHERE company_code = $1
ORDER BY flow_name
`;
flowParams = [companyCode];
}
const result = await query(flowQuery, flowParams);
return res.json({ success: true, data: result });
} catch (error) {
console.error("노드 플로우 목록 조회 오류:", error);
return res.status(500).json({
success: false,
message: "노드 플로우 목록 조회 실패",
error: error instanceof Error ? error.message : "알 수 없는 오류",
});
}
}
/**
* 배치 대시보드 통계 조회
* GET /api/batch-management/stats