Implemented audit log system
This commit is contained in:
50
api/src/services/logging/auditLog.ts
Normal file
50
api/src/services/logging/auditLog.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
import pool from "../../db";
|
||||
import { logger } from "./logger";
|
||||
|
||||
export type AuditArea = 'member' | 'calendar' | 'unit' | 'auth' | 'admin' | 'application';
|
||||
|
||||
export interface AuditContext {
|
||||
actorId: number; // The person doing the action (created_by)
|
||||
targetId?: number; // The ID of the thing being changed (target_id)
|
||||
}
|
||||
|
||||
class AuditLogger {
|
||||
async record(
|
||||
area: AuditArea,
|
||||
action: string,
|
||||
context: AuditContext,
|
||||
data: Record<string, any> = {} // Already optional with default {}
|
||||
) {
|
||||
const actionType = `${area}.${action}`;
|
||||
|
||||
try {
|
||||
await pool.query(
|
||||
`INSERT INTO audit_log (action_type, payload, target_id, created_by)
|
||||
VALUES (?, ?, ?, ?)`, // Fixed: removed extra comma/placeholder
|
||||
[
|
||||
actionType,
|
||||
JSON.stringify(data),
|
||||
context.targetId || null,
|
||||
context.actorId,
|
||||
]
|
||||
);
|
||||
} catch (err) {
|
||||
logger.error('audit', `AUDIT_FAILURE: Failed to log ${actionType}`, { error: err });
|
||||
}
|
||||
}
|
||||
|
||||
// Making data optional using '?' and default parameter
|
||||
member(action: 'update_rank' | 'status_change' | 'create', context: AuditContext, data: any = {}) {
|
||||
return this.record('member', action, context, data);
|
||||
}
|
||||
|
||||
calendar(action: 'event_signup' | 'event_create' | 'attendance', context: AuditContext, data: any = {}) {
|
||||
return this.record('calendar', action, context, data);
|
||||
}
|
||||
|
||||
application(action: 'created' | 'approved' | 'denied' | 'restarted', context: AuditContext, data: any = {}) {
|
||||
return this.record('application', action, context, data);
|
||||
}
|
||||
}
|
||||
|
||||
export const audit = new AuditLogger();
|
||||
Reference in New Issue
Block a user