/** * 테이블 관리 API * 테이블 컬럼 정보 조회 및 관리 기능 */ import { apiClient, ApiResponse } from "./client"; // 컬럼 정보 타입 (백엔드와 일치) export interface ColumnTypeInfo { tableName?: string; columnName: string; displayName: string; dataType: string; dbType: string; webType: string; inputType?: string; // text, number, entity, code, select, date, checkbox 등 detailSettings: string; description?: string; isNullable: string; isPrimaryKey: boolean; defaultValue?: string; maxLength?: number; numericPrecision?: number; numericScale?: number; codeCategory?: string; codeValue?: string; referenceTable?: string; referenceColumn?: string; displayColumn?: string; displayOrder?: number; isVisible?: boolean; } // 테이블 정보 타입 export interface TableInfo { tableName: string; displayName: string; description: string; columnCount: number; } // 컬럼 설정 타입 (백엔드 API와 동일한 필드명 사용) export interface ColumnSettings { columnName?: string; columnLabel: string; inputType: string; // 백엔드에서 inputType으로 받음 detailSettings: string; codeCategory: string; codeValue: string; referenceTable: string; referenceColumn: string; displayColumn?: string; displayOrder?: number; isVisible?: boolean; } // 컬럼 리스트 페이지네이션 응답 export interface ColumnListData { columns: ColumnTypeInfo[]; total: number; page: number; size: number; totalPages: number; } // API 응답 타입들 export interface TableListResponse extends ApiResponse {} export interface ColumnListResponse extends ApiResponse {} export interface ColumnSettingsResponse extends ApiResponse {} /** * 테이블 관리 API 클래스 */ class TableManagementApi { private readonly basePath = "/table-management"; /** * 테이블 목록 조회 */ async getTableList(): Promise { try { const response = await apiClient.get(`${this.basePath}/tables`); return response.data; } catch (error: any) { console.error("❌ 테이블 목록 조회 실패:", error); return { success: false, message: error.response?.data?.message || error.message || "테이블 목록을 조회할 수 없습니다.", errorCode: error.response?.data?.errorCode, }; } } /** * 특정 테이블의 컬럼 목록 조회 */ async getColumnList(tableName: string, size: number = 1000): Promise { try { const response = await apiClient.get(`${this.basePath}/tables/${tableName}/columns?size=${size}`); return response.data; } catch (error: any) { console.error(`❌ 테이블 '${tableName}' 컬럼 목록 조회 실패:`, error); return { success: false, message: error.response?.data?.message || error.message || `테이블 '${tableName}'의 컬럼 정보를 조회할 수 없습니다.`, errorCode: error.response?.data?.errorCode, }; } } /** * 컬럼 타입 설정 저장 */ async updateColumnSettings( tableName: string, columnName: string, settings: ColumnSettings, ): Promise { try { const response = await apiClient.put(`${this.basePath}/tables/${tableName}/columns/${columnName}`, settings); return response.data; } catch (error: any) { console.error(`❌ 컬럼 '${tableName}.${columnName}' 설정 저장 실패:`, error); return { success: false, message: error.response?.data?.message || error.message || "컬럼 설정을 저장할 수 없습니다.", errorCode: error.response?.data?.errorCode, }; } } /** * 여러 컬럼 설정 일괄 저장 */ async updateMultipleColumnSettings( tableName: string, settingsArray: Array<{ columnName: string; settings: ColumnSettings }>, ): Promise { try { const response = await apiClient.put(`${this.basePath}/tables/${tableName}/columns/batch`, { settings: settingsArray, }); return response.data; } catch (error: any) { console.error(`❌ 테이블 '${tableName}' 컬럼 설정 일괄 저장 실패:`, error); return { success: false, message: error.response?.data?.message || error.message || "컬럼 설정을 일괄 저장할 수 없습니다.", errorCode: error.response?.data?.errorCode, }; } } /** * 테이블 스키마 정보 조회 (컬럼 존재 여부 검증용) */ async getTableSchema(tableName: string): Promise> { try { const response = await apiClient.get(`${this.basePath}/tables/${tableName}/schema`); return response.data; } catch (error: any) { console.error(`❌ 테이블 '${tableName}' 스키마 조회 실패:`, error); return { success: false, message: error.response?.data?.message || error.message || `테이블 '${tableName}'의 스키마 정보를 조회할 수 없습니다.`, errorCode: error.response?.data?.errorCode, }; } } /** * 테이블 존재 여부 확인 */ async checkTableExists(tableName: string): Promise> { try { const response = await apiClient.get(`${this.basePath}/tables/${tableName}/exists`); return response.data; } catch (error: any) { console.error(`❌ 테이블 '${tableName}' 존재 여부 확인 실패:`, error); return { success: false, message: error.response?.data?.message || error.message || "테이블 존재 여부를 확인할 수 없습니다.", errorCode: error.response?.data?.errorCode, }; } } /** * 컬럼 웹타입 정보 조회 (화면관리 연동용) */ async getColumnWebTypes(tableName: string): Promise> { try { const response = await apiClient.get(`${this.basePath}/tables/${tableName}/web-types`); return response.data; } catch (error: any) { console.error(`❌ 테이블 '${tableName}' 웹타입 정보 조회 실패:`, error); return { success: false, message: error.response?.data?.message || error.message || "웹타입 정보를 조회할 수 없습니다.", errorCode: error.response?.data?.errorCode, }; } } /** * 데이터베이스 연결 상태 확인 */ async checkDatabaseConnection(): Promise> { try { const response = await apiClient.get(`${this.basePath}/health`); return response.data; } catch (error: any) { console.error("❌ 데이터베이스 연결 상태 확인 실패:", error); return { success: false, message: error.response?.data?.message || error.message || "데이터베이스 연결 상태를 확인할 수 없습니다.", errorCode: error.response?.data?.errorCode, }; } } // ======================================== // 테이블 로그 시스템 API // ======================================== /** * 로그 테이블 생성 */ async createLogTable( tableName: string, pkColumn: { columnName: string; dataType: string }, ): Promise> { try { const response = await apiClient.post(`${this.basePath}/tables/${tableName}/log`, { pkColumn }); return response.data; } catch (error: any) { console.error(`❌ 로그 테이블 생성 실패: ${tableName}`, error); return { success: false, message: error.response?.data?.message || error.message || "로그 테이블을 생성할 수 없습니다.", errorCode: error.response?.data?.errorCode, }; } } /** * 로그 설정 조회 */ async getLogConfig(tableName: string): Promise< ApiResponse<{ originalTableName: string; logTableName: string; triggerName: string; triggerFunctionName: string; isActive: string; createdAt: Date; createdBy: string; } | null> > { try { const response = await apiClient.get(`${this.basePath}/tables/${tableName}/log/config`); return response.data; } catch (error: any) { console.error(`❌ 로그 설정 조회 실패: ${tableName}`, error); return { success: false, message: error.response?.data?.message || error.message || "로그 설정을 조회할 수 없습니다.", errorCode: error.response?.data?.errorCode, }; } } /** * 로그 데이터 조회 */ async getLogData( tableName: string, options: { page?: number; size?: number; operationType?: string; startDate?: string; endDate?: string; changedBy?: string; originalId?: string; } = {}, ): Promise< ApiResponse<{ data: any[]; total: number; page: number; size: number; totalPages: number; }> > { try { const response = await apiClient.get(`${this.basePath}/tables/${tableName}/log`, { params: options, }); return response.data; } catch (error: any) { console.error(`❌ 로그 데이터 조회 실패: ${tableName}`, error); return { success: false, message: error.response?.data?.message || error.message || "로그 데이터를 조회할 수 없습니다.", errorCode: error.response?.data?.errorCode, }; } } /** * 로그 테이블 활성화/비활성화 */ async toggleLogTable(tableName: string, isActive: boolean): Promise> { try { const response = await apiClient.post(`${this.basePath}/tables/${tableName}/log/toggle`, { isActive, }); return response.data; } catch (error: any) { console.error(`❌ 로그 테이블 토글 실패: ${tableName}`, error); return { success: false, message: error.response?.data?.message || error.message || "로그 테이블 설정을 변경할 수 없습니다.", errorCode: error.response?.data?.errorCode, }; } } /** * 두 테이블 간의 엔티티 관계 자동 감지 * column_labels에서 정의된 엔티티/카테고리 타입 설정을 기반으로 * 두 테이블 간의 외래키 관계를 자동으로 감지합니다. */ async getTableEntityRelations( leftTable: string, rightTable: string ): Promise; }>> { try { const response = await apiClient.get( `${this.basePath}/tables/entity-relations?leftTable=${encodeURIComponent(leftTable)}&rightTable=${encodeURIComponent(rightTable)}` ); return response.data; } catch (error: any) { console.error(`❌ 테이블 엔티티 관계 조회 실패: ${leftTable} <-> ${rightTable}`, error); return { success: false, message: error.response?.data?.message || error.message || "테이블 엔티티 관계를 조회할 수 없습니다.", errorCode: error.response?.data?.errorCode, }; } } } // 싱글톤 인스턴스 생성 export const tableManagementApi = new TableManagementApi(); // 편의 함수들 export const getTableColumns = (tableName: string) => tableManagementApi.getColumnList(tableName); export const updateColumnType = (tableName: string, columnName: string, settings: ColumnSettings) => tableManagementApi.updateColumnSettings(tableName, columnName, settings); export const checkTableExists = (tableName: string) => tableManagementApi.checkTableExists(tableName);