-- Rate Limit Alert Configuration -- Stores alert thresholds and tracks alert state -- Alert configuration table CREATE TABLE IF NOT EXISTS public.rate_limit_alert_config ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), metric_type TEXT NOT NULL CHECK (metric_type IN ('block_rate', 'total_requests', 'unique_ips', 'function_specific')), threshold_value NUMERIC NOT NULL, time_window_ms INTEGER NOT NULL DEFAULT 60000, function_name TEXT, -- nullable, only for function_specific alerts enabled BOOLEAN NOT NULL DEFAULT true, created_at TIMESTAMPTZ NOT NULL DEFAULT now(), updated_at TIMESTAMPTZ NOT NULL DEFAULT now(), created_by UUID REFERENCES auth.users(id), CONSTRAINT unique_alert_config UNIQUE (metric_type, function_name) ); -- Alert history table (tracks when alerts were triggered) CREATE TABLE IF NOT EXISTS public.rate_limit_alerts ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), config_id UUID REFERENCES public.rate_limit_alert_config(id) ON DELETE CASCADE, metric_type TEXT NOT NULL, metric_value NUMERIC NOT NULL, threshold_value NUMERIC NOT NULL, time_window_ms INTEGER NOT NULL, function_name TEXT, alert_message TEXT NOT NULL, resolved_at TIMESTAMPTZ, created_at TIMESTAMPTZ NOT NULL DEFAULT now() ); -- Enable RLS ALTER TABLE public.rate_limit_alert_config ENABLE ROW LEVEL SECURITY; ALTER TABLE public.rate_limit_alerts ENABLE ROW LEVEL SECURITY; -- RLS Policies for alert config (admin/moderator only) CREATE POLICY "Moderators can view alert configs" ON public.rate_limit_alert_config FOR SELECT TO authenticated USING ( EXISTS ( SELECT 1 FROM public.user_roles WHERE user_id = auth.uid() AND role IN ('admin', 'moderator', 'superuser') ) ); CREATE POLICY "Admins can manage alert configs" ON public.rate_limit_alert_config FOR ALL TO authenticated USING ( EXISTS ( SELECT 1 FROM public.user_roles WHERE user_id = auth.uid() AND role IN ('admin', 'superuser') ) ) WITH CHECK ( EXISTS ( SELECT 1 FROM public.user_roles WHERE user_id = auth.uid() AND role IN ('admin', 'superuser') ) ); -- RLS Policies for alert history (moderators can view) CREATE POLICY "Moderators can view alert history" ON public.rate_limit_alerts FOR SELECT TO authenticated USING ( EXISTS ( SELECT 1 FROM public.user_roles WHERE user_id = auth.uid() AND role IN ('admin', 'moderator', 'superuser') ) ); CREATE POLICY "System can insert alerts" ON public.rate_limit_alerts FOR INSERT TO authenticated WITH CHECK (true); -- Indexes for performance CREATE INDEX IF NOT EXISTS idx_rate_limit_alert_config_enabled ON public.rate_limit_alert_config(enabled); CREATE INDEX IF NOT EXISTS idx_rate_limit_alert_config_metric_type ON public.rate_limit_alert_config(metric_type); CREATE INDEX IF NOT EXISTS idx_rate_limit_alerts_created_at ON public.rate_limit_alerts(created_at DESC); CREATE INDEX IF NOT EXISTS idx_rate_limit_alerts_config_id ON public.rate_limit_alerts(config_id); CREATE INDEX IF NOT EXISTS idx_rate_limit_alerts_resolved ON public.rate_limit_alerts(resolved_at) WHERE resolved_at IS NULL; -- Function to update updated_at timestamp CREATE OR REPLACE FUNCTION update_rate_limit_alert_config_updated_at() RETURNS TRIGGER AS $$ BEGIN NEW.updated_at = now(); RETURN NEW; END; $$ LANGUAGE plpgsql; -- Trigger for updated_at CREATE TRIGGER update_rate_limit_alert_config_updated_at BEFORE UPDATE ON public.rate_limit_alert_config FOR EACH ROW EXECUTE FUNCTION update_rate_limit_alert_config_updated_at(); -- Insert default alert configurations INSERT INTO public.rate_limit_alert_config (metric_type, threshold_value, time_window_ms, enabled) VALUES ('block_rate', 0.5, 300000, true), -- Alert if block rate > 50% in 5 minutes ('total_requests', 1000, 60000, true), -- Alert if total requests > 1000/minute ('unique_ips', 100, 300000, false) -- Alert if unique IPs > 100 in 5 minutes (disabled by default) ON CONFLICT (metric_type, function_name) DO NOTHING; -- Grant necessary permissions GRANT SELECT, INSERT ON public.rate_limit_alerts TO authenticated; GRANT SELECT ON public.rate_limit_alert_config TO authenticated;