ERP-node/backend-node/src/routes/companyManagementRoutes.ts

183 lines
5.3 KiB
TypeScript

import express from "express";
import { authenticateToken } from "../middleware/authMiddleware";
import { AuthenticatedRequest } from "../types/auth";
import { logger } from "../utils/logger";
import { FileSystemManager } from "../utils/fileSystemManager";
import { PrismaClient } from "@prisma/client";
const router = express.Router();
const prisma = new PrismaClient();
// 모든 라우트에 인증 미들웨어 적용
router.use(authenticateToken);
/**
* DELETE /api/company-management/:companyCode
* 회사 삭제 및 파일 정리
*/
router.delete(
"/:companyCode",
async (req: AuthenticatedRequest, res): Promise<void> => {
try {
const { companyCode } = req.params;
const { createBackup = true } = req.body;
logger.info("회사 삭제 요청", {
companyCode,
createBackup,
userId: req.user?.userId,
});
// 1. 회사 존재 확인
const existingCompany = await prisma.company_mng.findUnique({
where: { company_code: companyCode },
});
if (!existingCompany) {
res.status(404).json({
success: false,
message: "존재하지 않는 회사입니다.",
errorCode: "COMPANY_NOT_FOUND",
});
return;
}
// 2. 회사 파일 정리 (백업 또는 삭제)
try {
await FileSystemManager.cleanupCompanyFiles(companyCode, createBackup);
logger.info("회사 파일 정리 완료", { companyCode, createBackup });
} catch (fileError) {
logger.error("회사 파일 정리 실패", { companyCode, error: fileError });
res.status(500).json({
success: false,
message: "회사 파일 정리 중 오류가 발생했습니다.",
error:
fileError instanceof Error ? fileError.message : "Unknown error",
});
return;
}
// 3. 데이터베이스에서 회사 삭제 (soft delete)
await prisma.company_mng.update({
where: { company_code: companyCode },
data: {
status: "deleted",
},
});
logger.info("회사 삭제 완료", {
companyCode,
companyName: existingCompany.company_name,
deletedBy: req.user?.userId,
});
res.json({
success: true,
message: `회사 '${existingCompany.company_name}'이(가) 성공적으로 삭제되었습니다.`,
data: {
companyCode,
companyName: existingCompany.company_name,
backupCreated: createBackup,
deletedAt: new Date().toISOString(),
},
});
} catch (error) {
logger.error("회사 삭제 실패", {
error,
companyCode: req.params.companyCode,
});
res.status(500).json({
success: false,
message: "회사 삭제 중 오류가 발생했습니다.",
error: error instanceof Error ? error.message : "Unknown error",
});
}
}
);
/**
* GET /api/company-management/:companyCode/disk-usage
* 회사별 디스크 사용량 조회
*/
router.get(
"/:companyCode/disk-usage",
async (req: AuthenticatedRequest, res): Promise<void> => {
try {
const { companyCode } = req.params;
const diskUsage = FileSystemManager.getCompanyDiskUsage(companyCode);
res.json({
success: true,
data: {
companyCode,
fileCount: diskUsage.fileCount,
totalSize: diskUsage.totalSize,
totalSizeMB:
Math.round((diskUsage.totalSize / 1024 / 1024) * 100) / 100,
lastChecked: new Date().toISOString(),
},
});
} catch (error) {
logger.error("디스크 사용량 조회 실패", {
error,
companyCode: req.params.companyCode,
});
res.status(500).json({
success: false,
message: "디스크 사용량 조회 중 오류가 발생했습니다.",
error: error instanceof Error ? error.message : "Unknown error",
});
}
}
);
/**
* GET /api/company-management/disk-usage/all
* 전체 회사 디스크 사용량 조회
*/
router.get(
"/disk-usage/all",
async (req: AuthenticatedRequest, res): Promise<void> => {
try {
const allUsage = FileSystemManager.getAllCompaniesDiskUsage();
const totalStats = allUsage.reduce(
(acc, company) => ({
totalFiles: acc.totalFiles + company.fileCount,
totalSize: acc.totalSize + company.totalSize,
}),
{ totalFiles: 0, totalSize: 0 }
);
res.json({
success: true,
data: {
companies: allUsage.map((company) => ({
...company,
totalSizeMB:
Math.round((company.totalSize / 1024 / 1024) * 100) / 100,
})),
summary: {
totalCompanies: allUsage.length,
totalFiles: totalStats.totalFiles,
totalSize: totalStats.totalSize,
totalSizeMB:
Math.round((totalStats.totalSize / 1024 / 1024) * 100) / 100,
},
lastChecked: new Date().toISOString(),
},
});
} catch (error) {
logger.error("전체 디스크 사용량 조회 실패", { error });
res.status(500).json({
success: false,
message: "전체 디스크 사용량 조회 중 오류가 발생했습니다.",
error: error instanceof Error ? error.message : "Unknown error",
});
}
}
);
export default router;