2026-03-04 15:02:27 +09:00
|
|
|
import { Request } from "express";
|
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.
2026-03-04 13:49:08 +09:00
|
|
|
import { query, pool } from "../database/db";
|
|
|
|
|
import logger from "../utils/logger";
|
|
|
|
|
|
2026-03-04 15:02:27 +09:00
|
|
|
export function getClientIp(req: Request): string {
|
|
|
|
|
const forwarded = req.headers["x-forwarded-for"];
|
|
|
|
|
if (forwarded) {
|
|
|
|
|
const first = Array.isArray(forwarded) ? forwarded[0] : forwarded.split(",")[0];
|
|
|
|
|
return first.trim();
|
|
|
|
|
}
|
|
|
|
|
const realIp = req.headers["x-real-ip"];
|
|
|
|
|
if (realIp) {
|
|
|
|
|
return Array.isArray(realIp) ? realIp[0] : realIp;
|
|
|
|
|
}
|
|
|
|
|
return req.ip || req.socket?.remoteAddress || "unknown";
|
|
|
|
|
}
|
|
|
|
|
|
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.
2026-03-04 13:49:08 +09:00
|
|
|
export type AuditAction =
|
|
|
|
|
| "CREATE"
|
|
|
|
|
| "UPDATE"
|
|
|
|
|
| "DELETE"
|
|
|
|
|
| "COPY"
|
|
|
|
|
| "LOGIN"
|
|
|
|
|
| "STATUS_CHANGE"
|
|
|
|
|
| "BATCH_CREATE"
|
|
|
|
|
| "BATCH_UPDATE"
|
|
|
|
|
| "BATCH_DELETE";
|
|
|
|
|
|
|
|
|
|
export type AuditResourceType =
|
|
|
|
|
| "MENU"
|
|
|
|
|
| "SCREEN"
|
|
|
|
|
| "SCREEN_LAYOUT"
|
|
|
|
|
| "FLOW"
|
|
|
|
|
| "FLOW_STEP"
|
|
|
|
|
| "USER"
|
|
|
|
|
| "ROLE"
|
|
|
|
|
| "PERMISSION"
|
|
|
|
|
| "COMPANY"
|
|
|
|
|
| "CODE_CATEGORY"
|
|
|
|
|
| "CODE"
|
|
|
|
|
| "DATA"
|
|
|
|
|
| "TABLE"
|
|
|
|
|
| "NUMBERING_RULE"
|
2026-03-12 02:13:15 +09:00
|
|
|
| "BATCH"
|
|
|
|
|
| "NODE_FLOW";
|
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.
2026-03-04 13:49:08 +09:00
|
|
|
|
|
|
|
|
export interface AuditLogParams {
|
|
|
|
|
companyCode: string;
|
|
|
|
|
userId: string;
|
|
|
|
|
userName?: string;
|
|
|
|
|
action: AuditAction;
|
|
|
|
|
resourceType: AuditResourceType;
|
|
|
|
|
resourceId?: string;
|
|
|
|
|
resourceName?: string;
|
|
|
|
|
tableName?: string;
|
|
|
|
|
summary?: string;
|
|
|
|
|
changes?: {
|
|
|
|
|
before?: Record<string, any>;
|
|
|
|
|
after?: Record<string, any>;
|
|
|
|
|
fields?: string[];
|
|
|
|
|
};
|
|
|
|
|
ipAddress?: string;
|
|
|
|
|
requestPath?: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface AuditLogEntry {
|
|
|
|
|
id: number;
|
|
|
|
|
company_code: string;
|
2026-03-12 05:14:27 +09:00
|
|
|
company_name: string | null;
|
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.
2026-03-04 13:49:08 +09:00
|
|
|
user_id: string;
|
|
|
|
|
user_name: string | null;
|
|
|
|
|
action: string;
|
|
|
|
|
resource_type: string;
|
|
|
|
|
resource_id: string | null;
|
|
|
|
|
resource_name: string | null;
|
|
|
|
|
table_name: string | null;
|
|
|
|
|
summary: string | null;
|
|
|
|
|
changes: any;
|
|
|
|
|
ip_address: string | null;
|
|
|
|
|
request_path: string | null;
|
|
|
|
|
created_at: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface AuditLogFilters {
|
|
|
|
|
companyCode?: string;
|
|
|
|
|
userId?: string;
|
|
|
|
|
resourceType?: string;
|
|
|
|
|
action?: string;
|
|
|
|
|
tableName?: string;
|
|
|
|
|
dateFrom?: string;
|
|
|
|
|
dateTo?: string;
|
|
|
|
|
search?: string;
|
|
|
|
|
page?: number;
|
|
|
|
|
limit?: number;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface AuditLogStats {
|
|
|
|
|
dailyCounts: Array<{ date: string; count: number }>;
|
|
|
|
|
resourceTypeCounts: Array<{ resource_type: string; count: number }>;
|
|
|
|
|
actionCounts: Array<{ action: string; count: number }>;
|
|
|
|
|
topUsers: Array<{ user_id: string; user_name: string; count: number }>;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class AuditLogService {
|
|
|
|
|
/**
|
|
|
|
|
* 감사 로그 1건 기록 (fire-and-forget)
|
|
|
|
|
* 본 작업에 영향을 주지 않도록 에러를 내부에서 처리
|
|
|
|
|
*/
|
|
|
|
|
async log(params: AuditLogParams): Promise<void> {
|
|
|
|
|
try {
|
2026-03-12 05:14:27 +09:00
|
|
|
logger.info(`[AuditLog] 기록 시도: ${params.resourceType} / ${params.action} / ${params.resourceName || params.resourceId || "N/A"}`);
|
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.
2026-03-04 13:49:08 +09:00
|
|
|
await query(
|
|
|
|
|
`INSERT INTO system_audit_log
|
|
|
|
|
(company_code, user_id, user_name, action, resource_type,
|
|
|
|
|
resource_id, resource_name, table_name, summary, changes,
|
|
|
|
|
ip_address, request_path)
|
|
|
|
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)`,
|
|
|
|
|
[
|
|
|
|
|
params.companyCode,
|
|
|
|
|
params.userId,
|
|
|
|
|
params.userName || null,
|
|
|
|
|
params.action,
|
|
|
|
|
params.resourceType,
|
|
|
|
|
params.resourceId || null,
|
|
|
|
|
params.resourceName || null,
|
|
|
|
|
params.tableName || null,
|
|
|
|
|
params.summary || null,
|
|
|
|
|
params.changes ? JSON.stringify(params.changes) : null,
|
|
|
|
|
params.ipAddress || null,
|
|
|
|
|
params.requestPath || null,
|
|
|
|
|
]
|
|
|
|
|
);
|
2026-03-12 05:14:27 +09:00
|
|
|
logger.info(`[AuditLog] 기록 성공: ${params.resourceType} / ${params.action}`);
|
|
|
|
|
} catch (error: any) {
|
|
|
|
|
logger.error(`[AuditLog] 기록 실패: ${params.resourceType} / ${params.action} - ${error?.message}`, { error, params });
|
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.
2026-03-04 13:49:08 +09:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 감사 로그 다건 기록 (배치)
|
|
|
|
|
*/
|
|
|
|
|
async logBatch(entries: AuditLogParams[]): Promise<void> {
|
|
|
|
|
if (entries.length === 0) return;
|
|
|
|
|
try {
|
|
|
|
|
const values = entries
|
|
|
|
|
.map(
|
|
|
|
|
(_, i) =>
|
|
|
|
|
`($${i * 12 + 1}, $${i * 12 + 2}, $${i * 12 + 3}, $${i * 12 + 4}, $${i * 12 + 5}, $${i * 12 + 6}, $${i * 12 + 7}, $${i * 12 + 8}, $${i * 12 + 9}, $${i * 12 + 10}, $${i * 12 + 11}, $${i * 12 + 12})`
|
|
|
|
|
)
|
|
|
|
|
.join(", ");
|
|
|
|
|
|
|
|
|
|
const params = entries.flatMap((e) => [
|
|
|
|
|
e.companyCode,
|
|
|
|
|
e.userId,
|
|
|
|
|
e.userName || null,
|
|
|
|
|
e.action,
|
|
|
|
|
e.resourceType,
|
|
|
|
|
e.resourceId || null,
|
|
|
|
|
e.resourceName || null,
|
|
|
|
|
e.tableName || null,
|
|
|
|
|
e.summary || null,
|
|
|
|
|
e.changes ? JSON.stringify(e.changes) : null,
|
|
|
|
|
e.ipAddress || null,
|
|
|
|
|
e.requestPath || null,
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
await query(
|
|
|
|
|
`INSERT INTO system_audit_log
|
|
|
|
|
(company_code, user_id, user_name, action, resource_type,
|
|
|
|
|
resource_id, resource_name, table_name, summary, changes,
|
|
|
|
|
ip_address, request_path)
|
|
|
|
|
VALUES ${values}`,
|
|
|
|
|
params
|
|
|
|
|
);
|
|
|
|
|
} catch (error) {
|
|
|
|
|
logger.error("감사 로그 배치 기록 실패 (무시됨)", { error });
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 감사 로그 조회 (페이징, 필터)
|
|
|
|
|
*/
|
|
|
|
|
async queryLogs(
|
|
|
|
|
filters: AuditLogFilters,
|
|
|
|
|
isSuperAdmin: boolean = false
|
|
|
|
|
): Promise<{ data: AuditLogEntry[]; total: number }> {
|
|
|
|
|
const conditions: string[] = [];
|
|
|
|
|
const params: any[] = [];
|
|
|
|
|
let paramIndex = 1;
|
|
|
|
|
|
|
|
|
|
if (!isSuperAdmin && filters.companyCode) {
|
2026-03-12 05:14:27 +09:00
|
|
|
conditions.push(`sal.company_code = $${paramIndex++}`);
|
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.
2026-03-04 13:49:08 +09:00
|
|
|
params.push(filters.companyCode);
|
|
|
|
|
} else if (isSuperAdmin && filters.companyCode) {
|
2026-03-12 05:14:27 +09:00
|
|
|
conditions.push(`sal.company_code = $${paramIndex++}`);
|
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.
2026-03-04 13:49:08 +09:00
|
|
|
params.push(filters.companyCode);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (filters.userId) {
|
2026-03-12 05:14:27 +09:00
|
|
|
conditions.push(`sal.user_id = $${paramIndex++}`);
|
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.
2026-03-04 13:49:08 +09:00
|
|
|
params.push(filters.userId);
|
|
|
|
|
}
|
|
|
|
|
if (filters.resourceType) {
|
2026-03-12 05:14:27 +09:00
|
|
|
conditions.push(`sal.resource_type = $${paramIndex++}`);
|
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.
2026-03-04 13:49:08 +09:00
|
|
|
params.push(filters.resourceType);
|
|
|
|
|
}
|
|
|
|
|
if (filters.action) {
|
2026-03-12 05:14:27 +09:00
|
|
|
conditions.push(`sal.action = $${paramIndex++}`);
|
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.
2026-03-04 13:49:08 +09:00
|
|
|
params.push(filters.action);
|
|
|
|
|
}
|
|
|
|
|
if (filters.tableName) {
|
2026-03-12 05:14:27 +09:00
|
|
|
conditions.push(`sal.table_name = $${paramIndex++}`);
|
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.
2026-03-04 13:49:08 +09:00
|
|
|
params.push(filters.tableName);
|
|
|
|
|
}
|
|
|
|
|
if (filters.dateFrom) {
|
2026-03-12 05:14:27 +09:00
|
|
|
conditions.push(`sal.created_at >= $${paramIndex++}::timestamptz`);
|
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.
2026-03-04 13:49:08 +09:00
|
|
|
params.push(filters.dateFrom);
|
|
|
|
|
}
|
|
|
|
|
if (filters.dateTo) {
|
2026-03-12 05:14:27 +09:00
|
|
|
conditions.push(`sal.created_at <= $${paramIndex++}::timestamptz`);
|
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.
2026-03-04 13:49:08 +09:00
|
|
|
params.push(filters.dateTo);
|
|
|
|
|
}
|
|
|
|
|
if (filters.search) {
|
|
|
|
|
conditions.push(
|
2026-03-12 05:14:27 +09:00
|
|
|
`(sal.summary ILIKE $${paramIndex} OR sal.resource_name ILIKE $${paramIndex} OR sal.user_name ILIKE $${paramIndex})`
|
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.
2026-03-04 13:49:08 +09:00
|
|
|
);
|
|
|
|
|
params.push(`%${filters.search}%`);
|
|
|
|
|
paramIndex++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const whereClause =
|
|
|
|
|
conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
|
|
|
|
|
|
|
|
const page = filters.page || 1;
|
|
|
|
|
const limit = filters.limit || 50;
|
|
|
|
|
const offset = (page - 1) * limit;
|
|
|
|
|
|
|
|
|
|
const countResult = await query<{ count: string }>(
|
2026-03-12 05:14:27 +09:00
|
|
|
`SELECT COUNT(*) as count FROM system_audit_log sal ${whereClause}`,
|
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.
2026-03-04 13:49:08 +09:00
|
|
|
params
|
|
|
|
|
);
|
|
|
|
|
const total = parseInt(countResult[0].count, 10);
|
|
|
|
|
|
|
|
|
|
const data = await query<AuditLogEntry>(
|
2026-03-12 05:14:27 +09:00
|
|
|
`SELECT sal.*, ci.company_name
|
|
|
|
|
FROM system_audit_log sal
|
|
|
|
|
LEFT JOIN company_mng ci ON sal.company_code = ci.company_code
|
|
|
|
|
${whereClause}
|
|
|
|
|
ORDER BY sal.created_at DESC
|
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.
2026-03-04 13:49:08 +09:00
|
|
|
LIMIT $${paramIndex++} OFFSET $${paramIndex++}`,
|
|
|
|
|
[...params, limit, offset]
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
return { data, total };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 통계 조회
|
|
|
|
|
*/
|
|
|
|
|
async getStats(
|
|
|
|
|
companyCode?: string,
|
|
|
|
|
days: number = 30
|
|
|
|
|
): Promise<AuditLogStats> {
|
|
|
|
|
const companyFilter = companyCode
|
|
|
|
|
? "AND company_code = $1"
|
|
|
|
|
: "";
|
|
|
|
|
const params = companyCode ? [companyCode] : [];
|
|
|
|
|
|
|
|
|
|
const dailyCounts = await query<{ date: string; count: number }>(
|
|
|
|
|
`SELECT DATE(created_at) as date, COUNT(*)::int as count
|
|
|
|
|
FROM system_audit_log
|
|
|
|
|
WHERE created_at >= NOW() - INTERVAL '${days} days' ${companyFilter}
|
|
|
|
|
GROUP BY DATE(created_at)
|
|
|
|
|
ORDER BY date DESC`,
|
|
|
|
|
params
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const resourceTypeCounts = await query<{
|
|
|
|
|
resource_type: string;
|
|
|
|
|
count: number;
|
|
|
|
|
}>(
|
|
|
|
|
`SELECT resource_type, COUNT(*)::int as count
|
|
|
|
|
FROM system_audit_log
|
|
|
|
|
WHERE created_at >= NOW() - INTERVAL '${days} days' ${companyFilter}
|
|
|
|
|
GROUP BY resource_type
|
|
|
|
|
ORDER BY count DESC`,
|
|
|
|
|
params
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const actionCounts = await query<{ action: string; count: number }>(
|
|
|
|
|
`SELECT action, COUNT(*)::int as count
|
|
|
|
|
FROM system_audit_log
|
|
|
|
|
WHERE created_at >= NOW() - INTERVAL '${days} days' ${companyFilter}
|
|
|
|
|
GROUP BY action
|
|
|
|
|
ORDER BY count DESC`,
|
|
|
|
|
params
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const topUsers = await query<{
|
|
|
|
|
user_id: string;
|
|
|
|
|
user_name: string;
|
|
|
|
|
count: number;
|
|
|
|
|
}>(
|
|
|
|
|
`SELECT user_id, COALESCE(MAX(user_name), user_id) as user_name, COUNT(*)::int as count
|
|
|
|
|
FROM system_audit_log
|
|
|
|
|
WHERE created_at >= NOW() - INTERVAL '${days} days' ${companyFilter}
|
|
|
|
|
GROUP BY user_id
|
|
|
|
|
ORDER BY count DESC
|
|
|
|
|
LIMIT 10`,
|
|
|
|
|
params
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
return { dailyCounts, resourceTypeCounts, actionCounts, topUsers };
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const auditLogService = new AuditLogService();
|