feat: 노드 기반 데이터 플로우 시스템 구현
- 노드 에디터 UI 구현 (React Flow 기반)
- TableSource, DataTransform, INSERT, UPDATE, DELETE, UPSERT 노드
- 드래그앤드롭 노드 추가 및 연결
- 속성 패널을 통한 노드 설정
- 실시간 필드 라벨 표시 (column_labels 테이블 연동)
- 데이터 변환 노드 (DataTransform) 기능
- EXPLODE: 구분자로 1개 행 → 여러 행 확장
- UPPERCASE, LOWERCASE, TRIM, CONCAT, SPLIT, REPLACE 등 12가지 변환 타입
- In-place 변환 지원 (타겟 필드 생략 시 소스 필드 덮어쓰기)
- 변환된 필드가 하위 액션 노드에 자동 전달
- 노드 플로우 실행 엔진
- 위상 정렬을 통한 노드 실행 순서 결정
- 레벨별 병렬 실행 (Promise.allSettled)
- 부분 실패 허용 (한 노드 실패 시 연결된 하위 노드만 스킵)
- 트랜잭션 기반 안전한 데이터 처리
- UPSERT 액션 로직 구현
- DB 제약 조건 없이 SELECT → UPDATE or INSERT 방식
- 복합 충돌 키 지원 (예: sales_no + product_name)
- 파라미터 인덱스 정확한 매핑
- 데이터 소스 자동 감지
- 테이블 선택 데이터 (selectedRowsData) 자동 주입
- 폼 입력 데이터 (formData) 자동 주입
- TableSource 노드가 외부 데이터 우선 사용
- 버튼 컴포넌트 통합
- 기존 관계 실행 + 새 노드 플로우 실행 하이브리드 지원
- 노드 플로우 선택 UI 추가
- API 클라이언트 통합 (Axios)
- 개발 문서 작성
- 노드 기반 제어 시스템 개선 계획
- 노드 연결 규칙 설계
- 노드 실행 엔진 설계
- 노드 구조 개선안
- 버튼 통합 분석
2025-10-02 16:22:29 +09:00
"use client" ;
/ * *
* 조 건 분 기 노 드 속 성 편 집
* /
2026-01-07 09:55:19 +09:00
import { useEffect , useState , useCallback } from "react" ;
import { Plus , Trash2 , Database , Search , Check , ChevronsUpDown } from "lucide-react" ;
feat: 노드 기반 데이터 플로우 시스템 구현
- 노드 에디터 UI 구현 (React Flow 기반)
- TableSource, DataTransform, INSERT, UPDATE, DELETE, UPSERT 노드
- 드래그앤드롭 노드 추가 및 연결
- 속성 패널을 통한 노드 설정
- 실시간 필드 라벨 표시 (column_labels 테이블 연동)
- 데이터 변환 노드 (DataTransform) 기능
- EXPLODE: 구분자로 1개 행 → 여러 행 확장
- UPPERCASE, LOWERCASE, TRIM, CONCAT, SPLIT, REPLACE 등 12가지 변환 타입
- In-place 변환 지원 (타겟 필드 생략 시 소스 필드 덮어쓰기)
- 변환된 필드가 하위 액션 노드에 자동 전달
- 노드 플로우 실행 엔진
- 위상 정렬을 통한 노드 실행 순서 결정
- 레벨별 병렬 실행 (Promise.allSettled)
- 부분 실패 허용 (한 노드 실패 시 연결된 하위 노드만 스킵)
- 트랜잭션 기반 안전한 데이터 처리
- UPSERT 액션 로직 구현
- DB 제약 조건 없이 SELECT → UPDATE or INSERT 방식
- 복합 충돌 키 지원 (예: sales_no + product_name)
- 파라미터 인덱스 정확한 매핑
- 데이터 소스 자동 감지
- 테이블 선택 데이터 (selectedRowsData) 자동 주입
- 폼 입력 데이터 (formData) 자동 주입
- TableSource 노드가 외부 데이터 우선 사용
- 버튼 컴포넌트 통합
- 기존 관계 실행 + 새 노드 플로우 실행 하이브리드 지원
- 노드 플로우 선택 UI 추가
- API 클라이언트 통합 (Axios)
- 개발 문서 작성
- 노드 기반 제어 시스템 개선 계획
- 노드 연결 규칙 설계
- 노드 실행 엔진 설계
- 노드 구조 개선안
- 버튼 통합 분석
2025-10-02 16:22:29 +09:00
import { Label } from "@/components/ui/label" ;
import { Input } from "@/components/ui/input" ;
import { Button } from "@/components/ui/button" ;
import { Select , SelectContent , SelectItem , SelectTrigger , SelectValue } from "@/components/ui/select" ;
2026-01-07 09:55:19 +09:00
import { Command , CommandEmpty , CommandGroup , CommandInput , CommandItem , CommandList } from "@/components/ui/command" ;
import { Popover , PopoverContent , PopoverTrigger } from "@/components/ui/popover" ;
feat: 노드 기반 데이터 플로우 시스템 구현
- 노드 에디터 UI 구현 (React Flow 기반)
- TableSource, DataTransform, INSERT, UPDATE, DELETE, UPSERT 노드
- 드래그앤드롭 노드 추가 및 연결
- 속성 패널을 통한 노드 설정
- 실시간 필드 라벨 표시 (column_labels 테이블 연동)
- 데이터 변환 노드 (DataTransform) 기능
- EXPLODE: 구분자로 1개 행 → 여러 행 확장
- UPPERCASE, LOWERCASE, TRIM, CONCAT, SPLIT, REPLACE 등 12가지 변환 타입
- In-place 변환 지원 (타겟 필드 생략 시 소스 필드 덮어쓰기)
- 변환된 필드가 하위 액션 노드에 자동 전달
- 노드 플로우 실행 엔진
- 위상 정렬을 통한 노드 실행 순서 결정
- 레벨별 병렬 실행 (Promise.allSettled)
- 부분 실패 허용 (한 노드 실패 시 연결된 하위 노드만 스킵)
- 트랜잭션 기반 안전한 데이터 처리
- UPSERT 액션 로직 구현
- DB 제약 조건 없이 SELECT → UPDATE or INSERT 방식
- 복합 충돌 키 지원 (예: sales_no + product_name)
- 파라미터 인덱스 정확한 매핑
- 데이터 소스 자동 감지
- 테이블 선택 데이터 (selectedRowsData) 자동 주입
- 폼 입력 데이터 (formData) 자동 주입
- TableSource 노드가 외부 데이터 우선 사용
- 버튼 컴포넌트 통합
- 기존 관계 실행 + 새 노드 플로우 실행 하이브리드 지원
- 노드 플로우 선택 UI 추가
- API 클라이언트 통합 (Axios)
- 개발 문서 작성
- 노드 기반 제어 시스템 개선 계획
- 노드 연결 규칙 설계
- 노드 실행 엔진 설계
- 노드 구조 개선안
- 버튼 통합 분석
2025-10-02 16:22:29 +09:00
import { useFlowEditorStore } from "@/lib/stores/flowEditorStore" ;
2026-01-07 09:55:19 +09:00
import type { ConditionNodeData , ConditionOperator } from "@/types/node-editor" ;
import { tableManagementApi } from "@/lib/api/tableManagement" ;
import { cn } from "@/lib/utils" ;
feat: 노드 기반 데이터 플로우 시스템 구현
- 노드 에디터 UI 구현 (React Flow 기반)
- TableSource, DataTransform, INSERT, UPDATE, DELETE, UPSERT 노드
- 드래그앤드롭 노드 추가 및 연결
- 속성 패널을 통한 노드 설정
- 실시간 필드 라벨 표시 (column_labels 테이블 연동)
- 데이터 변환 노드 (DataTransform) 기능
- EXPLODE: 구분자로 1개 행 → 여러 행 확장
- UPPERCASE, LOWERCASE, TRIM, CONCAT, SPLIT, REPLACE 등 12가지 변환 타입
- In-place 변환 지원 (타겟 필드 생략 시 소스 필드 덮어쓰기)
- 변환된 필드가 하위 액션 노드에 자동 전달
- 노드 플로우 실행 엔진
- 위상 정렬을 통한 노드 실행 순서 결정
- 레벨별 병렬 실행 (Promise.allSettled)
- 부분 실패 허용 (한 노드 실패 시 연결된 하위 노드만 스킵)
- 트랜잭션 기반 안전한 데이터 처리
- UPSERT 액션 로직 구현
- DB 제약 조건 없이 SELECT → UPDATE or INSERT 방식
- 복합 충돌 키 지원 (예: sales_no + product_name)
- 파라미터 인덱스 정확한 매핑
- 데이터 소스 자동 감지
- 테이블 선택 데이터 (selectedRowsData) 자동 주입
- 폼 입력 데이터 (formData) 자동 주입
- TableSource 노드가 외부 데이터 우선 사용
- 버튼 컴포넌트 통합
- 기존 관계 실행 + 새 노드 플로우 실행 하이브리드 지원
- 노드 플로우 선택 UI 추가
- API 클라이언트 통합 (Axios)
- 개발 문서 작성
- 노드 기반 제어 시스템 개선 계획
- 노드 연결 규칙 설계
- 노드 실행 엔진 설계
- 노드 구조 개선안
- 버튼 통합 분석
2025-10-02 16:22:29 +09:00
2025-10-08 09:39:13 +09:00
// 필드 정의
interface FieldDefinition {
name : string ;
label? : string ;
type ? : string ;
}
2026-01-07 09:55:19 +09:00
// 테이블 정보
interface TableInfo {
tableName : string ;
tableLabel : string ;
}
// 테이블 컬럼 정보
interface ColumnInfo {
columnName : string ;
columnLabel : string ;
dataType : string ;
}
feat: 노드 기반 데이터 플로우 시스템 구현
- 노드 에디터 UI 구현 (React Flow 기반)
- TableSource, DataTransform, INSERT, UPDATE, DELETE, UPSERT 노드
- 드래그앤드롭 노드 추가 및 연결
- 속성 패널을 통한 노드 설정
- 실시간 필드 라벨 표시 (column_labels 테이블 연동)
- 데이터 변환 노드 (DataTransform) 기능
- EXPLODE: 구분자로 1개 행 → 여러 행 확장
- UPPERCASE, LOWERCASE, TRIM, CONCAT, SPLIT, REPLACE 등 12가지 변환 타입
- In-place 변환 지원 (타겟 필드 생략 시 소스 필드 덮어쓰기)
- 변환된 필드가 하위 액션 노드에 자동 전달
- 노드 플로우 실행 엔진
- 위상 정렬을 통한 노드 실행 순서 결정
- 레벨별 병렬 실행 (Promise.allSettled)
- 부분 실패 허용 (한 노드 실패 시 연결된 하위 노드만 스킵)
- 트랜잭션 기반 안전한 데이터 처리
- UPSERT 액션 로직 구현
- DB 제약 조건 없이 SELECT → UPDATE or INSERT 방식
- 복합 충돌 키 지원 (예: sales_no + product_name)
- 파라미터 인덱스 정확한 매핑
- 데이터 소스 자동 감지
- 테이블 선택 데이터 (selectedRowsData) 자동 주입
- 폼 입력 데이터 (formData) 자동 주입
- TableSource 노드가 외부 데이터 우선 사용
- 버튼 컴포넌트 통합
- 기존 관계 실행 + 새 노드 플로우 실행 하이브리드 지원
- 노드 플로우 선택 UI 추가
- API 클라이언트 통합 (Axios)
- 개발 문서 작성
- 노드 기반 제어 시스템 개선 계획
- 노드 연결 규칙 설계
- 노드 실행 엔진 설계
- 노드 구조 개선안
- 버튼 통합 분석
2025-10-02 16:22:29 +09:00
interface ConditionPropertiesProps {
nodeId : string ;
data : ConditionNodeData ;
}
const OPERATORS = [
{ value : "EQUALS" , label : "같음 (=)" } ,
{ value : "NOT_EQUALS" , label : "같지 않음 (≠)" } ,
{ value : "GREATER_THAN" , label : "보다 큼 (>)" } ,
{ value : "LESS_THAN" , label : "보다 작음 (<)" } ,
{ value : "GREATER_THAN_OR_EQUAL" , label : "크거나 같음 (≥)" } ,
{ value : "LESS_THAN_OR_EQUAL" , label : "작거나 같음 (≤)" } ,
{ value : "LIKE" , label : "포함 (LIKE)" } ,
{ value : "NOT_LIKE" , label : "미포함 (NOT LIKE)" } ,
{ value : "IN" , label : "IN" } ,
{ value : "NOT_IN" , label : "NOT IN" } ,
{ value : "IS_NULL" , label : "NULL" } ,
{ value : "IS_NOT_NULL" , label : "NOT NULL" } ,
2026-01-07 09:55:19 +09:00
{ value : "EXISTS_IN" , label : "다른 테이블에 존재함" } ,
{ value : "NOT_EXISTS_IN" , label : "다른 테이블에 존재하지 않음" } ,
feat: 노드 기반 데이터 플로우 시스템 구현
- 노드 에디터 UI 구현 (React Flow 기반)
- TableSource, DataTransform, INSERT, UPDATE, DELETE, UPSERT 노드
- 드래그앤드롭 노드 추가 및 연결
- 속성 패널을 통한 노드 설정
- 실시간 필드 라벨 표시 (column_labels 테이블 연동)
- 데이터 변환 노드 (DataTransform) 기능
- EXPLODE: 구분자로 1개 행 → 여러 행 확장
- UPPERCASE, LOWERCASE, TRIM, CONCAT, SPLIT, REPLACE 등 12가지 변환 타입
- In-place 변환 지원 (타겟 필드 생략 시 소스 필드 덮어쓰기)
- 변환된 필드가 하위 액션 노드에 자동 전달
- 노드 플로우 실행 엔진
- 위상 정렬을 통한 노드 실행 순서 결정
- 레벨별 병렬 실행 (Promise.allSettled)
- 부분 실패 허용 (한 노드 실패 시 연결된 하위 노드만 스킵)
- 트랜잭션 기반 안전한 데이터 처리
- UPSERT 액션 로직 구현
- DB 제약 조건 없이 SELECT → UPDATE or INSERT 방식
- 복합 충돌 키 지원 (예: sales_no + product_name)
- 파라미터 인덱스 정확한 매핑
- 데이터 소스 자동 감지
- 테이블 선택 데이터 (selectedRowsData) 자동 주입
- 폼 입력 데이터 (formData) 자동 주입
- TableSource 노드가 외부 데이터 우선 사용
- 버튼 컴포넌트 통합
- 기존 관계 실행 + 새 노드 플로우 실행 하이브리드 지원
- 노드 플로우 선택 UI 추가
- API 클라이언트 통합 (Axios)
- 개발 문서 작성
- 노드 기반 제어 시스템 개선 계획
- 노드 연결 규칙 설계
- 노드 실행 엔진 설계
- 노드 구조 개선안
- 버튼 통합 분석
2025-10-02 16:22:29 +09:00
] as const ;
2026-01-07 09:55:19 +09:00
// EXISTS 계열 연산자인지 확인
const isExistsOperator = ( operator : string ) : boolean = > {
return operator === "EXISTS_IN" || operator === "NOT_EXISTS_IN" ;
} ;
// 테이블 선택용 검색 가능한 Combobox
function TableCombobox ( {
tables ,
value ,
onSelect ,
placeholder = "테이블 검색..." ,
} : {
tables : TableInfo [ ] ;
value : string ;
onSelect : ( value : string ) = > void ;
placeholder? : string ;
} ) {
const [ open , setOpen ] = useState ( false ) ;
const selectedTable = tables . find ( ( t ) = > t . tableName === value ) ;
return (
< Popover open = { open } onOpenChange = { setOpen } >
< PopoverTrigger asChild >
< Button
variant = "outline"
role = "combobox"
aria - expanded = { open }
className = "mt-1 h-8 w-full justify-between text-xs"
>
{ selectedTable ? (
< span className = "truncate" >
{ selectedTable . tableLabel }
< span className = "ml-1 text-gray-400" > ( { selectedTable . tableName } ) < / span >
< / span >
) : (
< span className = "text-muted-foreground" > 테 이 블 선 택 < / span >
) }
< ChevronsUpDown className = "ml-2 h-3 w-3 shrink-0 opacity-50" / >
< / Button >
< / PopoverTrigger >
< PopoverContent className = "w-[300px] p-0" align = "start" >
< Command >
< CommandInput placeholder = { placeholder } className = "h-8 text-xs" / >
< CommandList >
< CommandEmpty className = "py-2 text-center text-xs" > 테 이 블 을 찾 을 수 없 습 니 다 . < / CommandEmpty >
< CommandGroup className = "max-h-[200px] overflow-y-auto" >
{ tables . map ( ( table ) = > (
< CommandItem
key = { table . tableName }
value = { ` ${ table . tableLabel } ${ table . tableName } ` }
onSelect = { ( ) = > {
onSelect ( table . tableName ) ;
setOpen ( false ) ;
} }
className = "text-xs"
>
< Check className = { cn ( "mr-2 h-3 w-3" , value === table . tableName ? "opacity-100" : "opacity-0" ) } / >
< div className = "flex flex-col" >
< span className = "font-medium" > { table . tableLabel } < / span >
< span className = "text-[10px] text-gray-500" > { table . tableName } < / span >
< / div >
< / CommandItem >
) ) }
< / CommandGroup >
< / CommandList >
< / Command >
< / PopoverContent >
< / Popover >
) ;
}
// 컬럼 선택용 검색 가능한 Combobox
function ColumnCombobox ( {
columns ,
value ,
onSelect ,
placeholder = "컬럼 검색..." ,
} : {
columns : ColumnInfo [ ] ;
value : string ;
onSelect : ( value : string ) = > void ;
placeholder? : string ;
} ) {
const [ open , setOpen ] = useState ( false ) ;
const selectedColumn = columns . find ( ( c ) = > c . columnName === value ) ;
return (
< Popover open = { open } onOpenChange = { setOpen } >
< PopoverTrigger asChild >
< Button
variant = "outline"
role = "combobox"
aria - expanded = { open }
className = "mt-1 h-8 w-full justify-between text-xs"
>
{ selectedColumn ? (
< span className = "truncate" >
{ selectedColumn . columnLabel }
< span className = "ml-1 text-gray-400" > ( { selectedColumn . columnName } ) < / span >
< / span >
) : (
< span className = "text-muted-foreground" > 컬 럼 선 택 < / span >
) }
< ChevronsUpDown className = "ml-2 h-3 w-3 shrink-0 opacity-50" / >
< / Button >
< / PopoverTrigger >
< PopoverContent className = "w-[300px] p-0" align = "start" >
< Command >
< CommandInput placeholder = { placeholder } className = "h-8 text-xs" / >
< CommandList >
< CommandEmpty className = "py-2 text-center text-xs" > 컬 럼 을 찾 을 수 없 습 니 다 . < / CommandEmpty >
< CommandGroup className = "max-h-[200px] overflow-y-auto" >
{ columns . map ( ( col ) = > (
< CommandItem
key = { col . columnName }
value = { ` ${ col . columnLabel } ${ col . columnName } ` }
onSelect = { ( ) = > {
onSelect ( col . columnName ) ;
setOpen ( false ) ;
} }
className = "text-xs"
>
< Check className = { cn ( "mr-2 h-3 w-3" , value === col . columnName ? "opacity-100" : "opacity-0" ) } / >
< span className = "font-medium" > { col . columnLabel } < / span >
< span className = "ml-1 text-[10px] text-gray-400" > ( { col . columnName } ) < / span >
< / CommandItem >
) ) }
< / CommandGroup >
< / CommandList >
< / Command >
< / PopoverContent >
< / Popover >
) ;
}
// 컬럼 선택 섹션 (자동 로드 포함)
function ColumnSelectSection ( {
lookupTable ,
lookupField ,
tableColumnsCache ,
loadingColumns ,
loadTableColumns ,
onSelect ,
} : {
lookupTable : string ;
lookupField : string ;
tableColumnsCache : Record < string , ColumnInfo [ ] > ;
loadingColumns : Record < string , boolean > ;
loadTableColumns : ( tableName : string ) = > Promise < ColumnInfo [ ] > ;
onSelect : ( value : string ) = > void ;
} ) {
// 캐시에 없고 로딩 중이 아니면 자동으로 로드
useEffect ( ( ) = > {
if ( lookupTable && ! tableColumnsCache [ lookupTable ] && ! loadingColumns [ lookupTable ] ) {
loadTableColumns ( lookupTable ) ;
}
} , [ lookupTable , tableColumnsCache , loadingColumns , loadTableColumns ] ) ;
const isLoading = loadingColumns [ lookupTable ] ;
const columns = tableColumnsCache [ lookupTable ] ;
return (
< div >
< Label className = "text-xs text-gray-600" >
< Search className = "mr-1 inline h-3 w-3" / >
비 교 할 컬 럼
< / Label >
{ isLoading ? (
< div className = "mt-1 rounded border border-dashed bg-gray-50 p-2 text-center text-xs text-gray-400" >
컬 럼 목 록 로 딩 중 . . .
< / div >
) : columns && columns . length > 0 ? (
< ColumnCombobox columns = { columns } value = { lookupField } onSelect = { onSelect } placeholder = "컬럼 검색..." / >
) : (
< div className = "mt-1 rounded border border-dashed bg-gray-50 p-2 text-center text-xs text-gray-400" >
컬 럼 목 록 을 로 드 할 수 없 습 니 다
< / div >
) }
< / div >
) ;
}
feat: 노드 기반 데이터 플로우 시스템 구현
- 노드 에디터 UI 구현 (React Flow 기반)
- TableSource, DataTransform, INSERT, UPDATE, DELETE, UPSERT 노드
- 드래그앤드롭 노드 추가 및 연결
- 속성 패널을 통한 노드 설정
- 실시간 필드 라벨 표시 (column_labels 테이블 연동)
- 데이터 변환 노드 (DataTransform) 기능
- EXPLODE: 구분자로 1개 행 → 여러 행 확장
- UPPERCASE, LOWERCASE, TRIM, CONCAT, SPLIT, REPLACE 등 12가지 변환 타입
- In-place 변환 지원 (타겟 필드 생략 시 소스 필드 덮어쓰기)
- 변환된 필드가 하위 액션 노드에 자동 전달
- 노드 플로우 실행 엔진
- 위상 정렬을 통한 노드 실행 순서 결정
- 레벨별 병렬 실행 (Promise.allSettled)
- 부분 실패 허용 (한 노드 실패 시 연결된 하위 노드만 스킵)
- 트랜잭션 기반 안전한 데이터 처리
- UPSERT 액션 로직 구현
- DB 제약 조건 없이 SELECT → UPDATE or INSERT 방식
- 복합 충돌 키 지원 (예: sales_no + product_name)
- 파라미터 인덱스 정확한 매핑
- 데이터 소스 자동 감지
- 테이블 선택 데이터 (selectedRowsData) 자동 주입
- 폼 입력 데이터 (formData) 자동 주입
- TableSource 노드가 외부 데이터 우선 사용
- 버튼 컴포넌트 통합
- 기존 관계 실행 + 새 노드 플로우 실행 하이브리드 지원
- 노드 플로우 선택 UI 추가
- API 클라이언트 통합 (Axios)
- 개발 문서 작성
- 노드 기반 제어 시스템 개선 계획
- 노드 연결 규칙 설계
- 노드 실행 엔진 설계
- 노드 구조 개선안
- 버튼 통합 분석
2025-10-02 16:22:29 +09:00
export function ConditionProperties ( { nodeId , data } : ConditionPropertiesProps ) {
2025-10-08 09:39:13 +09:00
const { updateNode , nodes , edges } = useFlowEditorStore ( ) ;
feat: 노드 기반 데이터 플로우 시스템 구현
- 노드 에디터 UI 구현 (React Flow 기반)
- TableSource, DataTransform, INSERT, UPDATE, DELETE, UPSERT 노드
- 드래그앤드롭 노드 추가 및 연결
- 속성 패널을 통한 노드 설정
- 실시간 필드 라벨 표시 (column_labels 테이블 연동)
- 데이터 변환 노드 (DataTransform) 기능
- EXPLODE: 구분자로 1개 행 → 여러 행 확장
- UPPERCASE, LOWERCASE, TRIM, CONCAT, SPLIT, REPLACE 등 12가지 변환 타입
- In-place 변환 지원 (타겟 필드 생략 시 소스 필드 덮어쓰기)
- 변환된 필드가 하위 액션 노드에 자동 전달
- 노드 플로우 실행 엔진
- 위상 정렬을 통한 노드 실행 순서 결정
- 레벨별 병렬 실행 (Promise.allSettled)
- 부분 실패 허용 (한 노드 실패 시 연결된 하위 노드만 스킵)
- 트랜잭션 기반 안전한 데이터 처리
- UPSERT 액션 로직 구현
- DB 제약 조건 없이 SELECT → UPDATE or INSERT 방식
- 복합 충돌 키 지원 (예: sales_no + product_name)
- 파라미터 인덱스 정확한 매핑
- 데이터 소스 자동 감지
- 테이블 선택 데이터 (selectedRowsData) 자동 주입
- 폼 입력 데이터 (formData) 자동 주입
- TableSource 노드가 외부 데이터 우선 사용
- 버튼 컴포넌트 통합
- 기존 관계 실행 + 새 노드 플로우 실행 하이브리드 지원
- 노드 플로우 선택 UI 추가
- API 클라이언트 통합 (Axios)
- 개발 문서 작성
- 노드 기반 제어 시스템 개선 계획
- 노드 연결 규칙 설계
- 노드 실행 엔진 설계
- 노드 구조 개선안
- 버튼 통합 분석
2025-10-02 16:22:29 +09:00
const [ displayName , setDisplayName ] = useState ( data . displayName || "조건 분기" ) ;
const [ conditions , setConditions ] = useState ( data . conditions || [ ] ) ;
const [ logic , setLogic ] = useState < "AND" | "OR" > ( data . logic || "AND" ) ;
2025-10-08 09:39:13 +09:00
const [ availableFields , setAvailableFields ] = useState < FieldDefinition [ ] > ( [ ] ) ;
feat: 노드 기반 데이터 플로우 시스템 구현
- 노드 에디터 UI 구현 (React Flow 기반)
- TableSource, DataTransform, INSERT, UPDATE, DELETE, UPSERT 노드
- 드래그앤드롭 노드 추가 및 연결
- 속성 패널을 통한 노드 설정
- 실시간 필드 라벨 표시 (column_labels 테이블 연동)
- 데이터 변환 노드 (DataTransform) 기능
- EXPLODE: 구분자로 1개 행 → 여러 행 확장
- UPPERCASE, LOWERCASE, TRIM, CONCAT, SPLIT, REPLACE 등 12가지 변환 타입
- In-place 변환 지원 (타겟 필드 생략 시 소스 필드 덮어쓰기)
- 변환된 필드가 하위 액션 노드에 자동 전달
- 노드 플로우 실행 엔진
- 위상 정렬을 통한 노드 실행 순서 결정
- 레벨별 병렬 실행 (Promise.allSettled)
- 부분 실패 허용 (한 노드 실패 시 연결된 하위 노드만 스킵)
- 트랜잭션 기반 안전한 데이터 처리
- UPSERT 액션 로직 구현
- DB 제약 조건 없이 SELECT → UPDATE or INSERT 방식
- 복합 충돌 키 지원 (예: sales_no + product_name)
- 파라미터 인덱스 정확한 매핑
- 데이터 소스 자동 감지
- 테이블 선택 데이터 (selectedRowsData) 자동 주입
- 폼 입력 데이터 (formData) 자동 주입
- TableSource 노드가 외부 데이터 우선 사용
- 버튼 컴포넌트 통합
- 기존 관계 실행 + 새 노드 플로우 실행 하이브리드 지원
- 노드 플로우 선택 UI 추가
- API 클라이언트 통합 (Axios)
- 개발 문서 작성
- 노드 기반 제어 시스템 개선 계획
- 노드 연결 규칙 설계
- 노드 실행 엔진 설계
- 노드 구조 개선안
- 버튼 통합 분석
2025-10-02 16:22:29 +09:00
2026-01-07 09:55:19 +09:00
// EXISTS 연산자용 상태
const [ allTables , setAllTables ] = useState < TableInfo [ ] > ( [ ] ) ;
const [ tableColumnsCache , setTableColumnsCache ] = useState < Record < string , ColumnInfo [ ] > > ( { } ) ;
const [ loadingTables , setLoadingTables ] = useState ( false ) ;
const [ loadingColumns , setLoadingColumns ] = useState < Record < string , boolean > > ( { } ) ;
feat: 노드 기반 데이터 플로우 시스템 구현
- 노드 에디터 UI 구현 (React Flow 기반)
- TableSource, DataTransform, INSERT, UPDATE, DELETE, UPSERT 노드
- 드래그앤드롭 노드 추가 및 연결
- 속성 패널을 통한 노드 설정
- 실시간 필드 라벨 표시 (column_labels 테이블 연동)
- 데이터 변환 노드 (DataTransform) 기능
- EXPLODE: 구분자로 1개 행 → 여러 행 확장
- UPPERCASE, LOWERCASE, TRIM, CONCAT, SPLIT, REPLACE 등 12가지 변환 타입
- In-place 변환 지원 (타겟 필드 생략 시 소스 필드 덮어쓰기)
- 변환된 필드가 하위 액션 노드에 자동 전달
- 노드 플로우 실행 엔진
- 위상 정렬을 통한 노드 실행 순서 결정
- 레벨별 병렬 실행 (Promise.allSettled)
- 부분 실패 허용 (한 노드 실패 시 연결된 하위 노드만 스킵)
- 트랜잭션 기반 안전한 데이터 처리
- UPSERT 액션 로직 구현
- DB 제약 조건 없이 SELECT → UPDATE or INSERT 방식
- 복합 충돌 키 지원 (예: sales_no + product_name)
- 파라미터 인덱스 정확한 매핑
- 데이터 소스 자동 감지
- 테이블 선택 데이터 (selectedRowsData) 자동 주입
- 폼 입력 데이터 (formData) 자동 주입
- TableSource 노드가 외부 데이터 우선 사용
- 버튼 컴포넌트 통합
- 기존 관계 실행 + 새 노드 플로우 실행 하이브리드 지원
- 노드 플로우 선택 UI 추가
- API 클라이언트 통합 (Axios)
- 개발 문서 작성
- 노드 기반 제어 시스템 개선 계획
- 노드 연결 규칙 설계
- 노드 실행 엔진 설계
- 노드 구조 개선안
- 버튼 통합 분석
2025-10-02 16:22:29 +09:00
// 데이터 변경 시 로컬 상태 업데이트
useEffect ( ( ) = > {
setDisplayName ( data . displayName || "조건 분기" ) ;
setConditions ( data . conditions || [ ] ) ;
setLogic ( data . logic || "AND" ) ;
} , [ data ] ) ;
2026-01-07 09:55:19 +09:00
// 전체 테이블 목록 로드 (EXISTS 연산자용)
useEffect ( ( ) = > {
const loadAllTables = async ( ) = > {
// 이미 EXISTS 연산자가 있거나 로드된 적이 있으면 스킵
if ( allTables . length > 0 ) return ;
// EXISTS 연산자가 하나라도 있으면 테이블 목록 로드
const hasExistsOperator = conditions . some ( ( c ) = > isExistsOperator ( c . operator ) ) ;
if ( ! hasExistsOperator ) return ;
setLoadingTables ( true ) ;
try {
const response = await tableManagementApi . getTableList ( ) ;
if ( response . success && response . data ) {
setAllTables (
response . data . map ( ( t : any ) = > ( {
tableName : t.tableName ,
tableLabel : t.tableLabel || t . tableName ,
} ) )
) ;
}
} catch ( error ) {
console . error ( "테이블 목록 로드 실패:" , error ) ;
} finally {
setLoadingTables ( false ) ;
}
} ;
loadAllTables ( ) ;
} , [ conditions , allTables . length ] ) ;
// 테이블 컬럼 로드 함수
const loadTableColumns = useCallback (
async ( tableName : string ) : Promise < ColumnInfo [ ] > = > {
// 캐시에 있으면 반환
if ( tableColumnsCache [ tableName ] ) {
return tableColumnsCache [ tableName ] ;
}
// 이미 로딩 중이면 스킵
if ( loadingColumns [ tableName ] ) {
return [ ] ;
}
// 로딩 상태 설정
setLoadingColumns ( ( prev ) = > ( { . . . prev , [ tableName ] : true } ) ) ;
try {
// getColumnList 반환: { success, data: { columns, total, ... } }
const response = await tableManagementApi . getColumnList ( tableName ) ;
if ( response . success && response . data && response . data . columns ) {
const columns = response . data . columns . map ( ( c : any ) = > ( {
columnName : c.columnName ,
columnLabel : c.columnLabel || c . columnName ,
dataType : c.dataType ,
} ) ) ;
setTableColumnsCache ( ( prev ) = > ( { . . . prev , [ tableName ] : columns } ) ) ;
console . log ( ` ✅ 테이블 ${ tableName } 컬럼 로드 완료: ` , columns . length , "개" ) ;
return columns ;
} else {
console . warn ( ` ⚠️ 테이블 ${ tableName } 컬럼 조회 실패: ` , response ) ;
}
} catch ( error ) {
console . error ( ` ❌ 테이블 ${ tableName } 컬럼 로드 실패: ` , error ) ;
} finally {
setLoadingColumns ( ( prev ) = > ( { . . . prev , [ tableName ] : false } ) ) ;
}
return [ ] ;
} ,
[ tableColumnsCache , loadingColumns ]
) ;
// EXISTS 연산자 선택 시 테이블 목록 강제 로드
const ensureTablesLoaded = useCallback ( async ( ) = > {
if ( allTables . length > 0 ) return ;
setLoadingTables ( true ) ;
try {
const response = await tableManagementApi . getTableList ( ) ;
if ( response . success && response . data ) {
setAllTables (
response . data . map ( ( t : any ) = > ( {
tableName : t.tableName ,
tableLabel : t.tableLabel || t . tableName ,
} ) )
) ;
}
} catch ( error ) {
console . error ( "테이블 목록 로드 실패:" , error ) ;
} finally {
setLoadingTables ( false ) ;
}
} , [ allTables . length ] ) ;
2025-10-08 09:39:13 +09:00
// 🔥 연결된 소스 노드의 필드를 재귀적으로 수집
useEffect ( ( ) = > {
const getAllSourceFields = ( currentNodeId : string , visited : Set < string > = new Set ( ) ) : FieldDefinition [ ] = > {
if ( visited . has ( currentNodeId ) ) return [ ] ;
visited . add ( currentNodeId ) ;
const fields : FieldDefinition [ ] = [ ] ;
// 현재 노드로 들어오는 엣지 찾기
const incomingEdges = edges . filter ( ( e ) = > e . target === currentNodeId ) ;
for ( const edge of incomingEdges ) {
const sourceNode = nodes . find ( ( n ) = > n . id === edge . source ) ;
if ( ! sourceNode ) continue ;
const sourceData = sourceNode . data as any ;
// 소스 노드 타입별 필드 수집
if ( sourceNode . type === "tableSource" ) {
// Table Source: fields 사용
if ( sourceData . fields && Array . isArray ( sourceData . fields ) ) {
console . log ( "🔍 [ConditionProperties] Table Source 필드:" , sourceData . fields ) ;
fields . push ( . . . sourceData . fields ) ;
} else {
console . log ( "⚠️ [ConditionProperties] Table Source에 필드 없음:" , sourceData ) ;
}
} else if ( sourceNode . type === "externalDBSource" ) {
// External DB Source: outputFields 사용
if ( sourceData . outputFields && Array . isArray ( sourceData . outputFields ) ) {
console . log ( "🔍 [ConditionProperties] External DB 필드:" , sourceData . outputFields ) ;
fields . push ( . . . sourceData . outputFields ) ;
} else {
console . log ( "⚠️ [ConditionProperties] External DB에 필드 없음:" , sourceData ) ;
}
} else if ( sourceNode . type === "dataTransform" ) {
// Data Transform: 재귀적으로 상위 노드 필드 수집
const upperFields = getAllSourceFields ( sourceNode . id , visited ) ;
// Data Transform의 변환 결과 추가
if ( sourceData . transformations && Array . isArray ( sourceData . transformations ) ) {
const inPlaceFields = new Set < string > ( ) ;
for ( const transform of sourceData . transformations ) {
const { sourceField , targetField } = transform ;
// In-place 변환인지 확인
if ( ! targetField || targetField === sourceField ) {
inPlaceFields . add ( sourceField ) ;
} else {
// 새로운 필드 생성
fields . push ( { name : targetField , label : targetField } ) ;
}
}
// 원본 필드 중 in-place 변환되지 않은 것들 추가
for ( const field of upperFields ) {
if ( ! inPlaceFields . has ( field . name ) ) {
fields . push ( field ) ;
} else {
// In-place 변환된 필드는 원본 이름으로 유지
fields . push ( field ) ;
}
}
} else {
fields . push ( . . . upperFields ) ;
}
2025-10-13 17:47:24 +09:00
} else if ( sourceNode . type === "restAPISource" ) {
// REST API Source: responseFields 사용
if ( sourceData . responseFields && Array . isArray ( sourceData . responseFields ) ) {
console . log ( "🔍 [ConditionProperties] REST API 필드:" , sourceData . responseFields ) ;
fields . push (
. . . sourceData . responseFields . map ( ( f : any ) = > ( {
name : f.name || f . fieldName ,
label : f.label || f . displayName || f . name ,
type : f . dataType || f . type ,
} ) ) ,
) ;
} else {
console . log ( "⚠️ [ConditionProperties] REST API에 필드 없음:" , sourceData ) ;
}
} else if ( sourceNode . type === "condition" ) {
// 조건 노드: 재귀적으로 상위 노드 필드 수집 (통과 노드)
console . log ( "✅ [ConditionProperties] 조건 노드 통과 → 상위 탐색" ) ;
fields . push ( . . . getAllSourceFields ( sourceNode . id , visited ) ) ;
2025-10-08 09:39:13 +09:00
} else if (
sourceNode . type === "insertAction" ||
sourceNode . type === "updateAction" ||
sourceNode . type === "deleteAction" ||
sourceNode . type === "upsertAction"
) {
// Action 노드: 재귀적으로 상위 노드 필드 수집
fields . push ( . . . getAllSourceFields ( sourceNode . id , visited ) ) ;
2025-10-13 17:47:24 +09:00
} else {
// 기타 모든 노드: 재귀적으로 상위 노드 필드 수집 (통과 노드로 처리)
console . log ( ` ✅ [ConditionProperties] 통과 노드 ( ${ sourceNode . type } ) → 상위 탐색 ` ) ;
fields . push ( . . . getAllSourceFields ( sourceNode . id , visited ) ) ;
2025-10-08 09:39:13 +09:00
}
}
// 중복 제거
const uniqueFields = Array . from ( new Map ( fields . map ( ( f ) = > [ f . name , f ] ) ) . values ( ) ) ;
return uniqueFields ;
} ;
const fields = getAllSourceFields ( nodeId ) ;
console . log ( "✅ [ConditionProperties] 최종 수집된 필드:" , fields ) ;
console . log ( "🔍 [ConditionProperties] 현재 노드 ID:" , nodeId ) ;
console . log (
"🔍 [ConditionProperties] 연결된 엣지:" ,
edges . filter ( ( e ) = > e . target === nodeId ) ,
) ;
setAvailableFields ( fields ) ;
} , [ nodeId , nodes , edges ] ) ;
feat: 노드 기반 데이터 플로우 시스템 구현
- 노드 에디터 UI 구현 (React Flow 기반)
- TableSource, DataTransform, INSERT, UPDATE, DELETE, UPSERT 노드
- 드래그앤드롭 노드 추가 및 연결
- 속성 패널을 통한 노드 설정
- 실시간 필드 라벨 표시 (column_labels 테이블 연동)
- 데이터 변환 노드 (DataTransform) 기능
- EXPLODE: 구분자로 1개 행 → 여러 행 확장
- UPPERCASE, LOWERCASE, TRIM, CONCAT, SPLIT, REPLACE 등 12가지 변환 타입
- In-place 변환 지원 (타겟 필드 생략 시 소스 필드 덮어쓰기)
- 변환된 필드가 하위 액션 노드에 자동 전달
- 노드 플로우 실행 엔진
- 위상 정렬을 통한 노드 실행 순서 결정
- 레벨별 병렬 실행 (Promise.allSettled)
- 부분 실패 허용 (한 노드 실패 시 연결된 하위 노드만 스킵)
- 트랜잭션 기반 안전한 데이터 처리
- UPSERT 액션 로직 구현
- DB 제약 조건 없이 SELECT → UPDATE or INSERT 방식
- 복합 충돌 키 지원 (예: sales_no + product_name)
- 파라미터 인덱스 정확한 매핑
- 데이터 소스 자동 감지
- 테이블 선택 데이터 (selectedRowsData) 자동 주입
- 폼 입력 데이터 (formData) 자동 주입
- TableSource 노드가 외부 데이터 우선 사용
- 버튼 컴포넌트 통합
- 기존 관계 실행 + 새 노드 플로우 실행 하이브리드 지원
- 노드 플로우 선택 UI 추가
- API 클라이언트 통합 (Axios)
- 개발 문서 작성
- 노드 기반 제어 시스템 개선 계획
- 노드 연결 규칙 설계
- 노드 실행 엔진 설계
- 노드 구조 개선안
- 버튼 통합 분석
2025-10-02 16:22:29 +09:00
const handleAddCondition = ( ) = > {
2026-01-07 09:55:19 +09:00
const newCondition = {
field : "" ,
operator : "EQUALS" as ConditionOperator ,
value : "" ,
valueType : "static" as "static" | "field" ,
// EXISTS 연산자용 필드는 초기값 없음
lookupTable : undefined ,
lookupTableLabel : undefined ,
lookupField : undefined ,
lookupFieldLabel : undefined ,
} ;
setConditions ( [ . . . conditions , newCondition ] ) ;
feat: 노드 기반 데이터 플로우 시스템 구현
- 노드 에디터 UI 구현 (React Flow 기반)
- TableSource, DataTransform, INSERT, UPDATE, DELETE, UPSERT 노드
- 드래그앤드롭 노드 추가 및 연결
- 속성 패널을 통한 노드 설정
- 실시간 필드 라벨 표시 (column_labels 테이블 연동)
- 데이터 변환 노드 (DataTransform) 기능
- EXPLODE: 구분자로 1개 행 → 여러 행 확장
- UPPERCASE, LOWERCASE, TRIM, CONCAT, SPLIT, REPLACE 등 12가지 변환 타입
- In-place 변환 지원 (타겟 필드 생략 시 소스 필드 덮어쓰기)
- 변환된 필드가 하위 액션 노드에 자동 전달
- 노드 플로우 실행 엔진
- 위상 정렬을 통한 노드 실행 순서 결정
- 레벨별 병렬 실행 (Promise.allSettled)
- 부분 실패 허용 (한 노드 실패 시 연결된 하위 노드만 스킵)
- 트랜잭션 기반 안전한 데이터 처리
- UPSERT 액션 로직 구현
- DB 제약 조건 없이 SELECT → UPDATE or INSERT 방식
- 복합 충돌 키 지원 (예: sales_no + product_name)
- 파라미터 인덱스 정확한 매핑
- 데이터 소스 자동 감지
- 테이블 선택 데이터 (selectedRowsData) 자동 주입
- 폼 입력 데이터 (formData) 자동 주입
- TableSource 노드가 외부 데이터 우선 사용
- 버튼 컴포넌트 통합
- 기존 관계 실행 + 새 노드 플로우 실행 하이브리드 지원
- 노드 플로우 선택 UI 추가
- API 클라이언트 통합 (Axios)
- 개발 문서 작성
- 노드 기반 제어 시스템 개선 계획
- 노드 연결 규칙 설계
- 노드 실행 엔진 설계
- 노드 구조 개선안
- 버튼 통합 분석
2025-10-02 16:22:29 +09:00
} ;
const handleRemoveCondition = ( index : number ) = > {
2025-10-24 14:11:12 +09:00
const newConditions = conditions . filter ( ( _ , i ) = > i !== index ) ;
setConditions ( newConditions ) ;
updateNode ( nodeId , {
conditions : newConditions ,
} ) ;
} ;
const handleDisplayNameChange = ( newDisplayName : string ) = > {
setDisplayName ( newDisplayName ) ;
updateNode ( nodeId , {
displayName : newDisplayName ,
} ) ;
feat: 노드 기반 데이터 플로우 시스템 구현
- 노드 에디터 UI 구현 (React Flow 기반)
- TableSource, DataTransform, INSERT, UPDATE, DELETE, UPSERT 노드
- 드래그앤드롭 노드 추가 및 연결
- 속성 패널을 통한 노드 설정
- 실시간 필드 라벨 표시 (column_labels 테이블 연동)
- 데이터 변환 노드 (DataTransform) 기능
- EXPLODE: 구분자로 1개 행 → 여러 행 확장
- UPPERCASE, LOWERCASE, TRIM, CONCAT, SPLIT, REPLACE 등 12가지 변환 타입
- In-place 변환 지원 (타겟 필드 생략 시 소스 필드 덮어쓰기)
- 변환된 필드가 하위 액션 노드에 자동 전달
- 노드 플로우 실행 엔진
- 위상 정렬을 통한 노드 실행 순서 결정
- 레벨별 병렬 실행 (Promise.allSettled)
- 부분 실패 허용 (한 노드 실패 시 연결된 하위 노드만 스킵)
- 트랜잭션 기반 안전한 데이터 처리
- UPSERT 액션 로직 구현
- DB 제약 조건 없이 SELECT → UPDATE or INSERT 방식
- 복합 충돌 키 지원 (예: sales_no + product_name)
- 파라미터 인덱스 정확한 매핑
- 데이터 소스 자동 감지
- 테이블 선택 데이터 (selectedRowsData) 자동 주입
- 폼 입력 데이터 (formData) 자동 주입
- TableSource 노드가 외부 데이터 우선 사용
- 버튼 컴포넌트 통합
- 기존 관계 실행 + 새 노드 플로우 실행 하이브리드 지원
- 노드 플로우 선택 UI 추가
- API 클라이언트 통합 (Axios)
- 개발 문서 작성
- 노드 기반 제어 시스템 개선 계획
- 노드 연결 규칙 설계
- 노드 실행 엔진 설계
- 노드 구조 개선안
- 버튼 통합 분석
2025-10-02 16:22:29 +09:00
} ;
2026-01-07 09:55:19 +09:00
const handleConditionChange = async ( index : number , field : string , value : any ) = > {
feat: 노드 기반 데이터 플로우 시스템 구현
- 노드 에디터 UI 구현 (React Flow 기반)
- TableSource, DataTransform, INSERT, UPDATE, DELETE, UPSERT 노드
- 드래그앤드롭 노드 추가 및 연결
- 속성 패널을 통한 노드 설정
- 실시간 필드 라벨 표시 (column_labels 테이블 연동)
- 데이터 변환 노드 (DataTransform) 기능
- EXPLODE: 구분자로 1개 행 → 여러 행 확장
- UPPERCASE, LOWERCASE, TRIM, CONCAT, SPLIT, REPLACE 등 12가지 변환 타입
- In-place 변환 지원 (타겟 필드 생략 시 소스 필드 덮어쓰기)
- 변환된 필드가 하위 액션 노드에 자동 전달
- 노드 플로우 실행 엔진
- 위상 정렬을 통한 노드 실행 순서 결정
- 레벨별 병렬 실행 (Promise.allSettled)
- 부분 실패 허용 (한 노드 실패 시 연결된 하위 노드만 스킵)
- 트랜잭션 기반 안전한 데이터 처리
- UPSERT 액션 로직 구현
- DB 제약 조건 없이 SELECT → UPDATE or INSERT 방식
- 복합 충돌 키 지원 (예: sales_no + product_name)
- 파라미터 인덱스 정확한 매핑
- 데이터 소스 자동 감지
- 테이블 선택 데이터 (selectedRowsData) 자동 주입
- 폼 입력 데이터 (formData) 자동 주입
- TableSource 노드가 외부 데이터 우선 사용
- 버튼 컴포넌트 통합
- 기존 관계 실행 + 새 노드 플로우 실행 하이브리드 지원
- 노드 플로우 선택 UI 추가
- API 클라이언트 통합 (Axios)
- 개발 문서 작성
- 노드 기반 제어 시스템 개선 계획
- 노드 연결 규칙 설계
- 노드 실행 엔진 설계
- 노드 구조 개선안
- 버튼 통합 분석
2025-10-02 16:22:29 +09:00
const newConditions = [ . . . conditions ] ;
newConditions [ index ] = { . . . newConditions [ index ] , [ field ] : value } ;
2026-01-07 09:55:19 +09:00
// EXISTS 연산자로 변경 시 테이블 목록 로드 및 기존 value/valueType 초기화
if ( field === "operator" && isExistsOperator ( value ) ) {
await ensureTablesLoaded ( ) ;
// EXISTS 연산자에서는 value, valueType이 필요 없으므로 초기화
newConditions [ index ] . value = "" ;
newConditions [ index ] . valueType = undefined ;
}
// EXISTS 연산자에서 다른 연산자로 변경 시 lookup 필드들 초기화
if ( field === "operator" && ! isExistsOperator ( value ) ) {
newConditions [ index ] . lookupTable = undefined ;
newConditions [ index ] . lookupTableLabel = undefined ;
newConditions [ index ] . lookupField = undefined ;
newConditions [ index ] . lookupFieldLabel = undefined ;
}
// lookupTable 변경 시 컬럼 목록 로드 및 라벨 설정
if ( field === "lookupTable" && value ) {
const tableInfo = allTables . find ( ( t ) = > t . tableName === value ) ;
if ( tableInfo ) {
newConditions [ index ] . lookupTableLabel = tableInfo . tableLabel ;
}
// 테이블 변경 시 필드 초기화
newConditions [ index ] . lookupField = undefined ;
newConditions [ index ] . lookupFieldLabel = undefined ;
// 컬럼 목록 미리 로드
await loadTableColumns ( value ) ;
}
// lookupField 변경 시 라벨 설정
if ( field === "lookupField" && value ) {
const tableName = newConditions [ index ] . lookupTable ;
if ( tableName && tableColumnsCache [ tableName ] ) {
const columnInfo = tableColumnsCache [ tableName ] . find ( ( c ) = > c . columnName === value ) ;
if ( columnInfo ) {
newConditions [ index ] . lookupFieldLabel = columnInfo . columnLabel ;
}
}
}
feat: 노드 기반 데이터 플로우 시스템 구현
- 노드 에디터 UI 구현 (React Flow 기반)
- TableSource, DataTransform, INSERT, UPDATE, DELETE, UPSERT 노드
- 드래그앤드롭 노드 추가 및 연결
- 속성 패널을 통한 노드 설정
- 실시간 필드 라벨 표시 (column_labels 테이블 연동)
- 데이터 변환 노드 (DataTransform) 기능
- EXPLODE: 구분자로 1개 행 → 여러 행 확장
- UPPERCASE, LOWERCASE, TRIM, CONCAT, SPLIT, REPLACE 등 12가지 변환 타입
- In-place 변환 지원 (타겟 필드 생략 시 소스 필드 덮어쓰기)
- 변환된 필드가 하위 액션 노드에 자동 전달
- 노드 플로우 실행 엔진
- 위상 정렬을 통한 노드 실행 순서 결정
- 레벨별 병렬 실행 (Promise.allSettled)
- 부분 실패 허용 (한 노드 실패 시 연결된 하위 노드만 스킵)
- 트랜잭션 기반 안전한 데이터 처리
- UPSERT 액션 로직 구현
- DB 제약 조건 없이 SELECT → UPDATE or INSERT 방식
- 복합 충돌 키 지원 (예: sales_no + product_name)
- 파라미터 인덱스 정확한 매핑
- 데이터 소스 자동 감지
- 테이블 선택 데이터 (selectedRowsData) 자동 주입
- 폼 입력 데이터 (formData) 자동 주입
- TableSource 노드가 외부 데이터 우선 사용
- 버튼 컴포넌트 통합
- 기존 관계 실행 + 새 노드 플로우 실행 하이브리드 지원
- 노드 플로우 선택 UI 추가
- API 클라이언트 통합 (Axios)
- 개발 문서 작성
- 노드 기반 제어 시스템 개선 계획
- 노드 연결 규칙 설계
- 노드 실행 엔진 설계
- 노드 구조 개선안
- 버튼 통합 분석
2025-10-02 16:22:29 +09:00
setConditions ( newConditions ) ;
2025-10-24 14:11:12 +09:00
updateNode ( nodeId , {
conditions : newConditions ,
} ) ;
feat: 노드 기반 데이터 플로우 시스템 구현
- 노드 에디터 UI 구현 (React Flow 기반)
- TableSource, DataTransform, INSERT, UPDATE, DELETE, UPSERT 노드
- 드래그앤드롭 노드 추가 및 연결
- 속성 패널을 통한 노드 설정
- 실시간 필드 라벨 표시 (column_labels 테이블 연동)
- 데이터 변환 노드 (DataTransform) 기능
- EXPLODE: 구분자로 1개 행 → 여러 행 확장
- UPPERCASE, LOWERCASE, TRIM, CONCAT, SPLIT, REPLACE 등 12가지 변환 타입
- In-place 변환 지원 (타겟 필드 생략 시 소스 필드 덮어쓰기)
- 변환된 필드가 하위 액션 노드에 자동 전달
- 노드 플로우 실행 엔진
- 위상 정렬을 통한 노드 실행 순서 결정
- 레벨별 병렬 실행 (Promise.allSettled)
- 부분 실패 허용 (한 노드 실패 시 연결된 하위 노드만 스킵)
- 트랜잭션 기반 안전한 데이터 처리
- UPSERT 액션 로직 구현
- DB 제약 조건 없이 SELECT → UPDATE or INSERT 방식
- 복합 충돌 키 지원 (예: sales_no + product_name)
- 파라미터 인덱스 정확한 매핑
- 데이터 소스 자동 감지
- 테이블 선택 데이터 (selectedRowsData) 자동 주입
- 폼 입력 데이터 (formData) 자동 주입
- TableSource 노드가 외부 데이터 우선 사용
- 버튼 컴포넌트 통합
- 기존 관계 실행 + 새 노드 플로우 실행 하이브리드 지원
- 노드 플로우 선택 UI 추가
- API 클라이언트 통합 (Axios)
- 개발 문서 작성
- 노드 기반 제어 시스템 개선 계획
- 노드 연결 규칙 설계
- 노드 실행 엔진 설계
- 노드 구조 개선안
- 버튼 통합 분석
2025-10-02 16:22:29 +09:00
} ;
2025-10-24 14:11:12 +09:00
const handleLogicChange = ( newLogic : "AND" | "OR" ) = > {
setLogic ( newLogic ) ;
feat: 노드 기반 데이터 플로우 시스템 구현
- 노드 에디터 UI 구현 (React Flow 기반)
- TableSource, DataTransform, INSERT, UPDATE, DELETE, UPSERT 노드
- 드래그앤드롭 노드 추가 및 연결
- 속성 패널을 통한 노드 설정
- 실시간 필드 라벨 표시 (column_labels 테이블 연동)
- 데이터 변환 노드 (DataTransform) 기능
- EXPLODE: 구분자로 1개 행 → 여러 행 확장
- UPPERCASE, LOWERCASE, TRIM, CONCAT, SPLIT, REPLACE 등 12가지 변환 타입
- In-place 변환 지원 (타겟 필드 생략 시 소스 필드 덮어쓰기)
- 변환된 필드가 하위 액션 노드에 자동 전달
- 노드 플로우 실행 엔진
- 위상 정렬을 통한 노드 실행 순서 결정
- 레벨별 병렬 실행 (Promise.allSettled)
- 부분 실패 허용 (한 노드 실패 시 연결된 하위 노드만 스킵)
- 트랜잭션 기반 안전한 데이터 처리
- UPSERT 액션 로직 구현
- DB 제약 조건 없이 SELECT → UPDATE or INSERT 방식
- 복합 충돌 키 지원 (예: sales_no + product_name)
- 파라미터 인덱스 정확한 매핑
- 데이터 소스 자동 감지
- 테이블 선택 데이터 (selectedRowsData) 자동 주입
- 폼 입력 데이터 (formData) 자동 주입
- TableSource 노드가 외부 데이터 우선 사용
- 버튼 컴포넌트 통합
- 기존 관계 실행 + 새 노드 플로우 실행 하이브리드 지원
- 노드 플로우 선택 UI 추가
- API 클라이언트 통합 (Axios)
- 개발 문서 작성
- 노드 기반 제어 시스템 개선 계획
- 노드 연결 규칙 설계
- 노드 실행 엔진 설계
- 노드 구조 개선안
- 버튼 통합 분석
2025-10-02 16:22:29 +09:00
updateNode ( nodeId , {
2025-10-24 14:11:12 +09:00
logic : newLogic ,
feat: 노드 기반 데이터 플로우 시스템 구현
- 노드 에디터 UI 구현 (React Flow 기반)
- TableSource, DataTransform, INSERT, UPDATE, DELETE, UPSERT 노드
- 드래그앤드롭 노드 추가 및 연결
- 속성 패널을 통한 노드 설정
- 실시간 필드 라벨 표시 (column_labels 테이블 연동)
- 데이터 변환 노드 (DataTransform) 기능
- EXPLODE: 구분자로 1개 행 → 여러 행 확장
- UPPERCASE, LOWERCASE, TRIM, CONCAT, SPLIT, REPLACE 등 12가지 변환 타입
- In-place 변환 지원 (타겟 필드 생략 시 소스 필드 덮어쓰기)
- 변환된 필드가 하위 액션 노드에 자동 전달
- 노드 플로우 실행 엔진
- 위상 정렬을 통한 노드 실행 순서 결정
- 레벨별 병렬 실행 (Promise.allSettled)
- 부분 실패 허용 (한 노드 실패 시 연결된 하위 노드만 스킵)
- 트랜잭션 기반 안전한 데이터 처리
- UPSERT 액션 로직 구현
- DB 제약 조건 없이 SELECT → UPDATE or INSERT 방식
- 복합 충돌 키 지원 (예: sales_no + product_name)
- 파라미터 인덱스 정확한 매핑
- 데이터 소스 자동 감지
- 테이블 선택 데이터 (selectedRowsData) 자동 주입
- 폼 입력 데이터 (formData) 자동 주입
- TableSource 노드가 외부 데이터 우선 사용
- 버튼 컴포넌트 통합
- 기존 관계 실행 + 새 노드 플로우 실행 하이브리드 지원
- 노드 플로우 선택 UI 추가
- API 클라이언트 통합 (Axios)
- 개발 문서 작성
- 노드 기반 제어 시스템 개선 계획
- 노드 연결 규칙 설계
- 노드 실행 엔진 설계
- 노드 구조 개선안
- 버튼 통합 분석
2025-10-02 16:22:29 +09:00
} ) ;
} ;
return (
2025-10-24 15:40:08 +09:00
< div >
2025-10-24 14:11:12 +09:00
< div className = "space-y-4 p-4 pb-8" >
feat: 노드 기반 데이터 플로우 시스템 구현
- 노드 에디터 UI 구현 (React Flow 기반)
- TableSource, DataTransform, INSERT, UPDATE, DELETE, UPSERT 노드
- 드래그앤드롭 노드 추가 및 연결
- 속성 패널을 통한 노드 설정
- 실시간 필드 라벨 표시 (column_labels 테이블 연동)
- 데이터 변환 노드 (DataTransform) 기능
- EXPLODE: 구분자로 1개 행 → 여러 행 확장
- UPPERCASE, LOWERCASE, TRIM, CONCAT, SPLIT, REPLACE 등 12가지 변환 타입
- In-place 변환 지원 (타겟 필드 생략 시 소스 필드 덮어쓰기)
- 변환된 필드가 하위 액션 노드에 자동 전달
- 노드 플로우 실행 엔진
- 위상 정렬을 통한 노드 실행 순서 결정
- 레벨별 병렬 실행 (Promise.allSettled)
- 부분 실패 허용 (한 노드 실패 시 연결된 하위 노드만 스킵)
- 트랜잭션 기반 안전한 데이터 처리
- UPSERT 액션 로직 구현
- DB 제약 조건 없이 SELECT → UPDATE or INSERT 방식
- 복합 충돌 키 지원 (예: sales_no + product_name)
- 파라미터 인덱스 정확한 매핑
- 데이터 소스 자동 감지
- 테이블 선택 데이터 (selectedRowsData) 자동 주입
- 폼 입력 데이터 (formData) 자동 주입
- TableSource 노드가 외부 데이터 우선 사용
- 버튼 컴포넌트 통합
- 기존 관계 실행 + 새 노드 플로우 실행 하이브리드 지원
- 노드 플로우 선택 UI 추가
- API 클라이언트 통합 (Axios)
- 개발 문서 작성
- 노드 기반 제어 시스템 개선 계획
- 노드 연결 규칙 설계
- 노드 실행 엔진 설계
- 노드 구조 개선안
- 버튼 통합 분석
2025-10-02 16:22:29 +09:00
{ /* 기본 정보 */ }
< div >
< h3 className = "mb-3 text-sm font-semibold" > 기 본 정 보 < / h3 >
< div className = "space-y-3" >
< div >
< Label htmlFor = "displayName" className = "text-xs" >
표 시 이 름
< / Label >
< Input
id = "displayName"
value = { displayName }
2025-10-24 14:11:12 +09:00
onChange = { ( e ) = > handleDisplayNameChange ( e . target . value ) }
feat: 노드 기반 데이터 플로우 시스템 구현
- 노드 에디터 UI 구현 (React Flow 기반)
- TableSource, DataTransform, INSERT, UPDATE, DELETE, UPSERT 노드
- 드래그앤드롭 노드 추가 및 연결
- 속성 패널을 통한 노드 설정
- 실시간 필드 라벨 표시 (column_labels 테이블 연동)
- 데이터 변환 노드 (DataTransform) 기능
- EXPLODE: 구분자로 1개 행 → 여러 행 확장
- UPPERCASE, LOWERCASE, TRIM, CONCAT, SPLIT, REPLACE 등 12가지 변환 타입
- In-place 변환 지원 (타겟 필드 생략 시 소스 필드 덮어쓰기)
- 변환된 필드가 하위 액션 노드에 자동 전달
- 노드 플로우 실행 엔진
- 위상 정렬을 통한 노드 실행 순서 결정
- 레벨별 병렬 실행 (Promise.allSettled)
- 부분 실패 허용 (한 노드 실패 시 연결된 하위 노드만 스킵)
- 트랜잭션 기반 안전한 데이터 처리
- UPSERT 액션 로직 구현
- DB 제약 조건 없이 SELECT → UPDATE or INSERT 방식
- 복합 충돌 키 지원 (예: sales_no + product_name)
- 파라미터 인덱스 정확한 매핑
- 데이터 소스 자동 감지
- 테이블 선택 데이터 (selectedRowsData) 자동 주입
- 폼 입력 데이터 (formData) 자동 주입
- TableSource 노드가 외부 데이터 우선 사용
- 버튼 컴포넌트 통합
- 기존 관계 실행 + 새 노드 플로우 실행 하이브리드 지원
- 노드 플로우 선택 UI 추가
- API 클라이언트 통합 (Axios)
- 개발 문서 작성
- 노드 기반 제어 시스템 개선 계획
- 노드 연결 규칙 설계
- 노드 실행 엔진 설계
- 노드 구조 개선안
- 버튼 통합 분석
2025-10-02 16:22:29 +09:00
className = "mt-1"
placeholder = "노드 표시 이름"
/ >
< / div >
< div >
< Label htmlFor = "logic" className = "text-xs" >
조 건 로 직
< / Label >
2025-10-24 14:11:12 +09:00
< Select value = { logic } onValueChange = { handleLogicChange } >
feat: 노드 기반 데이터 플로우 시스템 구현
- 노드 에디터 UI 구현 (React Flow 기반)
- TableSource, DataTransform, INSERT, UPDATE, DELETE, UPSERT 노드
- 드래그앤드롭 노드 추가 및 연결
- 속성 패널을 통한 노드 설정
- 실시간 필드 라벨 표시 (column_labels 테이블 연동)
- 데이터 변환 노드 (DataTransform) 기능
- EXPLODE: 구분자로 1개 행 → 여러 행 확장
- UPPERCASE, LOWERCASE, TRIM, CONCAT, SPLIT, REPLACE 등 12가지 변환 타입
- In-place 변환 지원 (타겟 필드 생략 시 소스 필드 덮어쓰기)
- 변환된 필드가 하위 액션 노드에 자동 전달
- 노드 플로우 실행 엔진
- 위상 정렬을 통한 노드 실행 순서 결정
- 레벨별 병렬 실행 (Promise.allSettled)
- 부분 실패 허용 (한 노드 실패 시 연결된 하위 노드만 스킵)
- 트랜잭션 기반 안전한 데이터 처리
- UPSERT 액션 로직 구현
- DB 제약 조건 없이 SELECT → UPDATE or INSERT 방식
- 복합 충돌 키 지원 (예: sales_no + product_name)
- 파라미터 인덱스 정확한 매핑
- 데이터 소스 자동 감지
- 테이블 선택 데이터 (selectedRowsData) 자동 주입
- 폼 입력 데이터 (formData) 자동 주입
- TableSource 노드가 외부 데이터 우선 사용
- 버튼 컴포넌트 통합
- 기존 관계 실행 + 새 노드 플로우 실행 하이브리드 지원
- 노드 플로우 선택 UI 추가
- API 클라이언트 통합 (Axios)
- 개발 문서 작성
- 노드 기반 제어 시스템 개선 계획
- 노드 연결 규칙 설계
- 노드 실행 엔진 설계
- 노드 구조 개선안
- 버튼 통합 분석
2025-10-02 16:22:29 +09:00
< SelectTrigger className = "mt-1" >
< SelectValue / >
< / SelectTrigger >
< SelectContent >
< SelectItem value = "AND" > AND ( 모 두 충 족 ) < / SelectItem >
< SelectItem value = "OR" > OR ( 하 나 라 도 충 족 ) < / SelectItem >
< / SelectContent >
< / Select >
< / div >
< / div >
< / div >
{ /* 조건식 */ }
< div >
< div className = "mb-2 flex items-center justify-between" >
< h3 className = "text-sm font-semibold" > 조 건 식 < / h3 >
< Button size = "sm" variant = "outline" onClick = { handleAddCondition } className = "h-7" >
< Plus className = "mr-1 h-3 w-3" / >
추 가
< / Button >
< / div >
{ conditions . length > 0 ? (
< div className = "space-y-2" >
{ conditions . map ( ( condition , index ) = > (
< div key = { index } className = "rounded border bg-yellow-50 p-3" >
< div className = "mb-2 flex items-center justify-between" >
< div className = "flex items-center gap-2" >
< span className = "text-xs font-medium text-yellow-700" > 조 건 # { index + 1 } < / span >
{ index > 0 && (
< span className = "rounded bg-yellow-200 px-1.5 py-0.5 text-xs font-semibold text-yellow-800" >
{ logic }
< / span >
) }
< / div >
< Button
size = "sm"
variant = "ghost"
onClick = { ( ) = > handleRemoveCondition ( index ) }
className = "h-6 w-6 p-0"
>
< Trash2 className = "h-3 w-3" / >
< / Button >
< / div >
< div className = "space-y-2" >
< div >
< Label className = "text-xs text-gray-600" > 필 드 명 < / Label >
2025-10-08 09:39:13 +09:00
{ availableFields . length > 0 ? (
< Select
value = { condition . field }
onValueChange = { ( value ) = > handleConditionChange ( index , "field" , value ) }
>
< SelectTrigger className = "mt-1 h-8 text-xs" >
< SelectValue placeholder = "필드 선택" / >
< / SelectTrigger >
< SelectContent >
{ availableFields . map ( ( field ) = > (
< SelectItem key = { field . name } value = { field . name } >
{ field . label || field . name }
{ field . type && < span className = "ml-2 text-xs text-gray-400" > ( { field . type } ) < / span > }
< / SelectItem >
) ) }
< / SelectContent >
< / Select >
) : (
< div className = "mt-1 rounded border border-dashed bg-gray-50 p-2 text-center text-xs text-gray-400" >
소 스 노 드 를 연 결 하 세 요
< / div >
) }
feat: 노드 기반 데이터 플로우 시스템 구현
- 노드 에디터 UI 구현 (React Flow 기반)
- TableSource, DataTransform, INSERT, UPDATE, DELETE, UPSERT 노드
- 드래그앤드롭 노드 추가 및 연결
- 속성 패널을 통한 노드 설정
- 실시간 필드 라벨 표시 (column_labels 테이블 연동)
- 데이터 변환 노드 (DataTransform) 기능
- EXPLODE: 구분자로 1개 행 → 여러 행 확장
- UPPERCASE, LOWERCASE, TRIM, CONCAT, SPLIT, REPLACE 등 12가지 변환 타입
- In-place 변환 지원 (타겟 필드 생략 시 소스 필드 덮어쓰기)
- 변환된 필드가 하위 액션 노드에 자동 전달
- 노드 플로우 실행 엔진
- 위상 정렬을 통한 노드 실행 순서 결정
- 레벨별 병렬 실행 (Promise.allSettled)
- 부분 실패 허용 (한 노드 실패 시 연결된 하위 노드만 스킵)
- 트랜잭션 기반 안전한 데이터 처리
- UPSERT 액션 로직 구현
- DB 제약 조건 없이 SELECT → UPDATE or INSERT 방식
- 복합 충돌 키 지원 (예: sales_no + product_name)
- 파라미터 인덱스 정확한 매핑
- 데이터 소스 자동 감지
- 테이블 선택 데이터 (selectedRowsData) 자동 주입
- 폼 입력 데이터 (formData) 자동 주입
- TableSource 노드가 외부 데이터 우선 사용
- 버튼 컴포넌트 통합
- 기존 관계 실행 + 새 노드 플로우 실행 하이브리드 지원
- 노드 플로우 선택 UI 추가
- API 클라이언트 통합 (Axios)
- 개발 문서 작성
- 노드 기반 제어 시스템 개선 계획
- 노드 연결 규칙 설계
- 노드 실행 엔진 설계
- 노드 구조 개선안
- 버튼 통합 분석
2025-10-02 16:22:29 +09:00
< / div >
< div >
< Label className = "text-xs text-gray-600" > 연 산 자 < / Label >
< Select
value = { condition . operator }
onValueChange = { ( value ) = > handleConditionChange ( index , "operator" , value ) }
>
< SelectTrigger className = "mt-1 h-8 text-xs" >
< SelectValue / >
< / SelectTrigger >
< SelectContent >
{ OPERATORS . map ( ( op ) = > (
< SelectItem key = { op . value } value = { op . value } >
{ op . label }
< / SelectItem >
) ) }
< / SelectContent >
< / Select >
< / div >
2026-01-07 09:55:19 +09:00
{ /* EXISTS 연산자인 경우: 테이블/필드 선택 UI (검색 가능한 Combobox) */ }
{ isExistsOperator ( condition . operator ) && (
2025-10-08 09:39:13 +09:00
< >
< div >
< Label className = "text-xs text-gray-600" >
2026-01-07 09:55:19 +09:00
< Database className = "mr-1 inline h-3 w-3" / >
조 회 할 테 이 블
2025-10-08 09:39:13 +09:00
< / Label >
2026-01-07 09:55:19 +09:00
{ loadingTables ? (
< div className = "mt-1 rounded border border-dashed bg-gray-50 p-2 text-center text-xs text-gray-400" >
테 이 블 목 록 로 딩 중 . . .
< / div >
) : allTables . length > 0 ? (
< TableCombobox
tables = { allTables }
value = { ( condition as any ) . lookupTable || "" }
onSelect = { ( value ) = > handleConditionChange ( index , "lookupTable" , value ) }
placeholder = "테이블 검색..."
2025-10-08 09:39:13 +09:00
/ >
2026-01-07 09:55:19 +09:00
) : (
< div className = "mt-1 rounded border border-dashed bg-gray-50 p-2 text-center text-xs text-gray-400" >
테 이 블 목 록 을 로 드 할 수 없 습 니 다
< / div >
2025-10-08 09:39:13 +09:00
) }
< / div >
2026-01-07 09:55:19 +09:00
{ ( condition as any ) . lookupTable && (
< ColumnSelectSection
lookupTable = { ( condition as any ) . lookupTable }
lookupField = { ( condition as any ) . lookupField || "" }
tableColumnsCache = { tableColumnsCache }
loadingColumns = { loadingColumns }
loadTableColumns = { loadTableColumns }
onSelect = { ( value ) = > handleConditionChange ( index , "lookupField" , value ) }
/ >
) }
< div className = "rounded bg-purple-50 p-2 text-xs text-purple-700" >
{ condition . operator === "EXISTS_IN"
? ` 소스의 " ${ condition . field || "..." } " 값이 " ${ ( condition as any ) . lookupTableLabel || "..." } " 테이블의 " ${ ( condition as any ) . lookupFieldLabel || "..." } " 컬럼에 존재하면 TRUE `
: ` 소스의 " ${ condition . field || "..." } " 값이 " ${ ( condition as any ) . lookupTableLabel || "..." } " 테이블의 " ${ ( condition as any ) . lookupFieldLabel || "..." } " 컬럼에 존재하지 않으면 TRUE ` }
< / div >
2025-10-08 09:39:13 +09:00
< / >
feat: 노드 기반 데이터 플로우 시스템 구현
- 노드 에디터 UI 구현 (React Flow 기반)
- TableSource, DataTransform, INSERT, UPDATE, DELETE, UPSERT 노드
- 드래그앤드롭 노드 추가 및 연결
- 속성 패널을 통한 노드 설정
- 실시간 필드 라벨 표시 (column_labels 테이블 연동)
- 데이터 변환 노드 (DataTransform) 기능
- EXPLODE: 구분자로 1개 행 → 여러 행 확장
- UPPERCASE, LOWERCASE, TRIM, CONCAT, SPLIT, REPLACE 등 12가지 변환 타입
- In-place 변환 지원 (타겟 필드 생략 시 소스 필드 덮어쓰기)
- 변환된 필드가 하위 액션 노드에 자동 전달
- 노드 플로우 실행 엔진
- 위상 정렬을 통한 노드 실행 순서 결정
- 레벨별 병렬 실행 (Promise.allSettled)
- 부분 실패 허용 (한 노드 실패 시 연결된 하위 노드만 스킵)
- 트랜잭션 기반 안전한 데이터 처리
- UPSERT 액션 로직 구현
- DB 제약 조건 없이 SELECT → UPDATE or INSERT 방식
- 복합 충돌 키 지원 (예: sales_no + product_name)
- 파라미터 인덱스 정확한 매핑
- 데이터 소스 자동 감지
- 테이블 선택 데이터 (selectedRowsData) 자동 주입
- 폼 입력 데이터 (formData) 자동 주입
- TableSource 노드가 외부 데이터 우선 사용
- 버튼 컴포넌트 통합
- 기존 관계 실행 + 새 노드 플로우 실행 하이브리드 지원
- 노드 플로우 선택 UI 추가
- API 클라이언트 통합 (Axios)
- 개발 문서 작성
- 노드 기반 제어 시스템 개선 계획
- 노드 연결 규칙 설계
- 노드 실행 엔진 설계
- 노드 구조 개선안
- 버튼 통합 분석
2025-10-02 16:22:29 +09:00
) }
2026-01-07 09:55:19 +09:00
{ /* 일반 연산자인 경우: 기존 비교값 UI */ }
{ condition . operator !== "IS_NULL" &&
condition . operator !== "IS_NOT_NULL" &&
! isExistsOperator ( condition . operator ) && (
< >
< div >
< Label className = "text-xs text-gray-600" > 비 교 값 타 입 < / Label >
< Select
value = { ( condition as any ) . valueType || "static" }
onValueChange = { ( value ) = > handleConditionChange ( index , "valueType" , value ) }
>
< SelectTrigger className = "mt-1 h-8 text-xs" >
< SelectValue / >
< / SelectTrigger >
< SelectContent >
< SelectItem value = "static" > 고 정 값 < / SelectItem >
< SelectItem value = "field" > 필 드 참 조 < / SelectItem >
< / SelectContent >
< / Select >
< / div >
< div >
< Label className = "text-xs text-gray-600" >
{ ( condition as any ) . valueType === "field" ? "비교 필드" : "비교 값" }
< / Label >
{ ( condition as any ) . valueType === "field" ? (
// 필드 참조: 드롭다운으로 선택
availableFields . length > 0 ? (
< Select
value = { condition . value as string }
onValueChange = { ( value ) = > handleConditionChange ( index , "value" , value ) }
>
< SelectTrigger className = "mt-1 h-8 text-xs" >
< SelectValue placeholder = "비교할 필드 선택" / >
< / SelectTrigger >
< SelectContent >
{ availableFields . map ( ( field ) = > (
< SelectItem key = { field . name } value = { field . name } >
{ field . label || field . name }
{ field . type && (
< span className = "ml-2 text-xs text-gray-400" > ( { field . type } ) < / span >
) }
< / SelectItem >
) ) }
< / SelectContent >
< / Select >
) : (
< div className = "mt-1 rounded border border-dashed bg-gray-50 p-2 text-center text-xs text-gray-400" >
소 스 노 드 를 연 결 하 세 요
< / div >
)
) : (
// 고정값: 직접 입력
< Input
value = { condition . value as string }
onChange = { ( e ) = > handleConditionChange ( index , "value" , e . target . value ) }
placeholder = "비교할 값"
className = "mt-1 h-8 text-xs"
/ >
) }
< / div >
< / >
) }
feat: 노드 기반 데이터 플로우 시스템 구현
- 노드 에디터 UI 구현 (React Flow 기반)
- TableSource, DataTransform, INSERT, UPDATE, DELETE, UPSERT 노드
- 드래그앤드롭 노드 추가 및 연결
- 속성 패널을 통한 노드 설정
- 실시간 필드 라벨 표시 (column_labels 테이블 연동)
- 데이터 변환 노드 (DataTransform) 기능
- EXPLODE: 구분자로 1개 행 → 여러 행 확장
- UPPERCASE, LOWERCASE, TRIM, CONCAT, SPLIT, REPLACE 등 12가지 변환 타입
- In-place 변환 지원 (타겟 필드 생략 시 소스 필드 덮어쓰기)
- 변환된 필드가 하위 액션 노드에 자동 전달
- 노드 플로우 실행 엔진
- 위상 정렬을 통한 노드 실행 순서 결정
- 레벨별 병렬 실행 (Promise.allSettled)
- 부분 실패 허용 (한 노드 실패 시 연결된 하위 노드만 스킵)
- 트랜잭션 기반 안전한 데이터 처리
- UPSERT 액션 로직 구현
- DB 제약 조건 없이 SELECT → UPDATE or INSERT 방식
- 복합 충돌 키 지원 (예: sales_no + product_name)
- 파라미터 인덱스 정확한 매핑
- 데이터 소스 자동 감지
- 테이블 선택 데이터 (selectedRowsData) 자동 주입
- 폼 입력 데이터 (formData) 자동 주입
- TableSource 노드가 외부 데이터 우선 사용
- 버튼 컴포넌트 통합
- 기존 관계 실행 + 새 노드 플로우 실행 하이브리드 지원
- 노드 플로우 선택 UI 추가
- API 클라이언트 통합 (Axios)
- 개발 문서 작성
- 노드 기반 제어 시스템 개선 계획
- 노드 연결 규칙 설계
- 노드 실행 엔진 설계
- 노드 구조 개선안
- 버튼 통합 분석
2025-10-02 16:22:29 +09:00
< / div >
< / div >
) ) }
< / div >
) : (
< div className = "rounded border border-dashed p-4 text-center text-xs text-gray-400" >
조 건 식 이 없 습 니 다 . "추가" 버 튼 을 클 릭 하 세 요 .
< / div >
) }
< / div >
{ /* 안내 */ }
< div className = "space-y-2" >
2025-10-08 09:39:13 +09:00
< div className = "rounded bg-blue-50 p-3 text-xs text-blue-700" >
2026-01-07 09:55:19 +09:00
< strong > 소 스 노 드 연 결 < / strong > : 테 이 블 / 외 부 DB 노 드 를 연 결 하 면 자 동 으 로 필 드 목 록 이 표 시 됩 니 다 .
2025-10-08 09:39:13 +09:00
< / div >
< div className = "rounded bg-green-50 p-3 text-xs text-green-700" >
2026-01-07 09:55:19 +09:00
< strong > 비 교 값 타 입 < / strong > : < br / >
- < strong > 고 정 값 < / strong > : 직 접 입 력 한 값 과 비 교 ( 예 : age & gt ; 30 )
< br / > - < strong > 필 드 참 조 < / strong > : 다 른 필 드 의 값 과 비 교 ( 예 : 주문수량 & gt ; 재 고 수 량 )
< / div >
< div className = "rounded bg-purple-50 p-3 text-xs text-purple-700" >
< strong > 테 이 블 존 재 여 부 검 사 < / strong > : < br / >
- < strong > 다 른 테 이 블 에 존 재 함 < / strong > : 값 이 다 른 테 이 블 에 있 으 면 TRUE
< br / > - < strong > 다 른 테 이 블 에 존 재 하 지 않 음 < / strong > : 값 이 다 른 테 이 블 에 없 으 면 TRUE
< br / >
( 예 : 품명이 품 목 정 보 테 이 블 에 없 으 면 자 동 등 록 )
2025-10-08 09:39:13 +09:00
< / div >
feat: 노드 기반 데이터 플로우 시스템 구현
- 노드 에디터 UI 구현 (React Flow 기반)
- TableSource, DataTransform, INSERT, UPDATE, DELETE, UPSERT 노드
- 드래그앤드롭 노드 추가 및 연결
- 속성 패널을 통한 노드 설정
- 실시간 필드 라벨 표시 (column_labels 테이블 연동)
- 데이터 변환 노드 (DataTransform) 기능
- EXPLODE: 구분자로 1개 행 → 여러 행 확장
- UPPERCASE, LOWERCASE, TRIM, CONCAT, SPLIT, REPLACE 등 12가지 변환 타입
- In-place 변환 지원 (타겟 필드 생략 시 소스 필드 덮어쓰기)
- 변환된 필드가 하위 액션 노드에 자동 전달
- 노드 플로우 실행 엔진
- 위상 정렬을 통한 노드 실행 순서 결정
- 레벨별 병렬 실행 (Promise.allSettled)
- 부분 실패 허용 (한 노드 실패 시 연결된 하위 노드만 스킵)
- 트랜잭션 기반 안전한 데이터 처리
- UPSERT 액션 로직 구현
- DB 제약 조건 없이 SELECT → UPDATE or INSERT 방식
- 복합 충돌 키 지원 (예: sales_no + product_name)
- 파라미터 인덱스 정확한 매핑
- 데이터 소스 자동 감지
- 테이블 선택 데이터 (selectedRowsData) 자동 주입
- 폼 입력 데이터 (formData) 자동 주입
- TableSource 노드가 외부 데이터 우선 사용
- 버튼 컴포넌트 통합
- 기존 관계 실행 + 새 노드 플로우 실행 하이브리드 지원
- 노드 플로우 선택 UI 추가
- API 클라이언트 통합 (Axios)
- 개발 문서 작성
- 노드 기반 제어 시스템 개선 계획
- 노드 연결 규칙 설계
- 노드 실행 엔진 설계
- 노드 구조 개선안
- 버튼 통합 분석
2025-10-02 16:22:29 +09:00
< div className = "rounded bg-yellow-50 p-3 text-xs text-yellow-700" >
2026-01-07 09:55:19 +09:00
< strong > AND < / strong > : 모 든 조 건 이 참 이 어 야 TRUE 출 력
feat: 노드 기반 데이터 플로우 시스템 구현
- 노드 에디터 UI 구현 (React Flow 기반)
- TableSource, DataTransform, INSERT, UPDATE, DELETE, UPSERT 노드
- 드래그앤드롭 노드 추가 및 연결
- 속성 패널을 통한 노드 설정
- 실시간 필드 라벨 표시 (column_labels 테이블 연동)
- 데이터 변환 노드 (DataTransform) 기능
- EXPLODE: 구분자로 1개 행 → 여러 행 확장
- UPPERCASE, LOWERCASE, TRIM, CONCAT, SPLIT, REPLACE 등 12가지 변환 타입
- In-place 변환 지원 (타겟 필드 생략 시 소스 필드 덮어쓰기)
- 변환된 필드가 하위 액션 노드에 자동 전달
- 노드 플로우 실행 엔진
- 위상 정렬을 통한 노드 실행 순서 결정
- 레벨별 병렬 실행 (Promise.allSettled)
- 부분 실패 허용 (한 노드 실패 시 연결된 하위 노드만 스킵)
- 트랜잭션 기반 안전한 데이터 처리
- UPSERT 액션 로직 구현
- DB 제약 조건 없이 SELECT → UPDATE or INSERT 방식
- 복합 충돌 키 지원 (예: sales_no + product_name)
- 파라미터 인덱스 정확한 매핑
- 데이터 소스 자동 감지
- 테이블 선택 데이터 (selectedRowsData) 자동 주입
- 폼 입력 데이터 (formData) 자동 주입
- TableSource 노드가 외부 데이터 우선 사용
- 버튼 컴포넌트 통합
- 기존 관계 실행 + 새 노드 플로우 실행 하이브리드 지원
- 노드 플로우 선택 UI 추가
- API 클라이언트 통합 (Axios)
- 개발 문서 작성
- 노드 기반 제어 시스템 개선 계획
- 노드 연결 규칙 설계
- 노드 실행 엔진 설계
- 노드 구조 개선안
- 버튼 통합 분석
2025-10-02 16:22:29 +09:00
< / div >
< div className = "rounded bg-yellow-50 p-3 text-xs text-yellow-700" >
2026-01-07 09:55:19 +09:00
< strong > OR < / strong > : 하 나 라 도 참 이 면 TRUE 출 력
feat: 노드 기반 데이터 플로우 시스템 구현
- 노드 에디터 UI 구현 (React Flow 기반)
- TableSource, DataTransform, INSERT, UPDATE, DELETE, UPSERT 노드
- 드래그앤드롭 노드 추가 및 연결
- 속성 패널을 통한 노드 설정
- 실시간 필드 라벨 표시 (column_labels 테이블 연동)
- 데이터 변환 노드 (DataTransform) 기능
- EXPLODE: 구분자로 1개 행 → 여러 행 확장
- UPPERCASE, LOWERCASE, TRIM, CONCAT, SPLIT, REPLACE 등 12가지 변환 타입
- In-place 변환 지원 (타겟 필드 생략 시 소스 필드 덮어쓰기)
- 변환된 필드가 하위 액션 노드에 자동 전달
- 노드 플로우 실행 엔진
- 위상 정렬을 통한 노드 실행 순서 결정
- 레벨별 병렬 실행 (Promise.allSettled)
- 부분 실패 허용 (한 노드 실패 시 연결된 하위 노드만 스킵)
- 트랜잭션 기반 안전한 데이터 처리
- UPSERT 액션 로직 구현
- DB 제약 조건 없이 SELECT → UPDATE or INSERT 방식
- 복합 충돌 키 지원 (예: sales_no + product_name)
- 파라미터 인덱스 정확한 매핑
- 데이터 소스 자동 감지
- 테이블 선택 데이터 (selectedRowsData) 자동 주입
- 폼 입력 데이터 (formData) 자동 주입
- TableSource 노드가 외부 데이터 우선 사용
- 버튼 컴포넌트 통합
- 기존 관계 실행 + 새 노드 플로우 실행 하이브리드 지원
- 노드 플로우 선택 UI 추가
- API 클라이언트 통합 (Axios)
- 개발 문서 작성
- 노드 기반 제어 시스템 개선 계획
- 노드 연결 규칙 설계
- 노드 실행 엔진 설계
- 노드 구조 개선안
- 버튼 통합 분석
2025-10-02 16:22:29 +09:00
< / div >
< div className = "rounded bg-yellow-50 p-3 text-xs text-yellow-700" >
2026-01-07 09:55:19 +09:00
TRUE 출 력 은 오 른 쪽 위 , FALSE 출 력 은 오 른 쪽 아 래 입 니 다 .
feat: 노드 기반 데이터 플로우 시스템 구현
- 노드 에디터 UI 구현 (React Flow 기반)
- TableSource, DataTransform, INSERT, UPDATE, DELETE, UPSERT 노드
- 드래그앤드롭 노드 추가 및 연결
- 속성 패널을 통한 노드 설정
- 실시간 필드 라벨 표시 (column_labels 테이블 연동)
- 데이터 변환 노드 (DataTransform) 기능
- EXPLODE: 구분자로 1개 행 → 여러 행 확장
- UPPERCASE, LOWERCASE, TRIM, CONCAT, SPLIT, REPLACE 등 12가지 변환 타입
- In-place 변환 지원 (타겟 필드 생략 시 소스 필드 덮어쓰기)
- 변환된 필드가 하위 액션 노드에 자동 전달
- 노드 플로우 실행 엔진
- 위상 정렬을 통한 노드 실행 순서 결정
- 레벨별 병렬 실행 (Promise.allSettled)
- 부분 실패 허용 (한 노드 실패 시 연결된 하위 노드만 스킵)
- 트랜잭션 기반 안전한 데이터 처리
- UPSERT 액션 로직 구현
- DB 제약 조건 없이 SELECT → UPDATE or INSERT 방식
- 복합 충돌 키 지원 (예: sales_no + product_name)
- 파라미터 인덱스 정확한 매핑
- 데이터 소스 자동 감지
- 테이블 선택 데이터 (selectedRowsData) 자동 주입
- 폼 입력 데이터 (formData) 자동 주입
- TableSource 노드가 외부 데이터 우선 사용
- 버튼 컴포넌트 통합
- 기존 관계 실행 + 새 노드 플로우 실행 하이브리드 지원
- 노드 플로우 선택 UI 추가
- API 클라이언트 통합 (Axios)
- 개발 문서 작성
- 노드 기반 제어 시스템 개선 계획
- 노드 연결 규칙 설계
- 노드 실행 엔진 설계
- 노드 구조 개선안
- 버튼 통합 분석
2025-10-02 16:22:29 +09:00
< / div >
< / div >
< / div >
2025-10-24 15:40:08 +09:00
< / div >
feat: 노드 기반 데이터 플로우 시스템 구현
- 노드 에디터 UI 구현 (React Flow 기반)
- TableSource, DataTransform, INSERT, UPDATE, DELETE, UPSERT 노드
- 드래그앤드롭 노드 추가 및 연결
- 속성 패널을 통한 노드 설정
- 실시간 필드 라벨 표시 (column_labels 테이블 연동)
- 데이터 변환 노드 (DataTransform) 기능
- EXPLODE: 구분자로 1개 행 → 여러 행 확장
- UPPERCASE, LOWERCASE, TRIM, CONCAT, SPLIT, REPLACE 등 12가지 변환 타입
- In-place 변환 지원 (타겟 필드 생략 시 소스 필드 덮어쓰기)
- 변환된 필드가 하위 액션 노드에 자동 전달
- 노드 플로우 실행 엔진
- 위상 정렬을 통한 노드 실행 순서 결정
- 레벨별 병렬 실행 (Promise.allSettled)
- 부분 실패 허용 (한 노드 실패 시 연결된 하위 노드만 스킵)
- 트랜잭션 기반 안전한 데이터 처리
- UPSERT 액션 로직 구현
- DB 제약 조건 없이 SELECT → UPDATE or INSERT 방식
- 복합 충돌 키 지원 (예: sales_no + product_name)
- 파라미터 인덱스 정확한 매핑
- 데이터 소스 자동 감지
- 테이블 선택 데이터 (selectedRowsData) 자동 주입
- 폼 입력 데이터 (formData) 자동 주입
- TableSource 노드가 외부 데이터 우선 사용
- 버튼 컴포넌트 통합
- 기존 관계 실행 + 새 노드 플로우 실행 하이브리드 지원
- 노드 플로우 선택 UI 추가
- API 클라이언트 통합 (Axios)
- 개발 문서 작성
- 노드 기반 제어 시스템 개선 계획
- 노드 연결 규칙 설계
- 노드 실행 엔진 설계
- 노드 구조 개선안
- 버튼 통합 분석
2025-10-02 16:22:29 +09:00
) ;
}