From 0d9ee4c40f9692381115a952b88a005b774c65bc Mon Sep 17 00:00:00 2001 From: kjs Date: Wed, 24 Sep 2025 15:02:54 +0900 Subject: [PATCH] =?UTF-8?q?=ED=85=8C=EC=9D=B4=EB=B8=94=20=EC=BB=AC?= =?UTF-8?q?=EB=9F=BC=20=ED=91=9C=EC=8B=9C=EB=AC=B8=EC=A0=9C=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/services/entityJoinService.ts | 6 ++ .../src/services/tableManagementService.ts | 73 ++++++++++++++++--- .../table-list/TableListComponent.tsx | 3 +- 3 files changed, 71 insertions(+), 11 deletions(-) diff --git a/backend-node/src/services/entityJoinService.ts b/backend-node/src/services/entityJoinService.ts index 56633952..b88c0c8b 100644 --- a/backend-node/src/services/entityJoinService.ts +++ b/backend-node/src/services/entityJoinService.ts @@ -233,6 +233,9 @@ export class EntityJoinService { "master_sabun", "location", "data_type", + "company_name", + "sales_yn", + "status", ].includes(col); if (isJoinTableColumn) { @@ -256,6 +259,9 @@ export class EntityJoinService { "master_sabun", "location", "data_type", + "company_name", + "sales_yn", + "status", ].includes(col); if (isJoinTableColumn) { diff --git a/backend-node/src/services/tableManagementService.ts b/backend-node/src/services/tableManagementService.ts index 1278c1c3..4ca5369d 100644 --- a/backend-node/src/services/tableManagementService.ts +++ b/backend-node/src/services/tableManagementService.ts @@ -2074,38 +2074,78 @@ export class TableManagementService { ); for (const additionalColumn of options.additionalJoinColumns) { - // 기존 조인 설정에서 같은 참조 테이블을 사용하는 설정 찾기 + // 🔍 sourceColumn을 기준으로 기존 조인 설정 찾기 (dept_code로 찾기) const baseJoinConfig = joinConfigs.find( - (config) => config.referenceTable === additionalColumn.sourceTable + (config) => config.sourceColumn === additionalColumn.sourceColumn ); if (baseJoinConfig) { // joinAlias에서 실제 컬럼명 추출 (예: dept_code_location_name -> location_name) // sourceColumn을 제거한 나머지 부분이 실제 컬럼명 const sourceColumn = baseJoinConfig.sourceColumn; // dept_code - const joinAlias = additionalColumn.joinAlias; // dept_code_location_name - const actualColumnName = joinAlias.replace(`${sourceColumn}_`, ""); // location_name + const joinAlias = additionalColumn.joinAlias; // dept_code_company_name + const actualColumnName = joinAlias.replace(`${sourceColumn}_`, ""); // company_name + + logger.info(`🔍 조인 컬럼 상세 분석:`, { + sourceColumn, + joinAlias, + actualColumnName, + referenceTable: additionalColumn.sourceTable, + }); + + // 🚨 기본 Entity 조인과 중복되지 않도록 체크 + const isBasicEntityJoin = + additionalColumn.joinAlias === + `${baseJoinConfig.sourceColumn}_name`; + + if (isBasicEntityJoin) { + logger.info( + `⚠️ 기본 Entity 조인과 중복: ${additionalColumn.joinAlias} - 건너뜀` + ); + continue; // 기본 Entity 조인과 중복되면 추가하지 않음 + } // 추가 조인 컬럼 설정 생성 const additionalJoinConfig: EntityJoinConfig = { sourceTable: tableName, sourceColumn: baseJoinConfig.sourceColumn, // 원본 컬럼 (dept_code) - referenceTable: additionalColumn.sourceTable, // 참조 테이블 (dept_info) + referenceTable: + (additionalColumn as any).referenceTable || + baseJoinConfig.referenceTable, // 참조 테이블 (dept_info) referenceColumn: baseJoinConfig.referenceColumn, // 참조 키 (dept_code) - displayColumns: [actualColumnName], // 표시할 컬럼들 (location_name) + displayColumns: [actualColumnName], // 표시할 컬럼들 (company_name) displayColumn: actualColumnName, // 하위 호환성 - aliasColumn: additionalColumn.joinAlias, // 별칭 (dept_code_location_name) + aliasColumn: additionalColumn.joinAlias, // 별칭 (dept_code_company_name) separator: " - ", // 기본 구분자 }; joinConfigs.push(additionalJoinConfig); logger.info( - `추가 조인 컬럼 설정 추가: ${additionalJoinConfig.aliasColumn} -> ${actualColumnName}` + `✅ 추가 조인 컬럼 설정 추가: ${additionalJoinConfig.aliasColumn} -> ${actualColumnName}` ); + logger.info(`🔍 추가된 조인 설정 상세:`, { + sourceTable: additionalJoinConfig.sourceTable, + sourceColumn: additionalJoinConfig.sourceColumn, + referenceTable: additionalJoinConfig.referenceTable, + displayColumns: additionalJoinConfig.displayColumns, + aliasColumn: additionalJoinConfig.aliasColumn, + }); } } } + // 최종 조인 설정 배열 로깅 + logger.info(`🎯 최종 joinConfigs 배열 (${joinConfigs.length}개):`); + joinConfigs.forEach((config, index) => { + logger.info( + ` ${index + 1}. ${config.sourceColumn} -> ${config.referenceTable} AS ${config.aliasColumn}`, + { + displayColumns: config.displayColumns, + displayColumn: config.displayColumn, + } + ); + }); + if (joinConfigs.length === 0) { logger.info(`Entity 조인 설정이 없음: ${tableName}`); const basicResult = await this.getTableData(tableName, options); @@ -2119,8 +2159,21 @@ export class TableManagementService { } // 조인 전략 결정 (테이블 크기 기반) - const strategy = - await entityJoinService.determineJoinStrategy(joinConfigs); + // 🚨 additionalJoinColumns가 있는 경우 강제로 full_join 사용 (캐시 안정성 보장) + let strategy: "full_join" | "cache_lookup" | "hybrid"; + + if ( + options.additionalJoinColumns && + options.additionalJoinColumns.length > 0 + ) { + strategy = "full_join"; + console.log( + `🔧 additionalJoinColumns 감지: 강제로 full_join 전략 사용 (${options.additionalJoinColumns.length}개 추가 조인)` + ); + } else { + strategy = await entityJoinService.determineJoinStrategy(joinConfigs); + } + console.log( `🎯 선택된 조인 전략: ${strategy} (${joinConfigs.length}개 Entity 조인)` ); diff --git a/frontend/lib/registry/components/table-list/TableListComponent.tsx b/frontend/lib/registry/components/table-list/TableListComponent.tsx index 10416855..6bd974ed 100644 --- a/frontend/lib/registry/components/table-list/TableListComponent.tsx +++ b/frontend/lib/registry/components/table-list/TableListComponent.tsx @@ -322,9 +322,10 @@ export const TableListComponent: React.FC = ({ console.log(`🔗 조인 설정: ${col.columnName} -> ${sourceColumn} (${referenceTable})`); return { - sourceTable: referenceTable, + sourceTable: tableConfig.selectedTable || "unknown", // 기본 테이블 (user_info) sourceColumn: sourceColumn, joinAlias: col.columnName, + referenceTable: referenceTable, // 참조 테이블 정보도 추가 }; }), ];