ERP-node/backend-node/src/controllers/entityJoinController.ts

327 lines
9.6 KiB
TypeScript
Raw Normal View History

2025-09-16 15:13:00 +09:00
import { Request, Response } from "express";
import { logger } from "../utils/logger";
import { TableManagementService } from "../services/tableManagementService";
import { entityJoinService } from "../services/entityJoinService";
import { referenceCacheService } from "../services/referenceCacheService";
const tableManagementService = new TableManagementService();
/**
* Entity
* ID값을 API
*/
export class EntityJoinController {
/**
* Entity
* GET /api/table-management/tables/:tableName/data-with-joins
*/
async getTableDataWithJoins(req: Request, res: Response): Promise<void> {
try {
const { tableName } = req.params;
const {
page = 1,
size = 20,
search,
sortBy,
sortOrder = "asc",
enableEntityJoin = true,
userLang, // userLang은 별도로 분리하여 search에 포함되지 않도록 함
...otherParams
} = req.query;
logger.info(`Entity 조인 데이터 요청: ${tableName}`, {
page,
size,
enableEntityJoin,
search,
});
// 검색 조건 처리
let searchConditions: Record<string, any> = {};
if (search) {
try {
// search가 문자열인 경우 JSON 파싱
searchConditions =
typeof search === "string" ? JSON.parse(search) : search;
} catch (error) {
logger.warn("검색 조건 파싱 오류:", error);
searchConditions = {};
}
}
const result = await tableManagementService.getTableDataWithEntityJoins(
tableName,
{
page: Number(page),
size: Number(size),
search:
Object.keys(searchConditions).length > 0
? searchConditions
: undefined,
sortBy: sortBy as string,
sortOrder: sortOrder as string,
enableEntityJoin:
enableEntityJoin === "true" || enableEntityJoin === true,
}
);
res.status(200).json({
success: true,
message: "Entity 조인 데이터 조회 성공",
data: result,
});
} catch (error) {
logger.error("Entity 조인 데이터 조회 실패", error);
res.status(500).json({
success: false,
message: "Entity 조인 데이터 조회 중 오류가 발생했습니다.",
error: error instanceof Error ? error.message : "Unknown error",
});
}
}
/**
* Entity
* GET /api/table-management/tables/:tableName/entity-joins
*/
async getEntityJoinConfigs(req: Request, res: Response): Promise<void> {
try {
const { tableName } = req.params;
logger.info(`Entity 조인 설정 조회: ${tableName}`);
const joinConfigs = await entityJoinService.detectEntityJoins(tableName);
res.status(200).json({
success: true,
message: "Entity 조인 설정 조회 성공",
data: {
tableName,
joinConfigs,
count: joinConfigs.length,
},
});
} catch (error) {
logger.error("Entity 조인 설정 조회 실패", error);
res.status(500).json({
success: false,
message: "Entity 조인 설정 조회 중 오류가 발생했습니다.",
error: error instanceof Error ? error.message : "Unknown error",
});
}
}
/**
*
* GET /api/table-management/reference-tables/:tableName/columns
*/
async getReferenceTableColumns(req: Request, res: Response): Promise<void> {
try {
const { tableName } = req.params;
logger.info(`참조 테이블 컬럼 조회: ${tableName}`);
const columns =
await tableManagementService.getReferenceTableColumns(tableName);
res.status(200).json({
success: true,
message: "참조 테이블 컬럼 조회 성공",
data: {
tableName,
columns,
count: columns.length,
},
});
} catch (error) {
logger.error("참조 테이블 컬럼 조회 실패", error);
res.status(500).json({
success: false,
message: "참조 테이블 컬럼 조회 중 오류가 발생했습니다.",
error: error instanceof Error ? error.message : "Unknown error",
});
}
}
/**
* Entity (display_column )
* PUT /api/table-management/tables/:tableName/columns/:columnName/entity-settings
*/
async updateEntitySettings(req: Request, res: Response): Promise<void> {
try {
const { tableName, columnName } = req.params;
const {
webType,
referenceTable,
referenceColumn,
displayColumn,
columnLabel,
description,
} = req.body;
logger.info(`Entity 설정 업데이트: ${tableName}.${columnName}`, req.body);
// Entity 타입인 경우 필수 필드 검증
if (webType === "entity") {
if (!referenceTable || !referenceColumn) {
res.status(400).json({
success: false,
message:
"Entity 타입의 경우 referenceTable과 referenceColumn이 필수입니다.",
});
return;
}
}
await tableManagementService.updateColumnLabel(tableName, columnName, {
webType,
referenceTable,
referenceColumn,
displayColumn,
columnLabel,
description,
});
// Entity 설정 변경 시 관련 캐시 무효화
if (webType === "entity" && referenceTable) {
referenceCacheService.invalidateCache(
referenceTable,
referenceColumn,
displayColumn
);
}
res.status(200).json({
success: true,
message: "Entity 설정 업데이트 성공",
data: {
tableName,
columnName,
settings: {
webType,
referenceTable,
referenceColumn,
displayColumn,
},
},
});
} catch (error) {
logger.error("Entity 설정 업데이트 실패", error);
res.status(500).json({
success: false,
message: "Entity 설정 업데이트 중 오류가 발생했습니다.",
error: error instanceof Error ? error.message : "Unknown error",
});
}
}
/**
*
* GET /api/table-management/cache/status
*/
async getCacheStatus(req: Request, res: Response): Promise<void> {
try {
logger.info("캐시 상태 조회");
const cacheInfo = referenceCacheService.getCacheInfo();
const overallHitRate = referenceCacheService.getOverallCacheHitRate();
res.status(200).json({
success: true,
message: "캐시 상태 조회 성공",
data: {
overallHitRate,
caches: cacheInfo,
summary: {
totalCaches: cacheInfo.length,
totalSize: cacheInfo.reduce((sum, cache) => sum + cache.size, 0),
averageHitRate:
cacheInfo.length > 0
? cacheInfo.reduce((sum, cache) => sum + cache.hitRate, 0) /
cacheInfo.length
: 0,
},
},
});
} catch (error) {
logger.error("캐시 상태 조회 실패", error);
res.status(500).json({
success: false,
message: "캐시 상태 조회 중 오류가 발생했습니다.",
error: error instanceof Error ? error.message : "Unknown error",
});
}
}
/**
*
* DELETE /api/table-management/cache
*/
async invalidateCache(req: Request, res: Response): Promise<void> {
try {
const { table, keyColumn, displayColumn } = req.query;
logger.info("캐시 무효화 요청", { table, keyColumn, displayColumn });
if (table && keyColumn && displayColumn) {
// 특정 캐시만 무효화
referenceCacheService.invalidateCache(
table as string,
keyColumn as string,
displayColumn as string
);
} else {
// 전체 캐시 무효화
referenceCacheService.invalidateCache();
}
res.status(200).json({
success: true,
message: "캐시 무효화 완료",
data: {
target: table ? `${table}.${keyColumn}.${displayColumn}` : "전체",
},
});
} catch (error) {
logger.error("캐시 무효화 실패", error);
res.status(500).json({
success: false,
message: "캐시 무효화 중 오류가 발생했습니다.",
error: error instanceof Error ? error.message : "Unknown error",
});
}
}
/**
*
* POST /api/table-management/cache/preload
*/
async preloadCommonCaches(req: Request, res: Response): Promise<void> {
try {
logger.info("공통 참조 테이블 자동 캐싱 시작");
await referenceCacheService.autoPreloadCommonTables();
const cacheInfo = referenceCacheService.getCacheInfo();
res.status(200).json({
success: true,
message: "공통 참조 테이블 캐싱 완료",
data: {
preloadedCaches: cacheInfo.length,
caches: cacheInfo,
},
});
} catch (error) {
logger.error("공통 참조 테이블 캐싱 실패", error);
res.status(500).json({
success: false,
message: "공통 참조 테이블 캐싱 중 오류가 발생했습니다.",
error: error instanceof Error ? error.message : "Unknown error",
});
}
}
}
export const entityJoinController = new EntityJoinController();