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

231 lines
6.4 KiB
TypeScript
Raw Normal View History

2025-09-16 15:13:00 +09:00
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>; // 🎯 화면별 엔티티 설정
dataFilter?: any; // 🆕 데이터 필터
2025-12-04 18:26:35 +09:00
excludeFilter?: {
enabled: boolean;
referenceTable: string;
referenceColumn: string;
sourceColumn: string;
filterColumn?: string;
filterValue?: any;
}; // 🆕 제외 필터 (다른 테이블에 이미 존재하는 데이터 제외)
companyCodeOverride?: string; // 🆕 프리뷰용 회사 코드 오버라이드 (최고 관리자만 사용 가능)
2025-09-16 15:13:00 +09:00
} = {},
): Promise<EntityJoinResponse> => {
2025-11-06 18:35:05 +09:00
// 🔒 멀티테넌시: company_code 자동 필터링 활성화
const autoFilter: {
enabled: boolean;
filterColumn: string;
userField: string;
companyCodeOverride?: string;
} = {
2025-11-06 18:35:05 +09:00
enabled: true,
filterColumn: "company_code",
userField: "companyCode",
};
// 🆕 프리뷰 모드에서 회사 코드 오버라이드 (최고 관리자만 백엔드에서 허용)
if (params.companyCodeOverride) {
autoFilter.companyCodeOverride = params.companyCodeOverride;
}
2025-09-16 15:13:00 +09:00
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,
2025-09-16 15:13:00 +09:00
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, // 🆕 데이터 필터
2025-12-04 18:26:35 +09:00
excludeFilter: params.excludeFilter ? JSON.stringify(params.excludeFilter) : undefined, // 🆕 제외 필터
2025-09-16 15:13:00 +09:00
},
});
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;
inputType?: string;
description?: string;
}>;
}>;
availableColumns: Array<{
tableName: string;
columnName: string;
columnLabel: string;
dataType: string;
inputType?: 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;
},
2025-09-16 15:13:00 +09:00
/**
*
*/
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;
},
};