import { apiClient } from "./client"; export interface EntityJoinConfig { sourceTable: string; sourceColumn: string; referenceTable: string; referenceColumn: string; displayColumn: string; aliasColumn: string; } export interface EntityJoinResponse { data: Record[]; total: number; page: number; size: number; totalPages: number; entityJoinInfo?: { joinConfigs: EntityJoinConfig[]; strategy: "full_join" | "cache_lookup"; performance: { queryTime: number; cacheHitRate?: number; }; }; } export interface ReferenceTableColumn { columnName: string; displayName: string; dataType: string; } export interface CacheStatus { overallHitRate: number; caches: Array<{ cacheKey: string; size: number; hitRate: number; lastUpdated: string; }>; summary: { totalCaches: number; totalSize: number; averageHitRate: number; }; } /** * Entity 조인 기능 API */ export const entityJoinApi = { /** * Entity 조인이 포함된 테이블 데이터 조회 */ getTableDataWithJoins: async ( tableName: string, params: { page?: number; size?: number; search?: Record; sortBy?: string; sortOrder?: "asc" | "desc"; enableEntityJoin?: boolean; additionalJoinColumns?: Array<{ sourceTable: string; sourceColumn: string; joinAlias: string; }>; screenEntityConfigs?: Record; // 🎯 화면별 엔티티 설정 dataFilter?: any; // 🆕 데이터 필터 excludeFilter?: { enabled: boolean; referenceTable: string; referenceColumn: string; sourceColumn: string; filterColumn?: string; filterValue?: any; }; // 🆕 제외 필터 (다른 테이블에 이미 존재하는 데이터 제외) companyCodeOverride?: string; // 🆕 프리뷰용 회사 코드 오버라이드 (최고 관리자만 사용 가능) } = {}, ): Promise => { // 🔒 멀티테넌시: company_code 자동 필터링 활성화 const autoFilter: { enabled: boolean; filterColumn: string; userField: string; companyCodeOverride?: string; } = { enabled: true, filterColumn: "company_code", userField: "companyCode", }; // 🆕 프리뷰 모드에서 회사 코드 오버라이드 (최고 관리자만 백엔드에서 허용) if (params.companyCodeOverride) { autoFilter.companyCodeOverride = params.companyCodeOverride; } const response = await apiClient.get(`/table-management/tables/${tableName}/data-with-joins`, { params: { page: params.page, size: params.size, sortBy: params.sortBy, sortOrder: params.sortOrder, enableEntityJoin: params.enableEntityJoin, search: params.search ? JSON.stringify(params.search) : undefined, additionalJoinColumns: params.additionalJoinColumns ? JSON.stringify(params.additionalJoinColumns) : undefined, screenEntityConfigs: params.screenEntityConfigs ? JSON.stringify(params.screenEntityConfigs) : undefined, // 🎯 화면별 엔티티 설정 autoFilter: JSON.stringify(autoFilter), // 🔒 멀티테넌시 필터링 (오버라이드 포함) dataFilter: params.dataFilter ? JSON.stringify(params.dataFilter) : undefined, // 🆕 데이터 필터 excludeFilter: params.excludeFilter ? JSON.stringify(params.excludeFilter) : undefined, // 🆕 제외 필터 }, }); return response.data.data; }, /** * 테이블의 Entity 조인 설정 조회 */ getEntityJoinConfigs: async ( tableName: string, ): Promise<{ tableName: string; joinConfigs: EntityJoinConfig[]; count: number; }> => { const response = await apiClient.get(`/table-management/tables/${tableName}/entity-joins`); return response.data.data; }, /** * 참조 테이블의 표시 가능한 컬럼 목록 조회 */ getReferenceTableColumns: async ( tableName: string, ): Promise<{ tableName: string; columns: ReferenceTableColumn[]; count: number; }> => { const response = await apiClient.get(`/table-management/reference-tables/${tableName}/columns`); return response.data.data; }, /** * 컬럼 Entity 설정 업데이트 */ updateEntitySettings: async ( tableName: string, columnName: string, settings: { webType: string; referenceTable?: string; referenceColumn?: string; displayColumn?: string; columnLabel?: string; description?: string; }, ): Promise => { await apiClient.put(`/table-management/tables/${tableName}/columns/${columnName}/entity-settings`, settings); }, /** * 캐시 상태 조회 */ getCacheStatus: async (): Promise => { const response = await apiClient.get(`/table-management/cache/status`); return response.data.data; }, /** * 캐시 무효화 */ invalidateCache: async (params?: { table?: string; keyColumn?: string; displayColumn?: string }): Promise => { await apiClient.delete(`/table-management/cache`, { params }); }, /** * Entity 조인된 테이블의 추가 컬럼 목록 조회 (화면편집기용) */ getEntityJoinColumns: async ( tableName: string, ): Promise<{ tableName: string; joinTables: Array<{ tableName: string; currentDisplayColumn: string; availableColumns: Array<{ columnName: string; columnLabel: string; dataType: string; description?: string; }>; }>; availableColumns: Array<{ tableName: string; columnName: string; columnLabel: string; dataType: string; joinAlias: string; suggestedLabel: string; }>; summary: { totalJoinTables: number; totalAvailableColumns: number; }; }> => { const response = await apiClient.get(`/table-management/tables/${tableName}/entity-join-columns`); return response.data.data; }, /** * 공통 참조 테이블 자동 캐싱 */ preloadCommonCaches: async (): Promise<{ preloadedCaches: number; caches: Array<{ cacheKey: string; size: number; hitRate: number; lastUpdated: string; }>; }> => { const response = await apiClient.post(`/table-management/cache/preload`); return response.data.data; }, };