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

290 lines
8.5 KiB
TypeScript
Raw Normal View History

2025-09-24 10:46:55 +09:00
// 배치관리 컨트롤러
// 작성일: 2024-12-24
import { Request, Response } from "express";
import { BatchService } from "../services/batchService";
import { BatchSchedulerService } from "../services/batchSchedulerService";
import { BatchConfigFilter, CreateBatchConfigRequest, UpdateBatchConfigRequest } from "../types/batchTypes";
2025-09-24 10:46:55 +09:00
export interface AuthenticatedRequest extends Request {
user?: {
userId: string;
username: string;
companyCode: string;
};
}
export class BatchController {
/**
*
* GET /api/batch-configs
*/
static async getBatchConfigs(req: AuthenticatedRequest, res: Response) {
try {
const { page = 1, limit = 10, search, isActive } = req.query;
2025-09-24 10:46:55 +09:00
const filter: BatchConfigFilter = {
page: Number(page),
limit: Number(limit),
search: search as string,
is_active: isActive as string
2025-09-24 10:46:55 +09:00
};
const result = await BatchService.getBatchConfigs(filter);
res.json({
success: true,
data: result.data,
pagination: result.pagination
});
2025-09-24 10:46:55 +09:00
} catch (error) {
console.error("배치 설정 목록 조회 오류:", error);
res.status(500).json({
2025-09-24 10:46:55 +09:00
success: false,
message: "배치 설정 목록 조회에 실패했습니다."
2025-09-24 10:46:55 +09:00
});
}
}
/**
*
* GET /api/batch-configs/connections
2025-09-24 10:46:55 +09:00
*/
static async getAvailableConnections(req: AuthenticatedRequest, res: Response) {
2025-09-24 10:46:55 +09:00
try {
const result = await BatchService.getAvailableConnections();
2025-09-24 10:46:55 +09:00
if (result.success) {
res.json(result);
2025-09-24 10:46:55 +09:00
} else {
res.status(500).json(result);
2025-09-24 10:46:55 +09:00
}
} catch (error) {
console.error("커넥션 목록 조회 오류:", error);
res.status(500).json({
2025-09-24 10:46:55 +09:00
success: false,
message: "커넥션 목록 조회에 실패했습니다."
2025-09-24 10:46:55 +09:00
});
}
}
/**
* (/ DB)
* GET /api/batch-configs/connections/:type/tables
* GET /api/batch-configs/connections/:type/:id/tables
2025-09-24 10:46:55 +09:00
*/
static async getTablesFromConnection(req: AuthenticatedRequest, res: Response) {
2025-09-24 10:46:55 +09:00
try {
const { type, id } = req.params;
if (!type || (type !== 'internal' && type !== 'external')) {
2025-09-24 10:46:55 +09:00
return res.status(400).json({
success: false,
message: "올바른 연결 타입을 지정해주세요. (internal 또는 external)"
2025-09-24 10:46:55 +09:00
});
}
const connectionId = type === 'external' ? Number(id) : undefined;
const result = await BatchService.getTablesFromConnection(type, connectionId);
2025-09-24 10:46:55 +09:00
if (result.success) {
return res.json(result);
2025-09-24 10:46:55 +09:00
} else {
return res.status(500).json(result);
2025-09-24 10:46:55 +09:00
}
} catch (error) {
console.error("테이블 목록 조회 오류:", error);
2025-09-24 10:46:55 +09:00
return res.status(500).json({
success: false,
message: "테이블 목록 조회에 실패했습니다."
2025-09-24 10:46:55 +09:00
});
}
}
/**
* (/ DB)
* GET /api/batch-configs/connections/:type/tables/:tableName/columns
* GET /api/batch-configs/connections/:type/:id/tables/:tableName/columns
2025-09-24 10:46:55 +09:00
*/
static async getTableColumns(req: AuthenticatedRequest, res: Response) {
2025-09-24 10:46:55 +09:00
try {
const { type, id, tableName } = req.params;
if (!type || !tableName) {
2025-09-24 10:46:55 +09:00
return res.status(400).json({
success: false,
message: "연결 타입과 테이블명을 모두 지정해주세요."
2025-09-24 10:46:55 +09:00
});
}
if (type !== 'internal' && type !== 'external') {
return res.status(400).json({
success: false,
message: "올바른 연결 타입을 지정해주세요. (internal 또는 external)"
});
}
2025-09-24 10:46:55 +09:00
const connectionId = type === 'external' ? Number(id) : undefined;
const result = await BatchService.getTableColumns(type, connectionId, tableName);
2025-09-24 10:46:55 +09:00
if (result.success) {
return res.json(result);
2025-09-24 10:46:55 +09:00
} else {
return res.status(500).json(result);
2025-09-24 10:46:55 +09:00
}
} catch (error) {
console.error("컬럼 정보 조회 오류:", error);
2025-09-24 10:46:55 +09:00
return res.status(500).json({
success: false,
message: "컬럼 정보 조회에 실패했습니다."
2025-09-24 10:46:55 +09:00
});
}
}
/**
*
* GET /api/batch-configs/:id
2025-09-24 10:46:55 +09:00
*/
static async getBatchConfigById(req: AuthenticatedRequest, res: Response) {
2025-09-24 10:46:55 +09:00
try {
const { id } = req.params;
const batchConfig = await BatchService.getBatchConfigById(Number(id));
if (!batchConfig) {
return res.status(404).json({
2025-09-24 10:46:55 +09:00
success: false,
message: "배치 설정을 찾을 수 없습니다."
2025-09-24 10:46:55 +09:00
});
}
return res.json({
success: true,
data: batchConfig
});
2025-09-24 10:46:55 +09:00
} catch (error) {
console.error("배치 설정 조회 오류:", error);
2025-09-24 10:46:55 +09:00
return res.status(500).json({
success: false,
message: "배치 설정 조회에 실패했습니다."
2025-09-24 10:46:55 +09:00
});
}
}
/**
*
* POST /api/batch-configs
2025-09-24 10:46:55 +09:00
*/
static async createBatchConfig(req: AuthenticatedRequest, res: Response) {
2025-09-24 10:46:55 +09:00
try {
const { batchName, description, cronSchedule, mappings } = req.body;
if (!batchName || !cronSchedule || !mappings || !Array.isArray(mappings)) {
return res.status(400).json({
success: false,
message: "필수 필드가 누락되었습니다. (batchName, cronSchedule, mappings)"
});
2025-09-24 10:46:55 +09:00
}
const batchConfig = await BatchService.createBatchConfig({
batchName,
description,
cronSchedule,
mappings
} as CreateBatchConfigRequest);
// 생성된 배치가 활성화 상태라면 스케줄러에 등록
if (batchConfig.data && batchConfig.data.is_active === 'Y' && batchConfig.data.id) {
await BatchSchedulerService.updateBatchSchedule(batchConfig.data.id);
}
return res.status(201).json({
success: true,
data: batchConfig,
message: "배치 설정이 성공적으로 생성되었습니다."
});
2025-09-24 10:46:55 +09:00
} catch (error) {
console.error("배치 설정 생성 오류:", error);
2025-09-24 10:46:55 +09:00
return res.status(500).json({
success: false,
message: "배치 설정 생성에 실패했습니다."
2025-09-24 10:46:55 +09:00
});
}
}
/**
*
* PUT /api/batch-configs/:id
2025-09-24 10:46:55 +09:00
*/
static async updateBatchConfig(req: AuthenticatedRequest, res: Response) {
2025-09-24 10:46:55 +09:00
try {
const { id } = req.params;
const { batchName, description, cronSchedule, mappings, isActive } = req.body;
if (!batchName || !cronSchedule) {
2025-09-24 10:46:55 +09:00
return res.status(400).json({
success: false,
message: "필수 필드가 누락되었습니다. (batchName, cronSchedule)"
2025-09-24 10:46:55 +09:00
});
}
const batchConfig = await BatchService.updateBatchConfig(Number(id), {
batchName,
description,
cronSchedule,
mappings,
isActive
} as UpdateBatchConfigRequest);
if (!batchConfig) {
return res.status(404).json({
2025-09-24 10:46:55 +09:00
success: false,
message: "배치 설정을 찾을 수 없습니다."
2025-09-24 10:46:55 +09:00
});
}
// 스케줄러에서 배치 스케줄 업데이트 (활성화 시 즉시 스케줄 등록)
await BatchSchedulerService.updateBatchSchedule(Number(id));
return res.json({
success: true,
data: batchConfig,
message: "배치 설정이 성공적으로 수정되었습니다."
});
2025-09-24 10:46:55 +09:00
} catch (error) {
console.error("배치 설정 수정 오류:", error);
2025-09-24 10:46:55 +09:00
return res.status(500).json({
success: false,
message: "배치 설정 수정에 실패했습니다."
2025-09-24 10:46:55 +09:00
});
}
}
/**
* ( )
* DELETE /api/batch-configs/:id
2025-09-24 10:46:55 +09:00
*/
static async deleteBatchConfig(req: AuthenticatedRequest, res: Response) {
2025-09-24 10:46:55 +09:00
try {
const { id } = req.params;
const result = await BatchService.deleteBatchConfig(Number(id));
if (!result) {
return res.status(404).json({
2025-09-24 10:46:55 +09:00
success: false,
message: "배치 설정을 찾을 수 없습니다."
2025-09-24 10:46:55 +09:00
});
}
return res.json({
success: true,
message: "배치 설정이 성공적으로 삭제되었습니다."
});
2025-09-24 10:46:55 +09:00
} catch (error) {
console.error("배치 설정 삭제 오류:", error);
2025-09-24 10:46:55 +09:00
return res.status(500).json({
success: false,
message: "배치 설정 삭제에 실패했습니다."
2025-09-24 10:46:55 +09:00
});
}
}
}