mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-22 14:31:12 -05:00
Fix security definer view issue by enabling security_invoker on grouped_alerts_view and implement grouped alerts system with new keys, hooks, components, and monitoring overview integration. Added migration to adjust view, updated query keys, created useGroupedAlerts, useAlertGroupActions, GroupedAlertsPanel, and updated MonitoringOverview to include grouped alerts.
91 lines
2.5 KiB
TypeScript
91 lines
2.5 KiB
TypeScript
import { useQuery } from '@tanstack/react-query';
|
|
import { supabase } from '@/lib/supabaseClient';
|
|
import { queryKeys } from '@/lib/queryKeys';
|
|
|
|
export interface GroupedAlert {
|
|
group_key: string;
|
|
alert_type?: string;
|
|
severity: 'critical' | 'high' | 'medium' | 'low';
|
|
source: 'system' | 'rate_limit';
|
|
function_name?: string;
|
|
metric_type?: string;
|
|
alert_count: number;
|
|
unresolved_count: number;
|
|
first_seen: string;
|
|
last_seen: string;
|
|
alert_ids: string[];
|
|
messages: string[];
|
|
has_resolved: boolean;
|
|
is_recurring: boolean;
|
|
is_active: boolean;
|
|
}
|
|
|
|
interface GroupedAlertsOptions {
|
|
includeResolved?: boolean;
|
|
minCount?: number;
|
|
severity?: 'critical' | 'high' | 'medium' | 'low';
|
|
}
|
|
|
|
export function useGroupedAlerts(options?: GroupedAlertsOptions) {
|
|
return useQuery({
|
|
queryKey: queryKeys.monitoring.groupedAlerts(options),
|
|
queryFn: async () => {
|
|
let query = supabase
|
|
.from('grouped_alerts_view')
|
|
.select('*')
|
|
.order('last_seen', { ascending: false });
|
|
|
|
if (!options?.includeResolved) {
|
|
query = query.gt('unresolved_count', 0);
|
|
}
|
|
|
|
if (options?.minCount) {
|
|
query = query.gte('alert_count', options.minCount);
|
|
}
|
|
|
|
if (options?.severity) {
|
|
query = query.eq('severity', options.severity);
|
|
}
|
|
|
|
const { data, error } = await query;
|
|
if (error) throw error;
|
|
|
|
return (data || []).map(alert => ({
|
|
...alert,
|
|
is_recurring: (alert.alert_count ?? 0) > 3,
|
|
is_active: new Date(alert.last_seen ?? new Date()).getTime() > Date.now() - 3600000,
|
|
})) as GroupedAlert[];
|
|
},
|
|
staleTime: 15000,
|
|
refetchInterval: 30000,
|
|
});
|
|
}
|
|
|
|
export function useAlertGroupDetails(groupKey: string, source: 'system' | 'rate_limit', alertIds: string[]) {
|
|
return useQuery({
|
|
queryKey: queryKeys.monitoring.alertGroupDetails(groupKey),
|
|
queryFn: async () => {
|
|
if (source === 'system') {
|
|
const { data, error } = await supabase
|
|
.from('system_alerts')
|
|
.select('*')
|
|
.in('id', alertIds)
|
|
.order('created_at', { ascending: false });
|
|
|
|
if (error) throw error;
|
|
return data || [];
|
|
} else {
|
|
const { data, error } = await supabase
|
|
.from('rate_limit_alerts')
|
|
.select('*')
|
|
.in('id', alertIds)
|
|
.order('created_at', { ascending: false });
|
|
|
|
if (error) throw error;
|
|
return data || [];
|
|
}
|
|
},
|
|
enabled: alertIds.length > 0,
|
|
});
|
|
}
|