ERP-node/frontend/lib/api/entityJoin.ts

222 lines
5.9 KiB
TypeScript

import { apiClient } from "./client";
export interface EntityJoinConfig {
sourceTable: string;
sourceColumn: string;
referenceTable: string;
referenceColumn: string;
displayColumn: string;
aliasColumn: string;
}
export interface EntityJoinResponse {
data: Record<string, any>[];
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<string, any>;
sortBy?: string;
sortOrder?: "asc" | "desc";
enableEntityJoin?: boolean;
additionalJoinColumns?: Array<{
sourceTable: string;
sourceColumn: string;
joinAlias: string;
}>;
screenEntityConfigs?: Record<string, any>; // 🎯 화면별 엔티티 설정
} = {},
): Promise<EntityJoinResponse> => {
const searchParams = new URLSearchParams();
if (params.page) searchParams.append("page", params.page.toString());
if (params.size) searchParams.append("size", params.size.toString());
if (params.sortBy) searchParams.append("sortBy", params.sortBy);
if (params.sortOrder) searchParams.append("sortOrder", params.sortOrder);
if (params.enableEntityJoin !== undefined) {
searchParams.append("enableEntityJoin", params.enableEntityJoin.toString());
}
// 검색 조건 추가
if (params.search) {
Object.entries(params.search).forEach(([key, value]) => {
if (value !== undefined && value !== null && value !== "") {
searchParams.append(key, String(value));
}
});
}
// 🔒 멀티테넌시: company_code 자동 필터링 활성화
const autoFilter = {
enabled: true,
filterColumn: "company_code",
userField: "companyCode",
};
const response = await apiClient.get(`/table-management/tables/${tableName}/data-with-joins`, {
params: {
...params,
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), // 🔒 멀티테넌시 필터링
},
});
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<void> => {
await apiClient.put(`/table-management/tables/${tableName}/columns/${columnName}/entity-settings`, settings);
},
/**
* 캐시 상태 조회
*/
getCacheStatus: async (): Promise<CacheStatus> => {
const response = await apiClient.get(`/table-management/cache/status`);
return response.data.data;
},
/**
* 캐시 무효화
*/
invalidateCache: async (params?: { table?: string; keyColumn?: string; displayColumn?: string }): Promise<void> => {
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;
},
};