Merge branch 'main' of http://39.117.244.52:3000/kjs/ERP-node into feature/screen-management

This commit is contained in:
kjs
2025-11-28 18:38:18 +09:00
97 changed files with 10731 additions and 3480 deletions

View File

@@ -169,22 +169,18 @@ export class BatchController {
static async getBatchConfigById(req: AuthenticatedRequest, res: Response) {
try {
const { id } = req.params;
const userCompanyCode = req.user?.companyCode;
const batchConfig = await BatchService.getBatchConfigById(
Number(id),
userCompanyCode
);
const result = await BatchService.getBatchConfigById(Number(id));
if (!batchConfig) {
if (!result.success || !result.data) {
return res.status(404).json({
success: false,
message: "배치 설정을 찾을 수 없습니다.",
message: result.message || "배치 설정을 찾을 수 없습니다.",
});
}
return res.json({
success: true,
data: batchConfig,
data: result.data,
});
} catch (error) {
console.error("배치 설정 조회 오류:", error);

View File

@@ -62,6 +62,11 @@ export class BatchExecutionLogController {
try {
const data: CreateBatchExecutionLogRequest = req.body;
// 멀티테넌시: company_code가 없으면 현재 사용자 회사 코드로 설정
if (!data.company_code) {
data.company_code = req.user?.companyCode || "*";
}
const result = await BatchExecutionLogService.createExecutionLog(data);
if (result.success) {

View File

@@ -265,8 +265,12 @@ export class BatchManagementController {
try {
// 실행 로그 생성
executionLog = await BatchService.createExecutionLog({
const { BatchExecutionLogService } = await import(
"../services/batchExecutionLogService"
);
const logResult = await BatchExecutionLogService.createExecutionLog({
batch_config_id: Number(id),
company_code: batchConfig.company_code,
execution_status: "RUNNING",
start_time: startTime,
total_records: 0,
@@ -274,6 +278,14 @@ export class BatchManagementController {
failed_records: 0,
});
if (!logResult.success || !logResult.data) {
throw new Error(
logResult.message || "배치 실행 로그를 생성할 수 없습니다."
);
}
executionLog = logResult.data;
// BatchSchedulerService의 executeBatchConfig 메서드 사용 (중복 로직 제거)
const { BatchSchedulerService } = await import(
"../services/batchSchedulerService"
@@ -290,7 +302,7 @@ export class BatchManagementController {
const duration = endTime.getTime() - startTime.getTime();
// 실행 로그 업데이트 (성공)
await BatchService.updateExecutionLog(executionLog.id, {
await BatchExecutionLogService.updateExecutionLog(executionLog.id, {
execution_status: "SUCCESS",
end_time: endTime,
duration_ms: duration,
@@ -406,22 +418,34 @@ export class BatchManagementController {
paramName,
paramValue,
paramSource,
requestBody,
} = req.body;
if (!apiUrl || !apiKey || !endpoint) {
// apiUrl, endpoint는 항상 필수
if (!apiUrl || !endpoint) {
return res.status(400).json({
success: false,
message: "API URL, API Key, 엔드포인트는 필수입니다.",
message: "API URL 엔드포인트는 필수입니다.",
});
}
// GET 요청일 때만 API Key 필수 (POST/PUT/DELETE는 선택)
if ((!method || method === "GET") && !apiKey) {
return res.status(400).json({
success: false,
message: "GET 메서드에서는 API Key가 필요합니다.",
});
}
console.log("🔍 REST API 미리보기 요청:", {
apiUrl,
endpoint,
method,
paramType,
paramName,
paramValue,
paramSource,
requestBody: requestBody ? "Included" : "None",
});
// RestApiConnector 사용하여 데이터 조회
@@ -429,7 +453,7 @@ export class BatchManagementController {
const connector = new RestApiConnector({
baseUrl: apiUrl,
apiKey: apiKey,
apiKey: apiKey || "",
timeout: 30000,
});
@@ -456,9 +480,28 @@ export class BatchManagementController {
console.log("🔗 최종 엔드포인트:", finalEndpoint);
// 데이터 조회 (최대 5개만) - GET 메서드만 지원
const result = await connector.executeQuery(finalEndpoint, method);
console.log(`[previewRestApiData] executeQuery 결과:`, {
// Request Body 파싱
let parsedBody = undefined;
if (requestBody && typeof requestBody === "string") {
try {
parsedBody = JSON.parse(requestBody);
} catch (e) {
console.warn("Request Body JSON 파싱 실패:", e);
// 파싱 실패 시 원본 문자열 사용하거나 무시 (상황에 따라 결정, 여기선 undefined로 처리하거나 에러 반환 가능)
// 여기서는 경고 로그 남기고 진행
}
} else if (requestBody) {
parsedBody = requestBody;
}
// 데이터 조회 - executeRequest 사용 (POST/PUT/DELETE 지원)
const result = await connector.executeRequest(
finalEndpoint,
method as "GET" | "POST" | "PUT" | "DELETE",
parsedBody
);
console.log(`[previewRestApiData] executeRequest 결과:`, {
rowCount: result.rowCount,
rowsLength: result.rows ? result.rows.length : "undefined",
firstRow:
@@ -532,15 +575,21 @@ export class BatchManagementController {
apiMappings,
});
// 🔐 멀티테넌시: 현재 사용자 회사 코드 사용 (프론트에서 받지 않음)
const companyCode = req.user?.companyCode || "*";
const userId = req.user?.userId;
// BatchService를 사용하여 배치 설정 저장
const batchConfig: CreateBatchConfigRequest = {
batchName: batchName,
description: description || "",
cronSchedule: cronSchedule,
isActive: "Y",
companyCode,
mappings: apiMappings,
};
const result = await BatchService.createBatchConfig(batchConfig);
const result = await BatchService.createBatchConfig(batchConfig, userId);
if (result.success && result.data) {
// 스케줄러에 자동 등록 ✅

View File

@@ -161,3 +161,4 @@ export const createMappingTemplate = async (