Implement Phase 1 audit logging

Add centralized admin action logger and integrate logging for:
- Alert resolutions (system, rate limit, grouped)
- Role grants/revokes in UserRoleManager
- Incident creation/acknowledgement/resolution
- Moderation lock overrides

Includes file updates and usage across relevant components to ensure consistent audit trails.
This commit is contained in:
gpt-engineer-app[bot]
2025-11-11 14:22:30 +00:00
parent 53b576ecc1
commit 8581950a6e
7 changed files with 167 additions and 0 deletions

View File

@@ -44,6 +44,14 @@ export function useResolveAlertGroup() {
}
}
// Log to audit trail
const { logAdminAction } = await import('@/lib/adminActionAuditHelpers');
await logAdminAction('alert_group_resolved', {
alert_source: source,
alert_count: alertIds.length,
alert_ids: alertIds,
});
return { count: alertIds.length, updatedAlerts: data };
},
onMutate: async ({ alertIds }) => {

View File

@@ -90,6 +90,17 @@ export function useCreateIncident() {
.insert(incidentAlerts);
if (linkError) throw linkError;
// Log to audit trail
const { logAdminAction } = await import('@/lib/adminActionAuditHelpers');
await logAdminAction('incident_created', {
incident_id: incident.id,
incident_number: incident.incident_number,
title: title,
severity: severity,
alert_count: alertIds.length,
correlation_rule_id: ruleId,
});
return incident as Incident;
},
@@ -122,6 +133,16 @@ export function useAcknowledgeIncident() {
.single();
if (error) throw error;
// Log to audit trail
const { logAdminAction } = await import('@/lib/adminActionAuditHelpers');
await logAdminAction('incident_acknowledged', {
incident_id: incidentId,
incident_number: data.incident_number,
severity: data.severity,
status_change: 'open -> investigating',
});
return data as Incident;
},
onSuccess: () => {
@@ -149,6 +170,13 @@ export function useResolveIncident() {
resolveAlerts?: boolean;
}) => {
const userId = (await supabase.auth.getUser()).data.user?.id;
// Fetch incident details before resolving
const { data: incident } = await supabase
.from('incidents')
.select('incident_number, severity, alert_count')
.eq('id', incidentId)
.single();
// Update incident
const { error: incidentError } = await supabase
@@ -162,6 +190,17 @@ export function useResolveIncident() {
.eq('id', incidentId);
if (incidentError) throw incidentError;
// Log to audit trail
const { logAdminAction } = await import('@/lib/adminActionAuditHelpers');
await logAdminAction('incident_resolved', {
incident_id: incidentId,
incident_number: incident?.incident_number,
severity: incident?.severity,
alert_count: incident?.alert_count,
resolution_notes: resolutionNotes,
resolved_linked_alerts: resolveAlerts,
});
// Optionally resolve all linked alerts
if (resolveAlerts) {

View File

@@ -151,6 +151,16 @@ export function useResolveAlert() {
return useMutation({
mutationFn: async (id: string) => {
// Fetch full alert details before resolving
const { data: alert, error: fetchError } = await supabase
.from('rate_limit_alerts')
.select('*')
.eq('id', id)
.single();
if (fetchError) throw fetchError;
// Resolve the alert
const { data, error } = await supabase
.from('rate_limit_alerts')
.update({ resolved_at: new Date().toISOString() })
@@ -159,6 +169,18 @@ export function useResolveAlert() {
.single();
if (error) throw error;
// Log to audit trail
const { logAdminAction } = await import('@/lib/adminActionAuditHelpers');
await logAdminAction('rate_limit_alert_resolved', {
alert_id: id,
metric_type: alert.metric_type,
metric_value: alert.metric_value,
threshold_value: alert.threshold_value,
function_name: alert.function_name,
time_window_ms: alert.time_window_ms,
});
return data;
},
onSuccess: () => {