From 1d97bcaa9f9c0e88ad633246c9e7ccd94705258e Mon Sep 17 00:00:00 2001 From: dohyeons Date: Thu, 11 Dec 2025 14:34:42 +0900 Subject: [PATCH] =?UTF-8?q?=EB=B0=B0=ED=8F=AC=20=EC=98=A4=EB=A5=98=20?= =?UTF-8?q?=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cascadingAutoFillController.ts | 74 ++++++++++++++----- .../cascadingConditionController.ts | 67 +++++++++++++---- .../cascadingHierarchyController.ts | 44 ++++++++--- .../cascadingMutualExclusionController.ts | 60 +++++++++++---- .../cascadingRelationController.ts | 40 +++++++--- .../src/services/nodeFlowExecutionService.ts | 6 +- 6 files changed, 220 insertions(+), 71 deletions(-) diff --git a/backend-node/src/controllers/cascadingAutoFillController.ts b/backend-node/src/controllers/cascadingAutoFillController.ts index bf033880..4a2fa61f 100644 --- a/backend-node/src/controllers/cascadingAutoFillController.ts +++ b/backend-node/src/controllers/cascadingAutoFillController.ts @@ -3,7 +3,8 @@ * 마스터 선택 시 여러 필드 자동 입력 기능 */ -import { Request, Response } from "express"; +import { Response } from "express"; +import { AuthenticatedRequest } from "../types/auth"; import { query, queryOne } from "../database/db"; import logger from "../utils/logger"; @@ -14,7 +15,10 @@ import logger from "../utils/logger"; /** * 자동 입력 그룹 목록 조회 */ -export const getAutoFillGroups = async (req: Request, res: Response) => { +export const getAutoFillGroups = async ( + req: AuthenticatedRequest, + res: Response +) => { try { const companyCode = req.user?.companyCode || "*"; const { isActive } = req.query; @@ -47,7 +51,10 @@ export const getAutoFillGroups = async (req: Request, res: Response) => { const result = await query(sql, params); - logger.info("자동 입력 그룹 목록 조회", { count: result.length, companyCode }); + logger.info("자동 입력 그룹 목록 조회", { + count: result.length, + companyCode, + }); res.json({ success: true, @@ -66,7 +73,10 @@ export const getAutoFillGroups = async (req: Request, res: Response) => { /** * 자동 입력 그룹 상세 조회 (매핑 포함) */ -export const getAutoFillGroupDetail = async (req: Request, res: Response) => { +export const getAutoFillGroupDetail = async ( + req: AuthenticatedRequest, + res: Response +) => { try { const { groupCode } = req.params; const companyCode = req.user?.companyCode || "*"; @@ -98,7 +108,10 @@ export const getAutoFillGroupDetail = async (req: Request, res: Response) => { WHERE group_code = $1 AND company_code = $2 ORDER BY sort_order, mapping_id `; - const mappingResult = await query(mappingSql, [groupCode, groupResult.company_code]); + const mappingResult = await query(mappingSql, [ + groupCode, + groupResult.company_code, + ]); logger.info("자동 입력 그룹 상세 조회", { groupCode, companyCode }); @@ -122,7 +135,9 @@ export const getAutoFillGroupDetail = async (req: Request, res: Response) => { /** * 그룹 코드 자동 생성 함수 */ -const generateAutoFillGroupCode = async (companyCode: string): Promise => { +const generateAutoFillGroupCode = async ( + companyCode: string +): Promise => { const prefix = "AF"; const result = await queryOne( `SELECT COUNT(*) as cnt FROM cascading_auto_fill_group WHERE company_code = $1`, @@ -136,7 +151,10 @@ const generateAutoFillGroupCode = async (companyCode: string): Promise = /** * 자동 입력 그룹 생성 */ -export const createAutoFillGroup = async (req: Request, res: Response) => { +export const createAutoFillGroup = async ( + req: AuthenticatedRequest, + res: Response +) => { try { const companyCode = req.user?.companyCode || "*"; const userId = req.user?.userId || "system"; @@ -153,7 +171,8 @@ export const createAutoFillGroup = async (req: Request, res: Response) => { if (!groupName || !masterTable || !masterValueColumn) { return res.status(400).json({ success: false, - message: "필수 필드가 누락되었습니다. (groupName, masterTable, masterValueColumn)", + message: + "필수 필드가 누락되었습니다. (groupName, masterTable, masterValueColumn)", }); } @@ -224,7 +243,10 @@ export const createAutoFillGroup = async (req: Request, res: Response) => { /** * 자동 입력 그룹 수정 */ -export const updateAutoFillGroup = async (req: Request, res: Response) => { +export const updateAutoFillGroup = async ( + req: AuthenticatedRequest, + res: Response +) => { try { const { groupCode } = req.params; const companyCode = req.user?.companyCode || "*"; @@ -333,7 +355,10 @@ export const updateAutoFillGroup = async (req: Request, res: Response) => { /** * 자동 입력 그룹 삭제 */ -export const deleteAutoFillGroup = async (req: Request, res: Response) => { +export const deleteAutoFillGroup = async ( + req: AuthenticatedRequest, + res: Response +) => { try { const { groupCode } = req.params; const companyCode = req.user?.companyCode || "*"; @@ -382,7 +407,10 @@ export const deleteAutoFillGroup = async (req: Request, res: Response) => { * 마스터 옵션 목록 조회 * 자동 입력 그룹의 마스터 테이블에서 선택 가능한 옵션 목록 */ -export const getAutoFillMasterOptions = async (req: Request, res: Response) => { +export const getAutoFillMasterOptions = async ( + req: AuthenticatedRequest, + res: Response +) => { try { const { groupCode } = req.params; const companyCode = req.user?.companyCode || "*"; @@ -436,7 +464,10 @@ export const getAutoFillMasterOptions = async (req: Request, res: Response) => { const optionsResult = await query(optionsSql, optionsParams); - logger.info("자동 입력 마스터 옵션 조회", { groupCode, count: optionsResult.length }); + logger.info("자동 입력 마스터 옵션 조회", { + groupCode, + count: optionsResult.length, + }); res.json({ success: true, @@ -456,7 +487,10 @@ export const getAutoFillMasterOptions = async (req: Request, res: Response) => { * 자동 입력 데이터 조회 * 마스터 값 선택 시 자동으로 입력할 데이터 조회 */ -export const getAutoFillData = async (req: Request, res: Response) => { +export const getAutoFillData = async ( + req: AuthenticatedRequest, + res: Response +) => { try { const { groupCode } = req.params; const { masterValue } = req.query; @@ -535,9 +569,10 @@ export const getAutoFillData = async (req: Request, res: Response) => { for (const mapping of mappings) { const sourceValue = dataResult?.[mapping.source_column]; - const finalValue = sourceValue !== null && sourceValue !== undefined - ? sourceValue - : mapping.default_value; + const finalValue = + sourceValue !== null && sourceValue !== undefined + ? sourceValue + : mapping.default_value; autoFillData[mapping.target_field] = finalValue; mappingInfo.push({ @@ -549,7 +584,11 @@ export const getAutoFillData = async (req: Request, res: Response) => { }); } - logger.info("자동 입력 데이터 조회", { groupCode, masterValue, fieldCount: mappingInfo.length }); + logger.info("자동 입력 데이터 조회", { + groupCode, + masterValue, + fieldCount: mappingInfo.length, + }); res.json({ success: true, @@ -565,4 +604,3 @@ export const getAutoFillData = async (req: Request, res: Response) => { }); } }; - diff --git a/backend-node/src/controllers/cascadingConditionController.ts b/backend-node/src/controllers/cascadingConditionController.ts index cf30a725..6cc89319 100644 --- a/backend-node/src/controllers/cascadingConditionController.ts +++ b/backend-node/src/controllers/cascadingConditionController.ts @@ -3,7 +3,8 @@ * 특정 필드 값에 따라 드롭다운 옵션을 필터링하는 기능 */ -import { Request, Response } from "express"; +import { Response } from "express"; +import { AuthenticatedRequest } from "../types/auth"; import { query, queryOne } from "../database/db"; import logger from "../utils/logger"; @@ -14,7 +15,10 @@ import logger from "../utils/logger"; /** * 조건부 연쇄 규칙 목록 조회 */ -export const getConditions = async (req: Request, res: Response) => { +export const getConditions = async ( + req: AuthenticatedRequest, + res: Response +) => { try { const companyCode = req.user?.companyCode || "*"; const { isActive, relationCode, relationType } = req.query; @@ -54,7 +58,10 @@ export const getConditions = async (req: Request, res: Response) => { const result = await query(sql, params); - logger.info("조건부 연쇄 규칙 목록 조회", { count: result.length, companyCode }); + logger.info("조건부 연쇄 규칙 목록 조회", { + count: result.length, + companyCode, + }); res.json({ success: true, @@ -62,7 +69,7 @@ export const getConditions = async (req: Request, res: Response) => { }); } catch (error: any) { console.error("조건부 연쇄 규칙 목록 조회 실패:", error); - logger.error("조건부 연쇄 규칙 목록 조회 실패", { + logger.error("조건부 연쇄 규칙 목록 조회 실패", { error: error.message, stack: error.stack, }); @@ -77,7 +84,10 @@ export const getConditions = async (req: Request, res: Response) => { /** * 조건부 연쇄 규칙 상세 조회 */ -export const getConditionDetail = async (req: Request, res: Response) => { +export const getConditionDetail = async ( + req: AuthenticatedRequest, + res: Response +) => { try { const { conditionId } = req.params; const companyCode = req.user?.companyCode || "*"; @@ -118,7 +128,10 @@ export const getConditionDetail = async (req: Request, res: Response) => { /** * 조건부 연쇄 규칙 생성 */ -export const createCondition = async (req: Request, res: Response) => { +export const createCondition = async ( + req: AuthenticatedRequest, + res: Response +) => { try { const companyCode = req.user?.companyCode || "*"; const { @@ -134,10 +147,18 @@ export const createCondition = async (req: Request, res: Response) => { } = req.body; // 필수 필드 검증 - if (!relationCode || !conditionName || !conditionField || !conditionValue || !filterColumn || !filterValues) { + if ( + !relationCode || + !conditionName || + !conditionField || + !conditionValue || + !filterColumn || + !filterValues + ) { return res.status(400).json({ success: false, - message: "필수 필드가 누락되었습니다. (relationCode, conditionName, conditionField, conditionValue, filterColumn, filterValues)", + message: + "필수 필드가 누락되었습니다. (relationCode, conditionName, conditionField, conditionValue, filterColumn, filterValues)", }); } @@ -164,7 +185,11 @@ export const createCondition = async (req: Request, res: Response) => { companyCode, ]); - logger.info("조건부 연쇄 규칙 생성", { conditionId: result?.condition_id, relationCode, companyCode }); + logger.info("조건부 연쇄 규칙 생성", { + conditionId: result?.condition_id, + relationCode, + companyCode, + }); res.status(201).json({ success: true, @@ -184,7 +209,10 @@ export const createCondition = async (req: Request, res: Response) => { /** * 조건부 연쇄 규칙 수정 */ -export const updateCondition = async (req: Request, res: Response) => { +export const updateCondition = async ( + req: AuthenticatedRequest, + res: Response +) => { try { const { conditionId } = req.params; const companyCode = req.user?.companyCode || "*"; @@ -264,7 +292,10 @@ export const updateCondition = async (req: Request, res: Response) => { /** * 조건부 연쇄 규칙 삭제 */ -export const deleteCondition = async (req: Request, res: Response) => { +export const deleteCondition = async ( + req: AuthenticatedRequest, + res: Response +) => { try { const { conditionId } = req.params; const companyCode = req.user?.companyCode || "*"; @@ -312,7 +343,10 @@ export const deleteCondition = async (req: Request, res: Response) => { * 조건에 따른 필터링된 옵션 조회 * 특정 관계 코드에 대해 조건 필드 값에 따라 필터링된 옵션 반환 */ -export const getFilteredOptions = async (req: Request, res: Response) => { +export const getFilteredOptions = async ( + req: AuthenticatedRequest, + res: Response +) => { try { const { relationCode } = req.params; const { conditionFieldValue, parentValue } = req.query; @@ -390,8 +424,12 @@ export const getFilteredOptions = async (req: Request, res: Response) => { // 조건부 필터 적용 if (matchedCondition) { - const filterValues = matchedCondition.filter_values.split(",").map((v: string) => v.trim()); - const placeholders = filterValues.map((_: any, i: number) => `$${optionsParamIndex + i}`).join(","); + const filterValues = matchedCondition.filter_values + .split(",") + .map((v: string) => v.trim()); + const placeholders = filterValues + .map((_: any, i: number) => `$${optionsParamIndex + i}`) + .join(","); optionsSql += ` AND ${matchedCondition.filter_column} IN (${placeholders})`; optionsParams.push(...filterValues); optionsParamIndex += filterValues.length; @@ -522,4 +560,3 @@ function evaluateCondition( return false; } } - diff --git a/backend-node/src/controllers/cascadingHierarchyController.ts b/backend-node/src/controllers/cascadingHierarchyController.ts index 59d243e2..e57efa09 100644 --- a/backend-node/src/controllers/cascadingHierarchyController.ts +++ b/backend-node/src/controllers/cascadingHierarchyController.ts @@ -3,7 +3,8 @@ * 국가 > 도시 > 구/군 같은 다단계 연쇄 드롭다운 관리 */ -import { Request, Response } from "express"; +import { Response } from "express"; +import { AuthenticatedRequest } from "../types/auth"; import { query, queryOne } from "../database/db"; import logger from "../utils/logger"; @@ -14,7 +15,10 @@ import logger from "../utils/logger"; /** * 계층 그룹 목록 조회 */ -export const getHierarchyGroups = async (req: Request, res: Response) => { +export const getHierarchyGroups = async ( + req: AuthenticatedRequest, + res: Response +) => { try { const companyCode = req.user?.companyCode || "*"; const { isActive, hierarchyType } = req.query; @@ -66,7 +70,10 @@ export const getHierarchyGroups = async (req: Request, res: Response) => { /** * 계층 그룹 상세 조회 (레벨 포함) */ -export const getHierarchyGroupDetail = async (req: Request, res: Response) => { +export const getHierarchyGroupDetail = async ( + req: AuthenticatedRequest, + res: Response +) => { try { const { groupCode } = req.params; const companyCode = req.user?.companyCode || "*"; @@ -124,7 +131,9 @@ export const getHierarchyGroupDetail = async (req: Request, res: Response) => { /** * 계층 그룹 코드 자동 생성 함수 */ -const generateHierarchyGroupCode = async (companyCode: string): Promise => { +const generateHierarchyGroupCode = async ( + companyCode: string +): Promise => { const prefix = "HG"; const result = await queryOne( `SELECT COUNT(*) as cnt FROM cascading_hierarchy_group WHERE company_code = $1`, @@ -138,7 +147,10 @@ const generateHierarchyGroupCode = async (companyCode: string): Promise /** * 계층 그룹 생성 */ -export const createHierarchyGroup = async (req: Request, res: Response) => { +export const createHierarchyGroup = async ( + req: AuthenticatedRequest, + res: Response +) => { try { const companyCode = req.user?.companyCode || "*"; const userId = req.user?.userId || "system"; @@ -280,7 +292,10 @@ export const createHierarchyGroup = async (req: Request, res: Response) => { /** * 계층 그룹 수정 */ -export const updateHierarchyGroup = async (req: Request, res: Response) => { +export const updateHierarchyGroup = async ( + req: AuthenticatedRequest, + res: Response +) => { try { const { groupCode } = req.params; const companyCode = req.user?.companyCode || "*"; @@ -364,7 +379,10 @@ export const updateHierarchyGroup = async (req: Request, res: Response) => { /** * 계층 그룹 삭제 */ -export const deleteHierarchyGroup = async (req: Request, res: Response) => { +export const deleteHierarchyGroup = async ( + req: AuthenticatedRequest, + res: Response +) => { try { const { groupCode } = req.params; const companyCode = req.user?.companyCode || "*"; @@ -423,7 +441,7 @@ export const deleteHierarchyGroup = async (req: Request, res: Response) => { /** * 레벨 추가 */ -export const addLevel = async (req: Request, res: Response) => { +export const addLevel = async (req: AuthenticatedRequest, res: Response) => { try { const { groupCode } = req.params; const companyCode = req.user?.companyCode || "*"; @@ -506,7 +524,7 @@ export const addLevel = async (req: Request, res: Response) => { /** * 레벨 수정 */ -export const updateLevel = async (req: Request, res: Response) => { +export const updateLevel = async (req: AuthenticatedRequest, res: Response) => { try { const { levelId } = req.params; const companyCode = req.user?.companyCode || "*"; @@ -600,7 +618,7 @@ export const updateLevel = async (req: Request, res: Response) => { /** * 레벨 삭제 */ -export const deleteLevel = async (req: Request, res: Response) => { +export const deleteLevel = async (req: AuthenticatedRequest, res: Response) => { try { const { levelId } = req.params; const companyCode = req.user?.companyCode || "*"; @@ -647,7 +665,10 @@ export const deleteLevel = async (req: Request, res: Response) => { /** * 특정 레벨의 옵션 조회 */ -export const getLevelOptions = async (req: Request, res: Response) => { +export const getLevelOptions = async ( + req: AuthenticatedRequest, + res: Response +) => { try { const { groupCode, levelOrder } = req.params; const { parentValue } = req.query; @@ -749,4 +770,3 @@ export const getLevelOptions = async (req: Request, res: Response) => { }); } }; - diff --git a/backend-node/src/controllers/cascadingMutualExclusionController.ts b/backend-node/src/controllers/cascadingMutualExclusionController.ts index 8714c73b..b1cbeaa6 100644 --- a/backend-node/src/controllers/cascadingMutualExclusionController.ts +++ b/backend-node/src/controllers/cascadingMutualExclusionController.ts @@ -3,7 +3,8 @@ * 두 필드가 같은 값을 선택할 수 없도록 제한하는 기능 */ -import { Request, Response } from "express"; +import { Response } from "express"; +import { AuthenticatedRequest } from "../types/auth"; import { query, queryOne } from "../database/db"; import logger from "../utils/logger"; @@ -14,7 +15,10 @@ import logger from "../utils/logger"; /** * 상호 배제 규칙 목록 조회 */ -export const getExclusions = async (req: Request, res: Response) => { +export const getExclusions = async ( + req: AuthenticatedRequest, + res: Response +) => { try { const companyCode = req.user?.companyCode || "*"; const { isActive } = req.query; @@ -42,7 +46,10 @@ export const getExclusions = async (req: Request, res: Response) => { const result = await query(sql, params); - logger.info("상호 배제 규칙 목록 조회", { count: result.length, companyCode }); + logger.info("상호 배제 규칙 목록 조회", { + count: result.length, + companyCode, + }); res.json({ success: true, @@ -61,7 +68,10 @@ export const getExclusions = async (req: Request, res: Response) => { /** * 상호 배제 규칙 상세 조회 */ -export const getExclusionDetail = async (req: Request, res: Response) => { +export const getExclusionDetail = async ( + req: AuthenticatedRequest, + res: Response +) => { try { const { exclusionId } = req.params; const companyCode = req.user?.companyCode || "*"; @@ -116,7 +126,10 @@ const generateExclusionCode = async (companyCode: string): Promise => { /** * 상호 배제 규칙 생성 */ -export const createExclusion = async (req: Request, res: Response) => { +export const createExclusion = async ( + req: AuthenticatedRequest, + res: Response +) => { try { const companyCode = req.user?.companyCode || "*"; const { @@ -133,7 +146,8 @@ export const createExclusion = async (req: Request, res: Response) => { if (!exclusionName || !fieldNames || !sourceTable || !valueColumn) { return res.status(400).json({ success: false, - message: "필수 필드가 누락되었습니다. (exclusionName, fieldNames, sourceTable, valueColumn)", + message: + "필수 필드가 누락되었습니다. (exclusionName, fieldNames, sourceTable, valueColumn)", }); } @@ -195,7 +209,10 @@ export const createExclusion = async (req: Request, res: Response) => { /** * 상호 배제 규칙 수정 */ -export const updateExclusion = async (req: Request, res: Response) => { +export const updateExclusion = async ( + req: AuthenticatedRequest, + res: Response +) => { try { const { exclusionId } = req.params; const companyCode = req.user?.companyCode || "*"; @@ -274,7 +291,10 @@ export const updateExclusion = async (req: Request, res: Response) => { /** * 상호 배제 규칙 삭제 */ -export const deleteExclusion = async (req: Request, res: Response) => { +export const deleteExclusion = async ( + req: AuthenticatedRequest, + res: Response +) => { try { const { exclusionId } = req.params; const companyCode = req.user?.companyCode || "*"; @@ -322,7 +342,10 @@ export const deleteExclusion = async (req: Request, res: Response) => { * 상호 배제 검증 * 선택하려는 값이 다른 필드와 충돌하는지 확인 */ -export const validateExclusion = async (req: Request, res: Response) => { +export const validateExclusion = async ( + req: AuthenticatedRequest, + res: Response +) => { try { const { exclusionCode } = req.params; const { fieldValues } = req.body; // { "source_warehouse": "WH001", "target_warehouse": "WH002" } @@ -347,7 +370,9 @@ export const validateExclusion = async (req: Request, res: Response) => { } // 필드명 파싱 - const fields = exclusion.field_names.split(",").map((f: string) => f.trim()); + const fields = exclusion.field_names + .split(",") + .map((f: string) => f.trim()); // 필드 값 수집 const values: string[] = []; @@ -418,7 +443,10 @@ export const validateExclusion = async (req: Request, res: Response) => { * 필드에 대한 배제 옵션 조회 * 다른 필드에서 이미 선택한 값을 제외한 옵션 반환 */ -export const getExcludedOptions = async (req: Request, res: Response) => { +export const getExcludedOptions = async ( + req: AuthenticatedRequest, + res: Response +) => { try { const { exclusionCode } = req.params; const { currentField, selectedValues } = req.query; // selectedValues: 이미 선택된 값들 (콤마 구분) @@ -470,9 +498,14 @@ export const getExcludedOptions = async (req: Request, res: Response) => { // 이미 선택된 값 제외 if (selectedValues) { - const excludeValues = (selectedValues as string).split(",").map((v) => v.trim()).filter((v) => v); + const excludeValues = (selectedValues as string) + .split(",") + .map((v) => v.trim()) + .filter((v) => v); if (excludeValues.length > 0) { - const placeholders = excludeValues.map((_, i) => `$${optionsParamIndex + i}`).join(","); + const placeholders = excludeValues + .map((_, i) => `$${optionsParamIndex + i}`) + .join(","); optionsSql += ` AND ${exclusion.value_column} NOT IN (${placeholders})`; optionsParams.push(...excludeValues); } @@ -502,4 +535,3 @@ export const getExcludedOptions = async (req: Request, res: Response) => { }); } }; - diff --git a/backend-node/src/controllers/cascadingRelationController.ts b/backend-node/src/controllers/cascadingRelationController.ts index 3f7b5cb6..27f03c71 100644 --- a/backend-node/src/controllers/cascadingRelationController.ts +++ b/backend-node/src/controllers/cascadingRelationController.ts @@ -1,4 +1,5 @@ -import { Request, Response } from "express"; +import { Response } from "express"; +import { AuthenticatedRequest } from "../types/auth"; import { getPool } from "../database/db"; import { logger } from "../utils/logger"; @@ -7,7 +8,10 @@ const pool = getPool(); /** * 연쇄 관계 목록 조회 */ -export const getCascadingRelations = async (req: Request, res: Response) => { +export const getCascadingRelations = async ( + req: AuthenticatedRequest, + res: Response +) => { try { const companyCode = req.user?.companyCode || "*"; const { isActive } = req.query; @@ -86,7 +90,10 @@ export const getCascadingRelations = async (req: Request, res: Response) => { /** * 연쇄 관계 상세 조회 */ -export const getCascadingRelationById = async (req: Request, res: Response) => { +export const getCascadingRelationById = async ( + req: AuthenticatedRequest, + res: Response +) => { try { const { id } = req.params; const companyCode = req.user?.companyCode || "*"; @@ -155,7 +162,7 @@ export const getCascadingRelationById = async (req: Request, res: Response) => { * 연쇄 관계 코드로 조회 */ export const getCascadingRelationByCode = async ( - req: Request, + req: AuthenticatedRequest, res: Response ) => { try { @@ -223,7 +230,10 @@ export const getCascadingRelationByCode = async ( /** * 연쇄 관계 생성 */ -export const createCascadingRelation = async (req: Request, res: Response) => { +export const createCascadingRelation = async ( + req: AuthenticatedRequest, + res: Response +) => { try { const companyCode = req.user?.companyCode || "*"; const userId = req.user?.userId || "system"; @@ -350,7 +360,10 @@ export const createCascadingRelation = async (req: Request, res: Response) => { /** * 연쇄 관계 수정 */ -export const updateCascadingRelation = async (req: Request, res: Response) => { +export const updateCascadingRelation = async ( + req: AuthenticatedRequest, + res: Response +) => { try { const { id } = req.params; const companyCode = req.user?.companyCode || "*"; @@ -474,7 +487,10 @@ export const updateCascadingRelation = async (req: Request, res: Response) => { /** * 연쇄 관계 삭제 */ -export const deleteCascadingRelation = async (req: Request, res: Response) => { +export const deleteCascadingRelation = async ( + req: AuthenticatedRequest, + res: Response +) => { try { const { id } = req.params; const companyCode = req.user?.companyCode || "*"; @@ -536,7 +552,10 @@ export const deleteCascadingRelation = async (req: Request, res: Response) => { * 🆕 연쇄 관계로 부모 옵션 조회 (상위 선택 역할용) * parent_table에서 전체 옵션을 조회합니다. */ -export const getParentOptions = async (req: Request, res: Response) => { +export const getParentOptions = async ( + req: AuthenticatedRequest, + res: Response +) => { try { const { code } = req.params; const companyCode = req.user?.companyCode || "*"; @@ -644,7 +663,10 @@ export const getParentOptions = async (req: Request, res: Response) => { * 연쇄 관계로 자식 옵션 조회 * 실제 연쇄 드롭다운에서 사용하는 API */ -export const getCascadingOptions = async (req: Request, res: Response) => { +export const getCascadingOptions = async ( + req: AuthenticatedRequest, + res: Response +) => { try { const { code } = req.params; const { parentValue } = req.query; diff --git a/backend-node/src/services/nodeFlowExecutionService.ts b/backend-node/src/services/nodeFlowExecutionService.ts index 461cd8d2..6f481198 100644 --- a/backend-node/src/services/nodeFlowExecutionService.ts +++ b/backend-node/src/services/nodeFlowExecutionService.ts @@ -3596,7 +3596,7 @@ export class NodeFlowExecutionService { // 계정 ID 우선순위: nodeAccountId > smtpConfigId > 첫 번째 활성 계정 let accountId = nodeAccountId || smtpConfigId; if (!accountId) { - const accounts = await mailAccountFileService.getAccounts(); + const accounts = await mailAccountFileService.getAllAccounts(); const activeAccount = accounts.find( (acc: any) => acc.status === "active" ); @@ -4216,7 +4216,7 @@ export class NodeFlowExecutionService { return this.evaluateFunction(func, sourceRow, targetRow, resultValues); case "condition": - return this.evaluateCondition( + return this.evaluateCaseCondition( condition, sourceRow, targetRow, @@ -4393,7 +4393,7 @@ export class NodeFlowExecutionService { /** * 조건 평가 (CASE WHEN ... THEN ... ELSE) */ - private static evaluateCondition( + private static evaluateCaseCondition( condition: any, sourceRow: any, targetRow: any,