diff --git a/backend-node/src/services/eventTriggerService.ts b/backend-node/src/services/eventTriggerService.ts index 6a26fcb5..758455c6 100644 --- a/backend-node/src/services/eventTriggerService.ts +++ b/backend-node/src/services/eventTriggerService.ts @@ -8,7 +8,7 @@ interface ConditionNode { id: string; // 고유 ID type: "condition" | "group-start" | "group-end"; field?: string; - operator_type?: "=" | "!=" | ">" | "<" | ">=" | "<=" | "LIKE"; + operator?: "=" | "!=" | ">" | "<" | ">=" | "<=" | "LIKE"; value?: any; dataType?: string; logicalOperator?: "AND" | "OR"; // 다음 조건과의 논리 연산자 @@ -430,15 +430,15 @@ export class EventTriggerService { condition: ConditionNode, data: Record ): boolean { - const { field, operator_type, value } = condition; + const { field, operator, value } = condition; - if (!field || !operator_type) { + if (!field || !operator) { return false; } const fieldValue = data[field]; - switch (operator_type) { + switch (operator) { case "=": return fieldValue == value; case "!=": @@ -628,9 +628,9 @@ export class EventTriggerService { if ( conditions.type === "condition" && conditions.field && - conditions.operator_type + conditions.operator ) { - return `${conditions.field} ${conditions.operator_type} '${conditions.value}'`; + return `${conditions.field} ${conditions.operator} '${conditions.value}'`; } return "1=1"; // 기본값 diff --git a/frontend/components/dataflow/ConnectionSetupModal.tsx b/frontend/components/dataflow/ConnectionSetupModal.tsx index 883a7f95..9b0bf788 100644 --- a/frontend/components/dataflow/ConnectionSetupModal.tsx +++ b/frontend/components/dataflow/ConnectionSetupModal.tsx @@ -193,26 +193,34 @@ export const ConnectionSetupModal: React.FC = ({ // data-save 설정 로드 - 안전하게 처리 const actionsData = Array.isArray(settings.actions) ? settings.actions : []; setDataSaveSettings({ - actions: actionsData.map((action: any) => ({ - id: action.id || `action-${Date.now()}`, - name: action.name || "새 액션", - actionType: action.actionType || "insert", - conditions: Array.isArray(action.conditions) ? action.conditions : [], + actions: actionsData.map((action: Record) => ({ + id: (action.id as string) || `action-${Date.now()}`, + name: (action.name as string) || "새 액션", + actionType: (action.actionType as "insert" | "update" | "delete" | "upsert") || "insert", + conditions: Array.isArray(action.conditions) + ? action.conditions.map( + (condition: Record) => + ({ + ...condition, + operator: condition.operator || "=", // 기본값 보장 + }) as ConditionNode, + ) + : [], fieldMappings: Array.isArray(action.fieldMappings) - ? action.fieldMappings.map((mapping: any) => ({ - sourceTable: mapping.sourceTable || "", - sourceField: mapping.sourceField || "", - targetTable: mapping.targetTable || "", - targetField: mapping.targetField || "", - defaultValue: mapping.defaultValue || "", - transformFunction: mapping.transformFunction || "", + ? action.fieldMappings.map((mapping: Record) => ({ + sourceTable: (mapping.sourceTable as string) || "", + sourceField: (mapping.sourceField as string) || "", + targetTable: (mapping.targetTable as string) || "", + targetField: (mapping.targetField as string) || "", + defaultValue: (mapping.defaultValue as string) || "", + transformFunction: (mapping.transformFunction as string) || "", })) : [], splitConfig: action.splitConfig ? { - sourceField: action.splitConfig.sourceField || "", - delimiter: action.splitConfig.delimiter || ",", - targetField: action.splitConfig.targetField || "", + sourceField: ((action.splitConfig as Record).sourceField as string) || "", + delimiter: ((action.splitConfig as Record).delimiter as string) || ",", + targetField: ((action.splitConfig as Record).targetField as string) || "", } : undefined, })), @@ -426,7 +434,15 @@ export const ConnectionSetupModal: React.FC = ({ id: action.id, actionType: action.actionType, enabled: true, - conditions: action.conditions, + conditions: + action.conditions?.map((condition) => { + // 모든 조건 타입에 대해 operator 필드 보장 + const baseCondition = { ...condition }; + if (condition.type === "condition") { + baseCondition.operator = condition.operator || "="; + } + return baseCondition; + }) || [], fieldMappings: action.fieldMappings.map((mapping) => ({ sourceTable: mapping.sourceTable, sourceField: mapping.sourceField, @@ -497,14 +513,14 @@ export const ConnectionSetupModal: React.FC = ({ const addCondition = () => { const newCondition: ConditionNode = { id: generateId(), - type: "condition", + type: "condition" as const, field: "", - operator_type: "=", + operator: "=", value: "", dataType: "string", // 첫 번째 조건이 아니고, 바로 앞이 group-start가 아니면 logicalOperator 추가 ...(conditions.length > 0 && - conditions[conditions.length - 1]?.type !== "group-start" && { logicalOperator: "AND" }), + conditions[conditions.length - 1]?.type !== "group-start" && { logicalOperator: "AND" as const }), }; setConditions([...conditions, newCondition]); @@ -517,11 +533,11 @@ export const ConnectionSetupModal: React.FC = ({ const groupStart: ConditionNode = { id: generateId(), - type: "group-start", + type: "group-start" as const, groupId, groupLevel, // 첫 번째 그룹이 아니면 logicalOperator 추가 - ...(conditions.length > 0 && { logicalOperator: "AND" }), + ...(conditions.length > 0 && { logicalOperator: "AND" as const }), }; setConditions([...conditions, groupStart]); @@ -539,7 +555,7 @@ export const ConnectionSetupModal: React.FC = ({ const lastOpenGroup = openGroups[openGroups.length - 1]; const groupEnd: ConditionNode = { id: generateId(), - type: "group-end", + type: "group-end" as const, groupId: lastOpenGroup.groupId, groupLevel: lastOpenGroup.groupLevel, }; @@ -621,10 +637,11 @@ export const ConnectionSetupModal: React.FC = ({ const groupStart: ConditionNode = { id: generateId(), - type: "group-start", + type: "group-start" as const, groupId, groupLevel, - logicalOperator: currentConditions.length > 0 ? "AND" : undefined, + // 첫 번째 그룹이 아니면 logicalOperator 추가 + ...(currentConditions.length > 0 && { logicalOperator: "AND" as const }), }; const newActions = [...dataSaveSettings.actions]; @@ -644,7 +661,7 @@ export const ConnectionSetupModal: React.FC = ({ const lastOpenGroup = openGroups[openGroups.length - 1]; const groupEnd: ConditionNode = { id: generateId(), - type: "group-end", + type: "group-end" as const, groupId: lastOpenGroup.groupId, groupLevel: lastOpenGroup.groupLevel, }; @@ -822,10 +839,10 @@ export const ConnectionSetupModal: React.FC = ({ @@ -1532,18 +1549,21 @@ export const ConnectionSetupModal: React.FC = ({ if (!newActions[actionIndex].conditions) { newActions[actionIndex].conditions = []; } - newActions[actionIndex].conditions = [ - ...(newActions[actionIndex].conditions || []), - { - id: generateId(), - type: "condition", - field: "", - operator_type: "=", - value: "", - dataType: "string", - logicalOperator: "AND", - }, - ]; + const currentConditions = newActions[actionIndex].conditions || []; + const newCondition: ConditionNode = { + id: generateId(), + type: "condition" as const, + field: "", + operator: "=", + value: "", + dataType: "string", + // 첫 번째 조건이 아니고, 바로 앞이 group-start가 아니면 logicalOperator 추가 + ...(currentConditions.length > 0 && + currentConditions[currentConditions.length - 1]?.type !== "group-start" && { + logicalOperator: "AND" as const, + }), + }; + newActions[actionIndex].conditions = [...currentConditions, newCondition]; setDataSaveSettings({ ...dataSaveSettings, actions: newActions }); }} className="h-6 text-xs" diff --git a/frontend/components/dataflow/DataFlowDesigner.tsx b/frontend/components/dataflow/DataFlowDesigner.tsx index 0cfa551d..297a9838 100644 --- a/frontend/components/dataflow/DataFlowDesigner.tsx +++ b/frontend/components/dataflow/DataFlowDesigner.tsx @@ -81,7 +81,7 @@ interface ExtendedJsonRelationship extends JsonRelationship { id: string; type: string; field?: string; - operator_type?: string; + operator?: string; value?: unknown; logicalOperator?: string; groupId?: string; @@ -96,7 +96,7 @@ interface ExtendedJsonRelationship extends JsonRelationship { id: string; type: string; field?: string; - operator_type?: string; + operator?: string; value?: unknown; logicalOperator?: string; groupId?: string; @@ -942,7 +942,7 @@ export const DataFlowDesigner: React.FC = ({ id: string; type: string; field?: string; - operator_type?: "=" | "!=" | ">" | "<" | ">=" | "<=" | "LIKE"; + operator?: "=" | "!=" | ">" | "<" | ">=" | "<=" | "LIKE"; value?: unknown; logicalOperator?: "AND" | "OR"; groupId?: string; @@ -981,7 +981,7 @@ export const DataFlowDesigner: React.FC = ({ id: cond.id, type: cond.type, field: cond.field, - operator: cond.operator_type, + operator: cond.operator, value: cond.value, dataType: "string", // 기본값 // 첫 번째 조건이 아닐 때만 logicalOperator 포함 @@ -1025,7 +1025,7 @@ export const DataFlowDesigner: React.FC = ({ id: string; type: string; field?: string; - operator_type?: string; + operator?: string; value?: unknown; logicalOperator?: string; groupId?: string; @@ -1085,7 +1085,7 @@ export const DataFlowDesigner: React.FC = ({ field: cond.field, value: cond.value, dataType: "string", // 기본값 - operator_type: cond.operator_type, + operator: cond.operator, // 첫 번째 조건이 아닐 때만 logicalOperator 포함 ...(index > 0 && cond.logicalOperator && { logicalOperator: cond.logicalOperator }), }; diff --git a/frontend/lib/api/dataflow.ts b/frontend/lib/api/dataflow.ts index fabb3e5f..a3ec592c 100644 --- a/frontend/lib/api/dataflow.ts +++ b/frontend/lib/api/dataflow.ts @@ -12,7 +12,7 @@ export interface ConditionNode { id: string; // 고유 ID type: "condition" | "group-start" | "group-end"; field?: string; - operator_type?: "=" | "!=" | ">" | "<" | ">=" | "<=" | "LIKE"; + operator?: "=" | "!=" | ">" | "<" | ">=" | "<=" | "LIKE"; value?: string | number | boolean; dataType?: string; logicalOperator?: "AND" | "OR"; // 다음 조건과의 논리 연산자 @@ -224,7 +224,7 @@ export interface JsonDataFlowDiagram { id: string; type: string; field?: string; - operator_type?: string; + operator?: string; value?: unknown; logicalOperator?: string; groupId?: string; @@ -315,7 +315,7 @@ export interface CreateDiagramRequest { id: string; type: string; field?: string; - operator_type?: string; + operator?: string; value?: unknown; dataType?: string; logicalOperator?: string;