feat: Integrate audit logging for various operations
- Added audit logging functionality across multiple controllers, including menu, user, department, flow, screen, and table management. - Implemented logging for create, update, and delete actions, capturing relevant details such as company code, user information, and changes made. - Enhanced the category tree service with a new endpoint to check if category values are in use, improving data integrity checks. - Updated routes to include new functionalities and ensure proper logging for batch operations and individual record changes. - This integration improves traceability and accountability for data modifications within the application.
This commit is contained in:
@@ -12,7 +12,8 @@ import {
|
||||
ColumnListResponse,
|
||||
ColumnSettingsResponse,
|
||||
} from "../types/tableManagement";
|
||||
import { query } from "../database/db"; // 🆕 query 함수 import
|
||||
import { query } from "../database/db";
|
||||
import { auditLogService } from "../services/auditLogService";
|
||||
|
||||
/**
|
||||
* 테이블 목록 조회
|
||||
@@ -962,6 +963,21 @@ export async function addTableData(
|
||||
|
||||
logger.info(`테이블 데이터 추가 완료: ${tableName}, id: ${result.insertedId}`);
|
||||
|
||||
auditLogService.log({
|
||||
companyCode: req.user?.companyCode || "",
|
||||
userId: req.user?.userId || "",
|
||||
userName: req.user?.userName || "",
|
||||
action: "CREATE",
|
||||
resourceType: "DATA",
|
||||
resourceId: result.insertedId || "",
|
||||
resourceName: tableName,
|
||||
tableName,
|
||||
summary: `${tableName} 데이터 추가`,
|
||||
changes: { after: data },
|
||||
ipAddress: (req as any).ip,
|
||||
requestPath: req.originalUrl,
|
||||
});
|
||||
|
||||
const response: ApiResponse<{ id: string | null }> = {
|
||||
success: true,
|
||||
message: "테이블 데이터를 성공적으로 추가했습니다.",
|
||||
@@ -1080,6 +1096,16 @@ export async function editTableData(
|
||||
return;
|
||||
}
|
||||
|
||||
// 변경된 필드만 추출
|
||||
const changedBefore: Record<string, any> = {};
|
||||
const changedAfter: Record<string, any> = {};
|
||||
for (const key of Object.keys(updatedData)) {
|
||||
if (String(originalData[key] ?? "") !== String(updatedData[key] ?? "")) {
|
||||
changedBefore[key] = originalData[key];
|
||||
changedAfter[key] = updatedData[key];
|
||||
}
|
||||
}
|
||||
|
||||
// 데이터 수정
|
||||
await tableManagementService.editTableData(
|
||||
tableName,
|
||||
@@ -1089,6 +1115,23 @@ export async function editTableData(
|
||||
|
||||
logger.info(`테이블 데이터 수정 완료: ${tableName}`);
|
||||
|
||||
if (Object.keys(changedAfter).length > 0) {
|
||||
auditLogService.log({
|
||||
companyCode: req.user?.companyCode || "",
|
||||
userId: req.user?.userId || "",
|
||||
userName: req.user?.userName || "",
|
||||
action: "UPDATE",
|
||||
resourceType: "DATA",
|
||||
resourceId: originalData.id?.toString() || "",
|
||||
resourceName: tableName,
|
||||
tableName,
|
||||
summary: `${tableName} 데이터 수정`,
|
||||
changes: { before: changedBefore, after: changedAfter },
|
||||
ipAddress: (req as any).ip,
|
||||
requestPath: req.originalUrl,
|
||||
});
|
||||
}
|
||||
|
||||
const response: ApiResponse<null> = {
|
||||
success: true,
|
||||
message: "테이블 데이터를 성공적으로 수정했습니다.",
|
||||
@@ -1406,6 +1449,22 @@ export async function deleteTableData(
|
||||
`테이블 데이터 삭제 완료: ${tableName}, ${deletedCount}건 삭제`
|
||||
);
|
||||
|
||||
const deleteItems = Array.isArray(data) ? data : [data];
|
||||
auditLogService.log({
|
||||
companyCode: req.user?.companyCode || "",
|
||||
userId: req.user?.userId || "",
|
||||
userName: req.user?.userName || "",
|
||||
action: "DELETE",
|
||||
resourceType: "DATA",
|
||||
resourceId: deleteItems[0]?.id?.toString() || "",
|
||||
resourceName: tableName,
|
||||
tableName,
|
||||
summary: `${tableName} 데이터 삭제 (${deletedCount}건)`,
|
||||
changes: { before: { deletedCount, items: deleteItems.length } },
|
||||
ipAddress: (req as any).ip,
|
||||
requestPath: req.originalUrl,
|
||||
});
|
||||
|
||||
const response: ApiResponse<{ deletedCount: number }> = {
|
||||
success: true,
|
||||
message: `테이블 데이터를 성공적으로 삭제했습니다. (${deletedCount}건)`,
|
||||
@@ -2285,6 +2344,21 @@ export async function multiTableSave(
|
||||
subTableResultsCount: subTableResults.length,
|
||||
});
|
||||
|
||||
auditLogService.log({
|
||||
companyCode: req.user?.companyCode || "",
|
||||
userId: req.user?.userId || "",
|
||||
userName: req.user?.userName || "",
|
||||
action: isUpdate ? "UPDATE" : "CREATE",
|
||||
resourceType: "DATA",
|
||||
resourceId: savedPkValue?.toString() || "",
|
||||
resourceName: mainTableName,
|
||||
tableName: mainTableName,
|
||||
summary: `${mainTableName} 데이터 ${isUpdate ? "수정" : "생성"}${subTableResults.length > 0 ? ` (서브 테이블 ${subTableResults.length}건)` : ""}`,
|
||||
changes: { after: mainData },
|
||||
ipAddress: (req as any).ip,
|
||||
requestPath: req.originalUrl,
|
||||
});
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
message: "다중 테이블 저장이 완료되었습니다.",
|
||||
|
||||
Reference in New Issue
Block a user