140 lines
3.9 KiB
TypeScript
140 lines
3.9 KiB
TypeScript
|
|
import { Response } from "express";
|
||
|
|
import { AuthenticatedRequest } from "../middleware/authMiddleware";
|
||
|
|
import { auditLogService } from "../services/auditLogService";
|
||
|
|
import { query } from "../database/db";
|
||
|
|
import logger from "../utils/logger";
|
||
|
|
|
||
|
|
export const getAuditLogs = async (
|
||
|
|
req: AuthenticatedRequest,
|
||
|
|
res: Response
|
||
|
|
): Promise<void> => {
|
||
|
|
try {
|
||
|
|
const userCompanyCode = req.user?.companyCode;
|
||
|
|
const isSuperAdmin = userCompanyCode === "*";
|
||
|
|
|
||
|
|
const {
|
||
|
|
companyCode,
|
||
|
|
userId,
|
||
|
|
resourceType,
|
||
|
|
action,
|
||
|
|
tableName,
|
||
|
|
dateFrom,
|
||
|
|
dateTo,
|
||
|
|
search,
|
||
|
|
page,
|
||
|
|
limit,
|
||
|
|
} = req.query;
|
||
|
|
|
||
|
|
const result = await auditLogService.queryLogs(
|
||
|
|
{
|
||
|
|
companyCode: (companyCode as string) || (isSuperAdmin ? undefined : userCompanyCode),
|
||
|
|
userId: userId as string,
|
||
|
|
resourceType: resourceType as string,
|
||
|
|
action: action as string,
|
||
|
|
tableName: tableName as string,
|
||
|
|
dateFrom: dateFrom as string,
|
||
|
|
dateTo: dateTo as string,
|
||
|
|
search: search as string,
|
||
|
|
page: page ? parseInt(page as string, 10) : 1,
|
||
|
|
limit: limit ? parseInt(limit as string, 10) : 50,
|
||
|
|
},
|
||
|
|
isSuperAdmin
|
||
|
|
);
|
||
|
|
|
||
|
|
res.json({
|
||
|
|
success: true,
|
||
|
|
data: result.data,
|
||
|
|
total: result.total,
|
||
|
|
page: page ? parseInt(page as string, 10) : 1,
|
||
|
|
limit: limit ? parseInt(limit as string, 10) : 50,
|
||
|
|
});
|
||
|
|
} catch (error: any) {
|
||
|
|
logger.error("감사 로그 조회 실패", { error: error.message });
|
||
|
|
res.status(500).json({
|
||
|
|
success: false,
|
||
|
|
message: "감사 로그 조회 중 오류가 발생했습니다.",
|
||
|
|
});
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
export const getAuditLogStats = async (
|
||
|
|
req: AuthenticatedRequest,
|
||
|
|
res: Response
|
||
|
|
): Promise<void> => {
|
||
|
|
try {
|
||
|
|
const userCompanyCode = req.user?.companyCode;
|
||
|
|
const isSuperAdmin = userCompanyCode === "*";
|
||
|
|
const { companyCode, days } = req.query;
|
||
|
|
|
||
|
|
const targetCompany = isSuperAdmin
|
||
|
|
? (companyCode as string) || undefined
|
||
|
|
: userCompanyCode;
|
||
|
|
|
||
|
|
const stats = await auditLogService.getStats(
|
||
|
|
targetCompany,
|
||
|
|
days ? parseInt(days as string, 10) : 30
|
||
|
|
);
|
||
|
|
|
||
|
|
res.json({ success: true, data: stats });
|
||
|
|
} catch (error: any) {
|
||
|
|
logger.error("감사 로그 통계 조회 실패", { error: error.message });
|
||
|
|
res.status(500).json({
|
||
|
|
success: false,
|
||
|
|
message: "감사 로그 통계 조회 중 오류가 발생했습니다.",
|
||
|
|
});
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
export const getAuditLogUsers = async (
|
||
|
|
req: AuthenticatedRequest,
|
||
|
|
res: Response
|
||
|
|
): Promise<void> => {
|
||
|
|
try {
|
||
|
|
const userCompanyCode = req.user?.companyCode;
|
||
|
|
const isSuperAdmin = userCompanyCode === "*";
|
||
|
|
const { companyCode } = req.query;
|
||
|
|
|
||
|
|
const conditions: string[] = ["LOWER(u.status) = 'active'"];
|
||
|
|
const params: any[] = [];
|
||
|
|
let paramIndex = 1;
|
||
|
|
|
||
|
|
if (!isSuperAdmin) {
|
||
|
|
conditions.push(`u.company_code = $${paramIndex++}`);
|
||
|
|
params.push(userCompanyCode);
|
||
|
|
} else if (companyCode) {
|
||
|
|
conditions.push(`u.company_code = $${paramIndex++}`);
|
||
|
|
params.push(companyCode);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!isSuperAdmin) {
|
||
|
|
conditions.push(`u.company_code != '*'`);
|
||
|
|
}
|
||
|
|
|
||
|
|
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
||
|
|
|
||
|
|
const users = await query<{ user_id: string; user_name: string; count: number }>(
|
||
|
|
`SELECT
|
||
|
|
u.user_id,
|
||
|
|
u.user_name,
|
||
|
|
COALESCE(sal.log_count, 0)::int as count
|
||
|
|
FROM user_info u
|
||
|
|
LEFT JOIN (
|
||
|
|
SELECT user_id, COUNT(*) as log_count
|
||
|
|
FROM system_audit_log
|
||
|
|
GROUP BY user_id
|
||
|
|
) sal ON u.user_id = sal.user_id
|
||
|
|
${whereClause}
|
||
|
|
ORDER BY count DESC, u.user_name ASC`,
|
||
|
|
params
|
||
|
|
);
|
||
|
|
|
||
|
|
res.json({ success: true, data: users });
|
||
|
|
} catch (error: any) {
|
||
|
|
logger.error("감사 로그 사용자 목록 조회 실패", { error: error.message });
|
||
|
|
res.status(500).json({
|
||
|
|
success: false,
|
||
|
|
message: "사용자 목록 조회 중 오류가 발생했습니다.",
|
||
|
|
});
|
||
|
|
}
|
||
|
|
};
|