mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-23 23:31:12 -05:00
Implement ML Anomaly Detection
Introduce statistical anomaly detection for metrics via edge function, hooks, and UI components. Adds detection algorithms (z-score, moving average, rate of change), anomaly storage, auto-alerts, and dashboard rendering of detected anomalies with run-once trigger and scheduling guidance.
This commit is contained in:
@@ -0,0 +1,143 @@
|
||||
-- ML-based Anomaly Detection System
|
||||
|
||||
-- Table: Time-series metrics for anomaly detection
|
||||
CREATE TABLE metric_time_series (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
metric_name TEXT NOT NULL,
|
||||
metric_category TEXT NOT NULL CHECK (metric_category IN ('system', 'database', 'rate_limit', 'moderation', 'api')),
|
||||
metric_value NUMERIC NOT NULL,
|
||||
timestamp TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
metadata JSONB,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Table: Detected anomalies
|
||||
CREATE TABLE anomaly_detections (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
metric_name TEXT NOT NULL,
|
||||
metric_category TEXT NOT NULL,
|
||||
anomaly_type TEXT NOT NULL CHECK (anomaly_type IN ('spike', 'drop', 'trend_change', 'outlier', 'pattern_break')),
|
||||
severity TEXT NOT NULL CHECK (severity IN ('critical', 'high', 'medium', 'low')),
|
||||
baseline_value NUMERIC NOT NULL,
|
||||
anomaly_value NUMERIC NOT NULL,
|
||||
deviation_score NUMERIC NOT NULL,
|
||||
confidence_score NUMERIC NOT NULL CHECK (confidence_score >= 0 AND confidence_score <= 1),
|
||||
detection_algorithm TEXT NOT NULL,
|
||||
time_window_start TIMESTAMPTZ NOT NULL,
|
||||
time_window_end TIMESTAMPTZ NOT NULL,
|
||||
detected_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
alert_created BOOLEAN NOT NULL DEFAULT false,
|
||||
alert_id UUID,
|
||||
metadata JSONB,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Table: Anomaly detection configuration
|
||||
CREATE TABLE anomaly_detection_config (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
metric_name TEXT NOT NULL UNIQUE,
|
||||
metric_category TEXT NOT NULL,
|
||||
enabled BOOLEAN NOT NULL DEFAULT true,
|
||||
sensitivity NUMERIC NOT NULL DEFAULT 3.0 CHECK (sensitivity > 0),
|
||||
lookback_window_minutes INTEGER NOT NULL DEFAULT 60,
|
||||
detection_algorithms TEXT[] NOT NULL DEFAULT ARRAY['z_score', 'moving_average', 'rate_of_change'],
|
||||
min_data_points INTEGER NOT NULL DEFAULT 10,
|
||||
alert_threshold_score NUMERIC NOT NULL DEFAULT 2.5,
|
||||
auto_create_alert BOOLEAN NOT NULL DEFAULT true,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- View: Recent anomalies with alert status
|
||||
CREATE OR REPLACE VIEW recent_anomalies_view
|
||||
WITH (security_invoker=on)
|
||||
AS
|
||||
SELECT
|
||||
ad.id,
|
||||
ad.metric_name,
|
||||
ad.metric_category,
|
||||
ad.anomaly_type,
|
||||
ad.severity,
|
||||
ad.baseline_value,
|
||||
ad.anomaly_value,
|
||||
ad.deviation_score,
|
||||
ad.confidence_score,
|
||||
ad.detection_algorithm,
|
||||
ad.time_window_start,
|
||||
ad.time_window_end,
|
||||
ad.detected_at,
|
||||
ad.alert_created,
|
||||
ad.alert_id,
|
||||
sa.message as alert_message,
|
||||
sa.resolved_at as alert_resolved_at
|
||||
FROM anomaly_detections ad
|
||||
LEFT JOIN system_alerts sa ON sa.id = ad.alert_id::uuid
|
||||
WHERE ad.detected_at > NOW() - INTERVAL '24 hours'
|
||||
ORDER BY ad.detected_at DESC;
|
||||
|
||||
-- Insert default anomaly detection configurations
|
||||
INSERT INTO anomaly_detection_config (metric_name, metric_category, sensitivity, lookback_window_minutes, detection_algorithms, alert_threshold_score) VALUES
|
||||
('error_rate', 'system', 2.5, 60, ARRAY['z_score', 'moving_average'], 2.0),
|
||||
('response_time', 'api', 3.0, 30, ARRAY['z_score', 'rate_of_change'], 2.5),
|
||||
('database_connections', 'database', 2.0, 120, ARRAY['z_score', 'moving_average'], 3.0),
|
||||
('rate_limit_violations', 'rate_limit', 2.5, 60, ARRAY['z_score', 'spike_detection'], 2.0),
|
||||
('moderation_queue_size', 'moderation', 3.0, 120, ARRAY['z_score', 'trend_change'], 2.5),
|
||||
('cpu_usage', 'system', 2.5, 30, ARRAY['z_score', 'moving_average'], 2.0),
|
||||
('memory_usage', 'system', 2.5, 30, ARRAY['z_score', 'moving_average'], 2.0),
|
||||
('request_rate', 'api', 3.0, 60, ARRAY['z_score', 'rate_of_change'], 2.5);
|
||||
|
||||
-- Create indexes
|
||||
CREATE INDEX idx_metric_time_series_name_timestamp ON metric_time_series(metric_name, timestamp DESC);
|
||||
CREATE INDEX idx_metric_time_series_category_timestamp ON metric_time_series(metric_category, timestamp DESC);
|
||||
CREATE INDEX idx_anomaly_detections_detected_at ON anomaly_detections(detected_at DESC);
|
||||
CREATE INDEX idx_anomaly_detections_alert_created ON anomaly_detections(alert_created) WHERE alert_created = false;
|
||||
CREATE INDEX idx_anomaly_detections_metric ON anomaly_detections(metric_name, detected_at DESC);
|
||||
|
||||
-- Grant permissions
|
||||
GRANT SELECT, INSERT ON metric_time_series TO authenticated;
|
||||
GRANT SELECT ON anomaly_detections TO authenticated;
|
||||
GRANT SELECT ON anomaly_detection_config TO authenticated;
|
||||
GRANT SELECT ON recent_anomalies_view TO authenticated;
|
||||
|
||||
-- RLS Policies
|
||||
ALTER TABLE metric_time_series ENABLE ROW LEVEL SECURITY;
|
||||
ALTER TABLE anomaly_detections ENABLE ROW LEVEL SECURITY;
|
||||
ALTER TABLE anomaly_detection_config ENABLE ROW LEVEL SECURITY;
|
||||
|
||||
-- System can insert metrics
|
||||
CREATE POLICY system_insert_metrics ON metric_time_series
|
||||
FOR INSERT WITH CHECK (true);
|
||||
|
||||
-- Moderators can view all metrics
|
||||
CREATE POLICY moderators_view_metrics ON metric_time_series
|
||||
FOR SELECT USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM user_roles
|
||||
WHERE user_id = auth.uid()
|
||||
AND role IN ('moderator', 'admin', 'superuser')
|
||||
)
|
||||
);
|
||||
|
||||
-- Moderators can view anomalies
|
||||
CREATE POLICY moderators_view_anomalies ON anomaly_detections
|
||||
FOR SELECT USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM user_roles
|
||||
WHERE user_id = auth.uid()
|
||||
AND role IN ('moderator', 'admin', 'superuser')
|
||||
)
|
||||
);
|
||||
|
||||
-- System can insert anomalies
|
||||
CREATE POLICY system_insert_anomalies ON anomaly_detections
|
||||
FOR INSERT WITH CHECK (true);
|
||||
|
||||
-- Admins can manage anomaly config
|
||||
CREATE POLICY admins_manage_config ON anomaly_detection_config
|
||||
FOR ALL USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM user_roles
|
||||
WHERE user_id = auth.uid()
|
||||
AND role IN ('admin', 'superuser')
|
||||
)
|
||||
);
|
||||
Reference in New Issue
Block a user