# 노드 구조 개선안 - FROM/TO 테이블 명확화 **작성일**: 2025-01-02 **버전**: 1.0 **상태**: 🤔 검토 중 --- ## 📋 문제 인식 ### 현재 설계의 한계 ``` 현재 플로우: TableSource(user_info) → FieldMapping → InsertAction(targetTable: "orders") ``` **문제점**: 1. 타겟 테이블(orders)이 노드로 표현되지 않음 2. InsertAction의 속성으로만 존재 → 시각적으로 불명확 3. FROM(user_info)과 TO(orders)의 관계가 직관적이지 않음 4. 타겟 테이블의 스키마 정보를 참조하기 어려움 --- ## 💡 개선 방안 ### 옵션 1: TableTarget 노드 추가 (권장 ⭐) **새로운 플로우**: ``` TableSource(user_info) → FieldMapping → TableTarget(orders) → InsertAction ``` **노드 추가**: - `TableTarget` - 타겟 테이블을 명시적으로 표현 **장점**: - ✅ FROM/TO가 시각적으로 명확 - ✅ 타겟 테이블 스키마를 미리 로드 가능 - ✅ FieldMapping에서 타겟 필드 자동 완성 가능 - ✅ 데이터 흐름이 직관적 **단점**: - ⚠️ 노드 개수 증가 (복잡도 증가) - ⚠️ 기존 설계와 호환성 문제 --- ### 옵션 2: Action 노드에 Target 속성 유지 (현재 방식) **현재 플로우 유지**: ``` TableSource(user_info) → FieldMapping → InsertAction(targetTable: "orders") ``` **개선 방법**: - Action 노드에서 타겟 테이블을 더 명확히 표시 - 노드 UI에 타겟 테이블명을 크게 표시 - Properties Panel에서 타겟 테이블 선택 시 스키마 정보 제공 **장점**: - ✅ 기존 설계 유지 (구현 완료된 상태) - ✅ 노드 개수가 적음 (간결함) - ✅ 빠른 플로우 구성 가능 **단점**: - ❌ 시각적으로 FROM/TO 관계가 불명확 - ❌ FieldMapping 단계에서 타겟 필드 정보 접근이 어려움 --- ### 옵션 3: 가상 노드 자동 표시 (신규 제안 ⭐⭐) **개념**: Action 노드에서 targetTable 속성을 설정하면, **시각적으로만** 타겟 테이블 노드를 자동 생성 **실제 플로우 (저장되는 구조)**: ``` TableSource(user_info) → FieldMapping → InsertAction(targetTable: "orders") ``` **시각적 표시 (화면에 보이는 모습)**: ``` TableSource(user_info) → FieldMapping → InsertAction(targetTable: "orders") → 👻 orders (가상 노드, 자동 생성) ``` **특징**: - 가상 노드는 선택/이동/삭제 불가능 - 반투명하게 표시하여 가상임을 명확히 표시 - Action 노드의 targetTable 속성 변경 시 자동 업데이트 - 저장 시에는 가상 노드 제외 **장점**: - ✅ 사용자는 기존대로 사용 (노드 추가 불필요) - ✅ 시각적으로 FROM/TO 관계 명확 - ✅ 기존 설계 100% 유지 - ✅ 구현 복잡도 낮음 - ✅ 기존 플로우와 완벽 호환 **단점**: - ⚠️ 가상 노드의 상호작용 제한 필요 - ⚠️ "왜 클릭이 안 되지?" 혼란 가능성 - ⚠️ 가상 노드 렌더링 로직 추가 --- ### 옵션 4: 하이브리드 방식 **조건부 사용**: ``` // 단순 케이스: TableTarget 생략 TableSource → FieldMapping → InsertAction(targetTable 지정) // 복잡한 케이스: TableTarget 사용 TableSource → FieldMapping → TableTarget → InsertAction ``` **장점**: - ✅ 유연성 제공 - ✅ 단순/복잡한 케이스 모두 대응 **단점**: - ❌ 사용자 혼란 가능성 - ❌ 검증 로직 복잡 --- ## 🎯 권장 방안 비교 ### 옵션 재평가 | 항목 | 옵션 1
(TableTarget) | 옵션 2
(현재 방식) | 옵션 3
(가상 노드) ⭐ | | ----------------- | ------------------------ | ---------------------- | ------------------------- | | **시각적 명확성** | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | | **구현 복잡도** | ⭐⭐⭐⭐ | ⭐⭐ | ⭐⭐⭐ | | **사용자 편의성** | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | | **기존 호환성** | ⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | | **자동 완성** | ⭐⭐⭐⭐⭐ | ⭐⭐ | ⭐⭐⭐ | | **유지보수성** | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐ | | **학습 곡선** | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ### 최종 권장: **옵션 3 (가상 노드 자동 표시)** ⭐⭐ **선택 이유**: 1. ✅ **최고의 시각적 명확성** - FROM/TO 관계가 한눈에 보임 2. ✅ **사용자 편의성** - 기존 방식 그대로, 노드 추가 불필요 3. ✅ **완벽한 호환성** - 기존 플로우 수정 불필요 4. ✅ **낮은 학습 곡선** - 새로운 노드 타입 학습 불필요 5. ✅ **적절한 구현 복잡도** - React Flow의 커스텀 렌더링 활용 **구현 방식**: ```typescript // Action 노드가 있으면 자동으로 가상 타겟 노드 생성 function generateVirtualTargetNodes(nodes: FlowNode[]): VirtualNode[] { return nodes .filter((node) => isActionNode(node.type) && node.data.targetTable) .map((actionNode) => ({ id: `virtual-target-${actionNode.id}`, type: "virtualTarget", position: { x: actionNode.position.x, y: actionNode.position.y + 150, }, data: { tableName: actionNode.data.targetTable, sourceActionId: actionNode.id, isVirtual: true, }, })); } ``` --- ## 🎯 대안: 옵션 1 (TableTarget 추가) ### 새로운 노드 타입 추가 #### TableTarget 노드 **타입**: `tableTarget` **데이터 구조**: ```typescript interface TableTargetNodeData { tableName: string; // 타겟 테이블명 schema?: string; // 스키마 (선택) columns?: Array<{ // 타겟 컬럼 정보 name: string; type: string; nullable: boolean; primaryKey: boolean; }>; displayName?: string; } ``` **특징**: - 입력: FieldMapping, DataTransform 등에서 받음 - 출력: Action 노드로 전달 - 타겟 테이블 스키마를 미리 로드하여 검증 가능 **시각적 표현**: ``` ┌────────────────────┐ │ 📊 Table Target │ ├────────────────────┤ │ orders │ │ schema: public │ ├────────────────────┤ │ 컬럼: │ │ • order_id (PK) │ │ • customer_id │ │ • order_date │ │ • total_amount │ └────────────────────┘ ``` --- ### 개선된 연결 규칙 #### TableTarget 추가 시 연결 규칙 **허용되는 연결**: ``` ✅ FieldMapping → TableTarget ✅ DataTransform → TableTarget ✅ Condition → TableTarget ✅ TableTarget → InsertAction ✅ TableTarget → UpdateAction ✅ TableTarget → UpsertAction ``` **금지되는 연결**: ``` ❌ TableSource → TableTarget (직접 연결 불가) ❌ TableTarget → DeleteAction (DELETE는 타겟 불필요) ❌ TableTarget → TableTarget ``` **새로운 검증 규칙**: 1. Action 노드는 TableTarget 또는 targetTable 속성 중 하나 필수 2. TableTarget이 있으면 Action의 targetTable 속성 무시 3. FieldMapping 이후에 TableTarget이 오면 자동 필드 매칭 제안 --- ### 실제 사용 예시 #### 예시 1: 단순 데이터 복사 **기존 방식**: ``` TableSource(user_info) → FieldMapping(user_id → customer_id, user_name → name) → InsertAction(targetTable: "customers") ``` **개선 방식**: ``` TableSource(user_info) → FieldMapping(user_id → customer_id) → TableTarget(customers) → InsertAction ``` **장점**: - customers 테이블 스키마를 FieldMapping에서 참조 가능 - 필드 자동 완성 제공 --- #### 예시 2: 조건부 데이터 처리 **개선 방식**: ``` TableSource(user_info) → Condition(age >= 18) ├─ TRUE → TableTarget(adult_users) → InsertAction └─ FALSE → TableTarget(minor_users) → InsertAction ``` **장점**: - TRUE/FALSE 분기마다 다른 타겟 테이블 명확히 표시 --- #### 예시 3: 멀티 소스 + 단일 타겟 **개선 방식**: ``` ┌─ TableSource(users) ────┐ │ ↓ └─ ExternalDB(orders) ─→ FieldMapping → TableTarget(user_orders) → InsertAction ``` **장점**: - 여러 소스에서 데이터를 받아 하나의 타겟으로 통합 - 타겟 테이블이 시각적으로 명확 --- ## 🔧 구현 계획 ### Phase 1: TableTarget 노드 구현 **작업 항목**: 1. ✅ `TableTargetNodeData` 인터페이스 정의 2. ✅ `TableTargetNode.tsx` 컴포넌트 생성 3. ✅ `TableTargetProperties.tsx` 속성 패널 생성 4. ✅ Node Palette에 추가 5. ✅ FlowEditor에 등록 **예상 시간**: 2시간 --- ### Phase 2: 연결 규칙 업데이트 **작업 항목**: 1. ✅ `validateConnection`에 TableTarget 규칙 추가 2. ✅ Action 노드가 TableTarget 입력을 받도록 수정 3. ✅ 검증 로직 업데이트 **예상 시간**: 1시간 --- ### Phase 3: 자동 필드 매핑 개선 **작업 항목**: 1. ✅ TableTarget이 연결되면 타겟 스키마 자동 로드 2. ✅ FieldMapping에서 타겟 필드 자동 완성 제공 3. ✅ 필드 타입 호환성 검증 **예상 시간**: 2시간 --- ### Phase 4: 기존 플로우 마이그레이션 **작업 항목**: 1. ✅ 기존 InsertAction의 targetTable을 TableTarget으로 변환 2. ✅ 자동 마이그레이션 스크립트 작성 3. ✅ 호환성 유지 모드 제공 **예상 시간**: 2시간 --- ## 🤔 고려사항 ### 1. 기존 플로우와의 호환성 **문제**: 이미 저장된 플로우는 TableTarget 없이 구성됨 **해결 방안**: - **옵션 A**: 자동 마이그레이션 - 플로우 로드 시 InsertAction의 targetTable을 TableTarget 노드로 변환 - 기존 데이터는 보존 - **옵션 B**: 호환성 모드 - TableTarget 없이도 동작하도록 유지 - 새 플로우만 TableTarget 사용 권장 **권장**: 옵션 B (호환성 모드) --- ### 2. 사용자 경험 **우려**: 노드가 하나 더 추가되어 복잡해짐 **완화 방안**: - 템플릿 제공: "TableSource → FieldMapping → TableTarget → InsertAction" 세트를 템플릿으로 제공 - 자동 생성: InsertAction 생성 시 TableTarget 자동 생성 옵션 - 가이드: 처음 사용자를 위한 튜토리얼 --- ### 3. 성능 **우려**: TableTarget이 스키마를 로드하면 성능 저하 가능성 **완화 방안**: - 캐싱: 한 번 로드한 스키마는 캐싱 - 지연 로딩: 필요할 때만 스키마 로드 - 백그라운드 로딩: 비동기로 스키마 로드 --- ## 📊 비교 분석 | 항목 | 옵션 1 (TableTarget) | 옵션 2 (현재 방식) | | ------------------- | -------------------- | ------------------ | | **시각적 명확성** | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | | **구현 복잡도** | ⭐⭐⭐⭐ | ⭐⭐ | | **사용자 학습곡선** | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | | **자동 완성 지원** | ⭐⭐⭐⭐⭐ | ⭐⭐ | | **유지보수성** | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | | **기존 호환성** | ⭐⭐ | ⭐⭐⭐⭐⭐ | --- ## 🎯 결론 ### 권장 사항: **옵션 1 (TableTarget 추가)** **이유**: 1. ✅ 데이터 흐름이 시각적으로 명확 2. ✅ 스키마 기반 자동 완성 가능 3. ✅ 향후 확장성 우수 4. ✅ 복잡한 데이터 흐름에서 특히 유용 **단계적 도입**: - Phase 1: TableTarget 노드 추가 (선택 사항) - Phase 2: 기존 방식과 공존 - Phase 3: 사용자 피드백 수집 - Phase 4: 장기적으로 TableTarget 방식 권장 --- ## 📝 다음 단계 1. **의사 결정**: 옵션 1 vs 옵션 2 선택 2. **프로토타입**: TableTarget 노드 간단히 구현 3. **테스트**: 실제 사용 시나리오로 검증 4. **문서화**: 사용 가이드 작성 5. **배포**: 단계적 릴리스 --- **피드백 환영**: 이 설계에 대한 의견을 주시면 개선하겠습니다! 💬