diff --git a/backend-node/src/controllers/tableManagementController.ts b/backend-node/src/controllers/tableManagementController.ts index 83384be6..9b3d81a2 100644 --- a/backend-node/src/controllers/tableManagementController.ts +++ b/backend-node/src/controllers/tableManagementController.ts @@ -901,13 +901,23 @@ export async function addTableData( } // 데이터 추가 - await tableManagementService.addTableData(tableName, data); + const result = await tableManagementService.addTableData(tableName, data); logger.info(`테이블 데이터 추가 완료: ${tableName}`); - const response: ApiResponse = { + // 무시된 컬럼이 있으면 경고 정보 포함 + const response: ApiResponse<{ + skippedColumns?: string[]; + savedColumns?: string[]; + }> = { success: true, - message: "테이블 데이터를 성공적으로 추가했습니다.", + message: result.skippedColumns.length > 0 + ? `테이블 데이터를 추가했습니다. (무시된 컬럼 ${result.skippedColumns.length}개: ${result.skippedColumns.join(", ")})` + : "테이블 데이터를 성공적으로 추가했습니다.", + data: { + skippedColumns: result.skippedColumns.length > 0 ? result.skippedColumns : undefined, + savedColumns: result.savedColumns, + }, }; res.status(201).json(response); diff --git a/backend-node/src/services/tableManagementService.ts b/backend-node/src/services/tableManagementService.ts index 8ac5989b..98db1eee 100644 --- a/backend-node/src/services/tableManagementService.ts +++ b/backend-node/src/services/tableManagementService.ts @@ -2261,11 +2261,12 @@ export class TableManagementService { /** * 테이블에 데이터 추가 + * @returns 무시된 컬럼 정보 (디버깅용) */ async addTableData( tableName: string, data: Record - ): Promise { + ): Promise<{ skippedColumns: string[]; savedColumns: string[] }> { try { logger.info(`=== 테이블 데이터 추가 시작: ${tableName} ===`); logger.info(`추가할 데이터:`, data); @@ -2296,10 +2297,41 @@ export class TableManagementService { logger.info(`created_date 자동 추가: ${data.created_date}`); } - // 컬럼명과 값을 분리하고 타입에 맞게 변환 - const columns = Object.keys(data); - const values = Object.values(data).map((value, index) => { - const columnName = columns[index]; + // 🆕 테이블에 존재하는 컬럼만 필터링 (존재하지 않는 컬럼은 무시) + const skippedColumns: string[] = []; + const existingColumns = Object.keys(data).filter((col) => { + const exists = columnTypeMap.has(col); + if (!exists) { + skippedColumns.push(col); + } + return exists; + }); + + // 무시된 컬럼이 있으면 경고 로그 출력 + if (skippedColumns.length > 0) { + logger.warn( + `⚠️ [${tableName}] 테이블에 존재하지 않는 컬럼 ${skippedColumns.length}개 무시됨: ${skippedColumns.join(", ")}` + ); + logger.warn( + `⚠️ [${tableName}] 무시된 컬럼 상세:`, + skippedColumns.map((col) => ({ column: col, value: data[col] })) + ); + } + + if (existingColumns.length === 0) { + throw new Error( + `저장할 유효한 컬럼이 없습니다. 테이블: ${tableName}, 전달된 컬럼: ${Object.keys(data).join(", ")}` + ); + } + + logger.info( + `✅ [${tableName}] 저장될 컬럼 ${existingColumns.length}개: ${existingColumns.join(", ")}` + ); + + // 컬럼명과 값을 분리하고 타입에 맞게 변환 (존재하는 컬럼만) + const columns = existingColumns; + const values = columns.map((columnName) => { + const value = data[columnName]; const dataType = columnTypeMap.get(columnName) || "text"; const convertedValue = this.convertValueForPostgreSQL(value, dataType); logger.info( @@ -2355,6 +2387,12 @@ export class TableManagementService { await query(insertQuery, values); logger.info(`테이블 데이터 추가 완료: ${tableName}`); + + // 무시된 컬럼과 저장된 컬럼 정보 반환 + return { + skippedColumns, + savedColumns: existingColumns, + }; } catch (error) { logger.error(`테이블 데이터 추가 오류: ${tableName}`, error); throw error; diff --git a/frontend/lib/utils/buttonActions.ts b/frontend/lib/utils/buttonActions.ts index e9327082..9b847ef3 100644 --- a/frontend/lib/utils/buttonActions.ts +++ b/frontend/lib/utils/buttonActions.ts @@ -1063,6 +1063,13 @@ export class ButtonActionExecutor { dataWithMeta, ); console.log("✅ [handleSave] RepeaterFieldGroup INSERT 완료:", insertResult.data); + // 무시된 컬럼이 있으면 경고 출력 + if (insertResult.data?.data?.skippedColumns?.length > 0) { + console.warn( + `⚠️ [${repeaterTargetTable}] 테이블에 존재하지 않는 컬럼이 무시됨:`, + insertResult.data.data.skippedColumns, + ); + } } else if (item.id) { // UPDATE (기존 항목) const originalData = { id: item.id };