데이터 저장 설정 로직 수정

This commit is contained in:
hyeonsu 2025-09-16 14:44:41 +09:00
parent d18e78e8a0
commit c64c374142
4 changed files with 76 additions and 56 deletions

View File

@ -8,7 +8,7 @@ interface ConditionNode {
id: string; // 고유 ID id: string; // 고유 ID
type: "condition" | "group-start" | "group-end"; type: "condition" | "group-start" | "group-end";
field?: string; field?: string;
operator_type?: "=" | "!=" | ">" | "<" | ">=" | "<=" | "LIKE"; operator?: "=" | "!=" | ">" | "<" | ">=" | "<=" | "LIKE";
value?: any; value?: any;
dataType?: string; dataType?: string;
logicalOperator?: "AND" | "OR"; // 다음 조건과의 논리 연산자 logicalOperator?: "AND" | "OR"; // 다음 조건과의 논리 연산자
@ -430,15 +430,15 @@ export class EventTriggerService {
condition: ConditionNode, condition: ConditionNode,
data: Record<string, any> data: Record<string, any>
): boolean { ): boolean {
const { field, operator_type, value } = condition; const { field, operator, value } = condition;
if (!field || !operator_type) { if (!field || !operator) {
return false; return false;
} }
const fieldValue = data[field]; const fieldValue = data[field];
switch (operator_type) { switch (operator) {
case "=": case "=":
return fieldValue == value; return fieldValue == value;
case "!=": case "!=":
@ -628,9 +628,9 @@ export class EventTriggerService {
if ( if (
conditions.type === "condition" && conditions.type === "condition" &&
conditions.field && 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"; // 기본값 return "1=1"; // 기본값

View File

@ -193,26 +193,34 @@ export const ConnectionSetupModal: React.FC<ConnectionSetupModalProps> = ({
// data-save 설정 로드 - 안전하게 처리 // data-save 설정 로드 - 안전하게 처리
const actionsData = Array.isArray(settings.actions) ? settings.actions : []; const actionsData = Array.isArray(settings.actions) ? settings.actions : [];
setDataSaveSettings({ setDataSaveSettings({
actions: actionsData.map((action: any) => ({ actions: actionsData.map((action: Record<string, unknown>) => ({
id: action.id || `action-${Date.now()}`, id: (action.id as string) || `action-${Date.now()}`,
name: action.name || "새 액션", name: (action.name as string) || "새 액션",
actionType: action.actionType || "insert", actionType: (action.actionType as "insert" | "update" | "delete" | "upsert") || "insert",
conditions: Array.isArray(action.conditions) ? action.conditions : [], conditions: Array.isArray(action.conditions)
? action.conditions.map(
(condition: Record<string, unknown>) =>
({
...condition,
operator: condition.operator || "=", // 기본값 보장
}) as ConditionNode,
)
: [],
fieldMappings: Array.isArray(action.fieldMappings) fieldMappings: Array.isArray(action.fieldMappings)
? action.fieldMappings.map((mapping: any) => ({ ? action.fieldMappings.map((mapping: Record<string, unknown>) => ({
sourceTable: mapping.sourceTable || "", sourceTable: (mapping.sourceTable as string) || "",
sourceField: mapping.sourceField || "", sourceField: (mapping.sourceField as string) || "",
targetTable: mapping.targetTable || "", targetTable: (mapping.targetTable as string) || "",
targetField: mapping.targetField || "", targetField: (mapping.targetField as string) || "",
defaultValue: mapping.defaultValue || "", defaultValue: (mapping.defaultValue as string) || "",
transformFunction: mapping.transformFunction || "", transformFunction: (mapping.transformFunction as string) || "",
})) }))
: [], : [],
splitConfig: action.splitConfig splitConfig: action.splitConfig
? { ? {
sourceField: action.splitConfig.sourceField || "", sourceField: ((action.splitConfig as Record<string, unknown>).sourceField as string) || "",
delimiter: action.splitConfig.delimiter || ",", delimiter: ((action.splitConfig as Record<string, unknown>).delimiter as string) || ",",
targetField: action.splitConfig.targetField || "", targetField: ((action.splitConfig as Record<string, unknown>).targetField as string) || "",
} }
: undefined, : undefined,
})), })),
@ -426,7 +434,15 @@ export const ConnectionSetupModal: React.FC<ConnectionSetupModalProps> = ({
id: action.id, id: action.id,
actionType: action.actionType, actionType: action.actionType,
enabled: true, 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) => ({ fieldMappings: action.fieldMappings.map((mapping) => ({
sourceTable: mapping.sourceTable, sourceTable: mapping.sourceTable,
sourceField: mapping.sourceField, sourceField: mapping.sourceField,
@ -497,14 +513,14 @@ export const ConnectionSetupModal: React.FC<ConnectionSetupModalProps> = ({
const addCondition = () => { const addCondition = () => {
const newCondition: ConditionNode = { const newCondition: ConditionNode = {
id: generateId(), id: generateId(),
type: "condition", type: "condition" as const,
field: "", field: "",
operator_type: "=", operator: "=",
value: "", value: "",
dataType: "string", dataType: "string",
// 첫 번째 조건이 아니고, 바로 앞이 group-start가 아니면 logicalOperator 추가 // 첫 번째 조건이 아니고, 바로 앞이 group-start가 아니면 logicalOperator 추가
...(conditions.length > 0 && ...(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]); setConditions([...conditions, newCondition]);
@ -517,11 +533,11 @@ export const ConnectionSetupModal: React.FC<ConnectionSetupModalProps> = ({
const groupStart: ConditionNode = { const groupStart: ConditionNode = {
id: generateId(), id: generateId(),
type: "group-start", type: "group-start" as const,
groupId, groupId,
groupLevel, groupLevel,
// 첫 번째 그룹이 아니면 logicalOperator 추가 // 첫 번째 그룹이 아니면 logicalOperator 추가
...(conditions.length > 0 && { logicalOperator: "AND" }), ...(conditions.length > 0 && { logicalOperator: "AND" as const }),
}; };
setConditions([...conditions, groupStart]); setConditions([...conditions, groupStart]);
@ -539,7 +555,7 @@ export const ConnectionSetupModal: React.FC<ConnectionSetupModalProps> = ({
const lastOpenGroup = openGroups[openGroups.length - 1]; const lastOpenGroup = openGroups[openGroups.length - 1];
const groupEnd: ConditionNode = { const groupEnd: ConditionNode = {
id: generateId(), id: generateId(),
type: "group-end", type: "group-end" as const,
groupId: lastOpenGroup.groupId, groupId: lastOpenGroup.groupId,
groupLevel: lastOpenGroup.groupLevel, groupLevel: lastOpenGroup.groupLevel,
}; };
@ -621,10 +637,11 @@ export const ConnectionSetupModal: React.FC<ConnectionSetupModalProps> = ({
const groupStart: ConditionNode = { const groupStart: ConditionNode = {
id: generateId(), id: generateId(),
type: "group-start", type: "group-start" as const,
groupId, groupId,
groupLevel, groupLevel,
logicalOperator: currentConditions.length > 0 ? "AND" : undefined, // 첫 번째 그룹이 아니면 logicalOperator 추가
...(currentConditions.length > 0 && { logicalOperator: "AND" as const }),
}; };
const newActions = [...dataSaveSettings.actions]; const newActions = [...dataSaveSettings.actions];
@ -644,7 +661,7 @@ export const ConnectionSetupModal: React.FC<ConnectionSetupModalProps> = ({
const lastOpenGroup = openGroups[openGroups.length - 1]; const lastOpenGroup = openGroups[openGroups.length - 1];
const groupEnd: ConditionNode = { const groupEnd: ConditionNode = {
id: generateId(), id: generateId(),
type: "group-end", type: "group-end" as const,
groupId: lastOpenGroup.groupId, groupId: lastOpenGroup.groupId,
groupLevel: lastOpenGroup.groupLevel, groupLevel: lastOpenGroup.groupLevel,
}; };
@ -822,10 +839,10 @@ export const ConnectionSetupModal: React.FC<ConnectionSetupModalProps> = ({
</SelectContent> </SelectContent>
</Select> </Select>
<Select <Select
value={condition.operator_type || "="} value={condition.operator || "="}
onValueChange={(value: "=" | "!=" | ">" | "<" | ">=" | "<=" | "LIKE") => { onValueChange={(value: "=" | "!=" | ">" | "<" | ">=" | "<=" | "LIKE") => {
const newActions = [...dataSaveSettings.actions]; const newActions = [...dataSaveSettings.actions];
newActions[actionIndex].conditions![condIndex].operator_type = value; newActions[actionIndex].conditions![condIndex].operator = value;
setDataSaveSettings({ ...dataSaveSettings, actions: newActions }); setDataSaveSettings({ ...dataSaveSettings, actions: newActions });
}} }}
> >
@ -1122,8 +1139,8 @@ export const ConnectionSetupModal: React.FC<ConnectionSetupModalProps> = ({
{/* 연산자 선택 */} {/* 연산자 선택 */}
<Select <Select
value={condition.operator_type || "="} value={condition.operator || "="}
onValueChange={(value) => updateCondition(index, "operator_type", value)} onValueChange={(value) => updateCondition(index, "operator", value)}
> >
<SelectTrigger className="h-8 w-20 text-xs"> <SelectTrigger className="h-8 w-20 text-xs">
<SelectValue /> <SelectValue />
@ -1532,18 +1549,21 @@ export const ConnectionSetupModal: React.FC<ConnectionSetupModalProps> = ({
if (!newActions[actionIndex].conditions) { if (!newActions[actionIndex].conditions) {
newActions[actionIndex].conditions = []; newActions[actionIndex].conditions = [];
} }
newActions[actionIndex].conditions = [ const currentConditions = newActions[actionIndex].conditions || [];
...(newActions[actionIndex].conditions || []), const newCondition: ConditionNode = {
{ id: generateId(),
id: generateId(), type: "condition" as const,
type: "condition", field: "",
field: "", operator: "=",
operator_type: "=", value: "",
value: "", dataType: "string",
dataType: "string", // 첫 번째 조건이 아니고, 바로 앞이 group-start가 아니면 logicalOperator 추가
logicalOperator: "AND", ...(currentConditions.length > 0 &&
}, currentConditions[currentConditions.length - 1]?.type !== "group-start" && {
]; logicalOperator: "AND" as const,
}),
};
newActions[actionIndex].conditions = [...currentConditions, newCondition];
setDataSaveSettings({ ...dataSaveSettings, actions: newActions }); setDataSaveSettings({ ...dataSaveSettings, actions: newActions });
}} }}
className="h-6 text-xs" className="h-6 text-xs"

View File

@ -81,7 +81,7 @@ interface ExtendedJsonRelationship extends JsonRelationship {
id: string; id: string;
type: string; type: string;
field?: string; field?: string;
operator_type?: string; operator?: string;
value?: unknown; value?: unknown;
logicalOperator?: string; logicalOperator?: string;
groupId?: string; groupId?: string;
@ -96,7 +96,7 @@ interface ExtendedJsonRelationship extends JsonRelationship {
id: string; id: string;
type: string; type: string;
field?: string; field?: string;
operator_type?: string; operator?: string;
value?: unknown; value?: unknown;
logicalOperator?: string; logicalOperator?: string;
groupId?: string; groupId?: string;
@ -942,7 +942,7 @@ export const DataFlowDesigner: React.FC<DataFlowDesignerProps> = ({
id: string; id: string;
type: string; type: string;
field?: string; field?: string;
operator_type?: "=" | "!=" | ">" | "<" | ">=" | "<=" | "LIKE"; operator?: "=" | "!=" | ">" | "<" | ">=" | "<=" | "LIKE";
value?: unknown; value?: unknown;
logicalOperator?: "AND" | "OR"; logicalOperator?: "AND" | "OR";
groupId?: string; groupId?: string;
@ -981,7 +981,7 @@ export const DataFlowDesigner: React.FC<DataFlowDesignerProps> = ({
id: cond.id, id: cond.id,
type: cond.type, type: cond.type,
field: cond.field, field: cond.field,
operator: cond.operator_type, operator: cond.operator,
value: cond.value, value: cond.value,
dataType: "string", // 기본값 dataType: "string", // 기본값
// 첫 번째 조건이 아닐 때만 logicalOperator 포함 // 첫 번째 조건이 아닐 때만 logicalOperator 포함
@ -1025,7 +1025,7 @@ export const DataFlowDesigner: React.FC<DataFlowDesignerProps> = ({
id: string; id: string;
type: string; type: string;
field?: string; field?: string;
operator_type?: string; operator?: string;
value?: unknown; value?: unknown;
logicalOperator?: string; logicalOperator?: string;
groupId?: string; groupId?: string;
@ -1085,7 +1085,7 @@ export const DataFlowDesigner: React.FC<DataFlowDesignerProps> = ({
field: cond.field, field: cond.field,
value: cond.value, value: cond.value,
dataType: "string", // 기본값 dataType: "string", // 기본값
operator_type: cond.operator_type, operator: cond.operator,
// 첫 번째 조건이 아닐 때만 logicalOperator 포함 // 첫 번째 조건이 아닐 때만 logicalOperator 포함
...(index > 0 && cond.logicalOperator && { logicalOperator: cond.logicalOperator }), ...(index > 0 && cond.logicalOperator && { logicalOperator: cond.logicalOperator }),
}; };

View File

@ -12,7 +12,7 @@ export interface ConditionNode {
id: string; // 고유 ID id: string; // 고유 ID
type: "condition" | "group-start" | "group-end"; type: "condition" | "group-start" | "group-end";
field?: string; field?: string;
operator_type?: "=" | "!=" | ">" | "<" | ">=" | "<=" | "LIKE"; operator?: "=" | "!=" | ">" | "<" | ">=" | "<=" | "LIKE";
value?: string | number | boolean; value?: string | number | boolean;
dataType?: string; dataType?: string;
logicalOperator?: "AND" | "OR"; // 다음 조건과의 논리 연산자 logicalOperator?: "AND" | "OR"; // 다음 조건과의 논리 연산자
@ -224,7 +224,7 @@ export interface JsonDataFlowDiagram {
id: string; id: string;
type: string; type: string;
field?: string; field?: string;
operator_type?: string; operator?: string;
value?: unknown; value?: unknown;
logicalOperator?: string; logicalOperator?: string;
groupId?: string; groupId?: string;
@ -315,7 +315,7 @@ export interface CreateDiagramRequest {
id: string; id: string;
type: string; type: string;
field?: string; field?: string;
operator_type?: string; operator?: string;
value?: unknown; value?: unknown;
dataType?: string; dataType?: string;
logicalOperator?: string; logicalOperator?: string;