mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-23 11:31:13 -05:00
Implement pipeline monitoring alerts
Approve and implement the Supabase migration for the pipeline monitoring alert system. This includes expanding alert types, adding new monitoring functions, and updating existing ones with escalating thresholds.
This commit is contained in:
124
src/components/admin/PipelineHealthAlerts.tsx
Normal file
124
src/components/admin/PipelineHealthAlerts.tsx
Normal file
@@ -0,0 +1,124 @@
|
||||
/**
|
||||
* Pipeline Health Alerts Component
|
||||
*
|
||||
* Displays critical pipeline alerts on the admin error monitoring dashboard.
|
||||
* Shows top 10 active alerts with severity-based styling and resolution actions.
|
||||
*/
|
||||
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
|
||||
import { useSystemAlerts } from '@/hooks/useSystemHealth';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { AlertTriangle, CheckCircle, XCircle, AlertCircle } from 'lucide-react';
|
||||
import { format } from 'date-fns';
|
||||
import { supabase } from '@/lib/supabaseClient';
|
||||
import { toast } from 'sonner';
|
||||
|
||||
const SEVERITY_CONFIG = {
|
||||
critical: { color: 'destructive', icon: XCircle },
|
||||
high: { color: 'destructive', icon: AlertCircle },
|
||||
medium: { color: 'default', icon: AlertTriangle },
|
||||
low: { color: 'secondary', icon: CheckCircle },
|
||||
} as const;
|
||||
|
||||
const ALERT_TYPE_LABELS: Record<string, string> = {
|
||||
failed_submissions: 'Failed Submissions',
|
||||
high_ban_rate: 'High Ban Attempt Rate',
|
||||
temp_ref_error: 'Temp Reference Error',
|
||||
orphaned_images: 'Orphaned Images',
|
||||
slow_approval: 'Slow Approvals',
|
||||
submission_queue_backlog: 'Queue Backlog',
|
||||
ban_attempt: 'Ban Attempt',
|
||||
upload_timeout: 'Upload Timeout',
|
||||
high_error_rate: 'High Error Rate',
|
||||
validation_error: 'Validation Error',
|
||||
stale_submissions: 'Stale Submissions',
|
||||
circular_dependency: 'Circular Dependency',
|
||||
};
|
||||
|
||||
export function PipelineHealthAlerts() {
|
||||
const { data: criticalAlerts } = useSystemAlerts('critical');
|
||||
const { data: highAlerts } = useSystemAlerts('high');
|
||||
const { data: mediumAlerts } = useSystemAlerts('medium');
|
||||
|
||||
const allAlerts = [
|
||||
...(criticalAlerts || []),
|
||||
...(highAlerts || []),
|
||||
...(mediumAlerts || [])
|
||||
].slice(0, 10);
|
||||
|
||||
const resolveAlert = async (alertId: string) => {
|
||||
const { error } = await supabase
|
||||
.from('system_alerts')
|
||||
.update({ resolved_at: new Date().toISOString() })
|
||||
.eq('id', alertId);
|
||||
|
||||
if (error) {
|
||||
toast.error('Failed to resolve alert');
|
||||
} else {
|
||||
toast.success('Alert resolved');
|
||||
}
|
||||
};
|
||||
|
||||
if (!allAlerts.length) {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle className="flex items-center gap-2">
|
||||
<CheckCircle className="w-5 h-5 text-green-500" />
|
||||
Pipeline Health: All Systems Operational
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<p className="text-sm text-muted-foreground">No active alerts. The sacred pipeline is flowing smoothly.</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>🚨 Active Pipeline Alerts</CardTitle>
|
||||
<CardDescription>
|
||||
Critical issues requiring attention ({allAlerts.length} active)
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-3">
|
||||
{allAlerts.map((alert) => {
|
||||
const config = SEVERITY_CONFIG[alert.severity];
|
||||
const Icon = config.icon;
|
||||
const label = ALERT_TYPE_LABELS[alert.alert_type] || alert.alert_type;
|
||||
|
||||
return (
|
||||
<div
|
||||
key={alert.id}
|
||||
className="flex items-start justify-between p-3 border rounded-lg hover:bg-accent transition-colors"
|
||||
>
|
||||
<div className="flex items-start gap-3 flex-1">
|
||||
<Icon className="w-5 h-5 mt-0.5 flex-shrink-0" />
|
||||
<div className="flex-1 min-w-0">
|
||||
<div className="flex items-center gap-2 mb-1">
|
||||
<Badge variant={config.color as any}>{alert.severity.toUpperCase()}</Badge>
|
||||
<span className="text-sm font-medium">{label}</span>
|
||||
</div>
|
||||
<p className="text-sm text-muted-foreground">{alert.message}</p>
|
||||
<p className="text-xs text-muted-foreground mt-1">
|
||||
{format(new Date(alert.created_at), 'PPp')}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => resolveAlert(alert.id)}
|
||||
>
|
||||
Resolve
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user