import { apiClient } from "./client"; // 관계명 중복 체크 export const checkRelationshipNameDuplicate = async (relationshipName: string, excludeDiagramId?: number) => { try { console.log(`🔍 관계명 중복 체크: "${relationshipName}", 제외 ID: ${excludeDiagramId}`); const response = await apiClient.get("/dataflow-diagrams", { params: { searchTerm: relationshipName, page: 1, size: 100, // 충분히 큰 수로 설정 }, }); if (!response.data.success) { throw new Error("관계명 중복 체크 실패"); } const diagrams = response.data.data.diagrams || []; // 정확히 일치하는 이름 찾기 (대소문자 구분) const duplicates = diagrams.filter( (diagram: any) => diagram.diagram_name === relationshipName && (!excludeDiagramId || diagram.diagram_id !== excludeDiagramId), ); console.log(`✅ 중복 체크 결과: ${duplicates.length}개 중복 발견`); return { isDuplicate: duplicates.length > 0, duplicateCount: duplicates.length, duplicateDiagrams: duplicates, }; } catch (error: any) { console.error("❌ 관계명 중복 체크 실패:", error); throw new Error("관계명 중복 체크 중 오류가 발생했습니다."); } }; /** * 저장된 dataflow diagram으로부터 관계 정보를 조회하여 DataConnectionDesigner에서 사용할 수 있는 형태로 변환 */ export const loadDataflowRelationship = async (diagramId: number) => { try { console.log(`📖 관계 정보 로드 시작: diagramId=${diagramId}`); // dataflow-diagrams API에서 해당 diagram 조회 const response = await apiClient.get(`/dataflow-diagrams/${diagramId}`); console.log("✅ diagram 조회 성공:", response.data); const diagram = response.data.data; if (!diagram || !diagram.relationships) { throw new Error("관계 정보를 찾을 수 없습니다."); } console.log("🔍 원본 diagram 구조:", diagram); console.log("🔍 relationships 구조:", diagram.relationships); console.log("🔍 relationships.relationships 구조:", diagram.relationships?.relationships); console.log("🔍 relationships.relationships 타입:", typeof diagram.relationships?.relationships); console.log("🔍 relationships.relationships 배열인가?:", Array.isArray(diagram.relationships?.relationships)); // 기존 구조와 redesigned 구조 모두 지원 let relationshipsData; // Case 1: Redesigned UI 구조 (단일 관계 객체) if (diagram.relationships.relationships && !Array.isArray(diagram.relationships.relationships)) { relationshipsData = diagram.relationships.relationships; console.log("✅ Redesigned 구조 감지:", relationshipsData); } // Case 2: 기존 구조 (관계 배열) - 첫 번째 관계만 로드 else if (diagram.relationships.relationships && Array.isArray(diagram.relationships.relationships)) { const firstRelation = diagram.relationships.relationships[0]; if (!firstRelation) { throw new Error("관계 데이터가 없습니다."); } console.log("🔄 기존 구조 감지, 변환 중:", firstRelation); // 기존 구조를 redesigned 구조로 변환 relationshipsData = { description: firstRelation.note || "", connectionType: firstRelation.connectionType || "data_save", fromConnection: { id: 0, name: "메인 데이터베이스 (현재 시스템)" }, // 기본값 toConnection: { id: 0, name: "메인 데이터베이스 (현재 시스템)" }, // 기본값 fromTable: firstRelation.fromTable, toTable: firstRelation.toTable, actionType: "insert", // 기본값 controlConditions: [], actionConditions: [], fieldMappings: [], }; // 기존 control 및 plan 데이터를 변환 if (diagram.control && diagram.control.length > 0) { const control = diagram.control.find((c) => c.id === firstRelation.id); if (control && control.conditions) { relationshipsData.controlConditions = control.conditions; } } if (diagram.plan && diagram.plan.length > 0) { const plan = diagram.plan.find((p) => p.id === firstRelation.id); if (plan && plan.actions && plan.actions.length > 0) { const firstAction = plan.actions[0]; relationshipsData.actionType = firstAction.actionType || "insert"; relationshipsData.fieldMappings = firstAction.fieldMappings || []; relationshipsData.actionConditions = firstAction.conditions || []; } } } // Case 3: 다른 구조들 처리 else if (diagram.relationships && typeof diagram.relationships === "object") { console.log("🔄 다른 구조 감지, relationships 전체를 확인 중:", diagram.relationships); // 현재 DB에 저장된 구조 처리 (relationships 객체에 모든 데이터가 있음) relationshipsData = { description: diagram.relationships.description || "", connectionType: diagram.relationships.connectionType || "data_save", fromConnection: diagram.relationships.fromConnection || { id: 0, name: "메인 데이터베이스 (현재 시스템)" }, toConnection: diagram.relationships.toConnection || { id: 0, name: "메인 데이터베이스 (현재 시스템)" }, fromTable: diagram.relationships.fromTable, toTable: diagram.relationships.toTable, actionType: diagram.relationships.actionType || "insert", controlConditions: diagram.relationships.controlConditions || [], actionConditions: diagram.relationships.actionConditions || [], fieldMappings: diagram.relationships.fieldMappings || [], // 🔧 멀티 액션 그룹 데이터 로드 actionGroups: diagram.relationships.actionGroups || null, }; console.log("✅ 현재 DB 구조 처리 완료:", relationshipsData); } else { throw new Error("관계 데이터가 없습니다."); } console.log("🔍 추출된 관계 데이터:", relationshipsData); // DataConnectionDesigner에서 사용하는 형태로 변환 const loadedData = { diagramId: diagram.diagram_id, // 🔧 수정 모드를 위한 diagramId 추가 relationshipName: diagram.diagram_name, description: relationshipsData.description || diagram.description || "", // 🔧 diagram.description도 확인 connectionType: relationshipsData.connectionType || "data_save", fromConnection: relationshipsData.fromConnection || { id: 0, name: "메인 데이터베이스 (현재 시스템)" }, toConnection: relationshipsData.toConnection || { id: 0, name: "메인 데이터베이스 (현재 시스템)" }, fromTable: relationshipsData.fromTable, toTable: relationshipsData.toTable, actionType: relationshipsData.actionType || "insert", controlConditions: relationshipsData.controlConditions || [], actionConditions: relationshipsData.actionConditions || [], fieldMappings: relationshipsData.fieldMappings || [], // 🔧 멀티 액션 그룹 데이터 포함 actionGroups: relationshipsData.actionGroups, }; console.log("✨ 변환된 로드 데이터:", loadedData); return loadedData; } catch (error: any) { console.error("❌ 관계 정보 로드 실패:", error); let errorMessage = "관계 정보를 불러오는 중 오류가 발생했습니다."; if (error.response?.status === 404) { errorMessage = "관계 정보를 찾을 수 없습니다."; } else if (error.response?.status === 401) { errorMessage = "인증이 필요합니다. 다시 로그인해주세요."; } else if (error.response?.data?.message) { errorMessage = error.response.data.message; } throw new Error(errorMessage); } }; export const saveDataflowRelationship = async (data: any, diagramId?: number) => { try { console.log("💾 데이터플로우 관계 저장:", { diagramId, isEdit: !!diagramId }); // dataflow-diagrams API 형식에 맞게 데이터 변환 const requestData = { diagram_name: data.relationshipName, relationships: { // 관계 정보를 relationships 형식으로 변환 connectionType: data.connectionType, actionType: data.actionType, fromConnection: data.fromConnection, toConnection: data.toConnection, fromTable: data.fromTable, toTable: data.toTable, fieldMappings: data.fieldMappings, controlConditions: data.controlConditions, actionConditions: data.actionConditions, description: data.description, // 🔧 멀티 액션 그룹 데이터 추가 actionGroups: data.actionGroups, }, category: { type: "data-connection", source: "redesigned-ui", }, control: { conditions: data.controlConditions, actionType: data.actionType, }, plan: { description: data.description, mappings: data.fieldMappings, }, }; console.log("📡 변환된 요청 데이터:", requestData); // 수정 모드인 경우 PUT, 신규 생성인 경우 POST const response = diagramId ? await apiClient.put(`/dataflow-diagrams/${diagramId}`, requestData) : await apiClient.post("/dataflow-diagrams", requestData); console.log("✅ dataflow-diagrams 저장 성공:", response.data); return response.data; } catch (error: any) { console.error("❌ 저장 실패:", error); // 구체적인 에러 메시지 제공 let errorMessage = "저장 중 오류가 발생했습니다."; if (error.response?.status === 404) { errorMessage = "API 엔드포인트를 찾을 수 없습니다. 백엔드 서비스를 확인해주세요."; } else if (error.response?.status === 401) { errorMessage = "인증이 필요합니다. 다시 로그인해주세요."; } else if (error.response?.data?.message) { errorMessage = error.response.data.message; } throw new Error(errorMessage); } };