diff --git a/backend-node/src/controllers/entityReferenceController.ts b/backend-node/src/controllers/entityReferenceController.ts index 1935065e..633cde62 100644 --- a/backend-node/src/controllers/entityReferenceController.ts +++ b/backend-node/src/controllers/entityReferenceController.ts @@ -53,29 +53,65 @@ export class EntityReferenceController { }); } - // detailSettings에서 참조 테이블 정보 추출 - let referenceTable = ""; - let displayColumn = "name"; + // column_labels에서 참조 테이블 정보 가져오기 + let referenceTable = columnInfo.reference_table || ""; + let referenceColumn = columnInfo.reference_column || ""; + let displayColumn = "name"; // 기본 표시 컬럼 + // detailSettings에서 displayColumn 정보 추출 try { if (columnInfo.detail_settings) { const detailSettings = JSON.parse(columnInfo.detail_settings); - referenceTable = detailSettings.referenceTable || ""; - displayColumn = detailSettings.displayColumn || "name"; + displayColumn = detailSettings.displayColumn || displayColumn; } } catch (error) { logger.warn("detailSettings 파싱 실패:", error); } + // reference_table이 없는 경우 컬럼명 기반으로 추론 + if (!referenceTable) { + if (columnName.endsWith("_code")) { + // dept_code -> dept_info + const baseTableName = columnName.replace("_code", "_info"); + referenceTable = baseTableName; + referenceColumn = columnName; // dept_code + logger.info(`참조 테이블 추론: ${columnName} -> ${referenceTable}`); + } else if (columnName.endsWith("_id")) { + // user_id -> user_info + const baseTableName = columnName.replace("_id", "_info"); + referenceTable = baseTableName; + referenceColumn = columnName; // user_id + logger.info(`참조 테이블 추론: ${columnName} -> ${referenceTable}`); + } + } + if (!referenceTable) { return res.status(400).json({ success: false, - message: `컬럼 '${columnName}'에 참조 테이블이 설정되지 않았습니다.`, + message: `컬럼 '${tableName}.${columnName}'에 참조 테이블이 설정되지 않았습니다.`, }); } + // 테이블별 적절한 표시 컬럼 설정 + if (referenceTable === "dept_info") { + displayColumn = "dept_name"; + } else if (referenceTable === "user_info") { + displayColumn = "user_name"; + } + + // referenceColumn이 없으면 테이블별 Primary Key로 설정 + if (!referenceColumn) { + if (referenceTable === "dept_info") { + referenceColumn = "dept_code"; + } else if (referenceTable === "user_info") { + referenceColumn = "user_id"; + } else { + referenceColumn = "id"; // 기본값 + } + } + // 동적 쿼리로 참조 데이터 조회 - let query = `SELECT id, ${displayColumn} as display_name FROM ${referenceTable}`; + let query = `SELECT ${referenceColumn}, ${displayColumn} as display_name FROM ${referenceTable}`; const queryParams: any[] = []; // 검색 조건 추가 @@ -87,13 +123,20 @@ export class EntityReferenceController { query += ` ORDER BY ${displayColumn} LIMIT $${queryParams.length + 1}`; queryParams.push(Number(limit)); + logger.info(`실행할 쿼리: ${query}`, { + queryParams, + referenceTable, + referenceColumn, + displayColumn, + }); + const referenceData = await prisma.$queryRawUnsafe(query, ...queryParams); // 옵션 형태로 변환 const options: EntityReferenceOption[] = (referenceData as any[]).map( (row) => ({ - value: String(row.id), - label: String(row.display_name || row.id), + value: String(row[referenceColumn]), + label: String(row.display_name || row[referenceColumn]), }) ); diff --git a/frontend/components/dataflow/condition/WebTypeInput.tsx b/frontend/components/dataflow/condition/WebTypeInput.tsx index 2db3e1b1..6291710b 100644 --- a/frontend/components/dataflow/condition/WebTypeInput.tsx +++ b/frontend/components/dataflow/condition/WebTypeInput.tsx @@ -75,9 +75,12 @@ export const WebTypeInput: React.FC = ({ column, value, onCha referenceTable: column.referenceTable, displayColumn: column.displayColumn, codeCategory: column.codeCategory, + detailSettings, + fallbackCodeCategory, }); - if (webType === "entity" && column.tableName && column.columnName) { + // webType이 entity이거나, referenceTable이 있으면 entity로 처리 + if ((webType === "entity" || column.referenceTable) && column.tableName && column.columnName) { console.log("🚀 Entity 데이터 로드 시작:", column.tableName, column.columnName); loadEntityData(); } else if (webType === "code" && (column.codeCategory || detailSettings.codeCategory || fallbackCodeCategory)) { @@ -85,9 +88,15 @@ export const WebTypeInput: React.FC = ({ column, value, onCha console.log("🚀 Code 데이터 로드 시작:", codeCategory); loadCodeData(); } else { - console.log("❌ 조건 불충족 - API 호출 안함"); + console.log("❌ 조건 불충족 - API 호출 안함", { + webType, + hasReferenceTable: !!column.referenceTable, + hasTableName: !!column.tableName, + hasColumnName: !!column.columnName, + hasCodeCategory: !!(column.codeCategory || detailSettings.codeCategory || fallbackCodeCategory), + }); } - }, [webType, column.tableName, column.columnName, column.codeCategory, fallbackCodeCategory]); + }, [webType, column.tableName, column.columnName, column.codeCategory, column.referenceTable, fallbackCodeCategory]); const loadEntityData = async () => { try { @@ -130,8 +139,10 @@ export const WebTypeInput: React.FC = ({ column, value, onCha className, }; - // WebType별 렌더링 - switch (webType) { + // WebType별 렌더링 (referenceTable이 있으면 entity로 처리) + const actualWebType = webType === "entity" || column.referenceTable ? "entity" : webType; + + switch (actualWebType) { case "text": return (