Merge remote-tracking branch 'upstream/main'
All checks were successful
Build and Push Images / build-and-push (push) Successful in 11m44s

This commit is contained in:
kjs
2025-12-31 10:57:23 +09:00
4 changed files with 248 additions and 5 deletions

View File

@@ -214,6 +214,73 @@ router.delete("/:flowId", async (req: Request, res: Response) => {
}
});
/**
* 플로우 소스 테이블 조회
* GET /api/dataflow/node-flows/:flowId/source-table
* 플로우의 첫 번째 소스 노드(tableSource, externalDBSource)에서 테이블명 추출
*/
router.get("/:flowId/source-table", async (req: Request, res: Response) => {
try {
const { flowId } = req.params;
const flow = await queryOne<{ flow_data: any }>(
`SELECT flow_data FROM node_flows WHERE flow_id = $1`,
[flowId]
);
if (!flow) {
return res.status(404).json({
success: false,
message: "플로우를 찾을 수 없습니다.",
});
}
const flowData =
typeof flow.flow_data === "string"
? JSON.parse(flow.flow_data)
: flow.flow_data;
const nodes = flowData.nodes || [];
// 소스 노드 찾기 (tableSource, externalDBSource 타입)
const sourceNode = nodes.find(
(node: any) =>
node.type === "tableSource" || node.type === "externalDBSource"
);
if (!sourceNode || !sourceNode.data?.tableName) {
return res.json({
success: true,
data: {
sourceTable: null,
sourceNodeType: null,
message: "소스 노드가 없거나 테이블명이 설정되지 않았습니다.",
},
});
}
logger.info(
`플로우 소스 테이블 조회: flowId=${flowId}, table=${sourceNode.data.tableName}`
);
return res.json({
success: true,
data: {
sourceTable: sourceNode.data.tableName,
sourceNodeType: sourceNode.type,
sourceNodeId: sourceNode.id,
displayName: sourceNode.data.displayName,
},
});
} catch (error) {
logger.error("플로우 소스 테이블 조회 실패:", error);
return res.status(500).json({
success: false,
message: "플로우 소스 테이블을 조회하지 못했습니다.",
});
}
});
/**
* 플로우 실행
* POST /api/dataflow/node-flows/:flowId/execute