-- Phase 3: Update Database Functions to Use Dynamic Supabase URL -- This migration updates database functions to fetch the Supabase URL from admin_settings -- instead of hardcoding it, allowing for easier environment management. -- Add Supabase API URL to admin settings for dynamic lookup INSERT INTO admin_settings (setting_key, setting_value, category, description, updated_by) VALUES ( 'supabase_api_url', '"https://api.thrillwiki.com"'::jsonb, 'system', 'Base URL for Supabase API calls (used by database functions)', NULL ) ON CONFLICT (setting_key) DO UPDATE SET setting_value = EXCLUDED.setting_value, description = EXCLUDED.description, updated_at = NOW(); -- Update Function 1: notify_discord_via_edge() CREATE OR REPLACE FUNCTION public.notify_discord_via_edge() RETURNS trigger LANGUAGE plpgsql SET search_path = 'public' AS $function$ DECLARE url text; base_url text; payload jsonb; BEGIN -- Get base URL from settings table SELECT setting_value::text INTO base_url FROM admin_settings WHERE setting_key = 'supabase_api_url'; -- Remove quotes from JSONB string base_url := trim(both '"' from base_url); -- Fallback to custom domain if setting not found IF base_url IS NULL THEN base_url := 'https://api.thrillwiki.com'; END IF; url := base_url || '/functions/v1/discord-webhook-poster'; payload := jsonb_build_object( 'table', TG_TABLE_SCHEMA || '.' || TG_TABLE_NAME, 'row', to_jsonb(NEW) ); PERFORM public.pg_net.http_post( url, payload::text, 'application/json' ); RETURN NEW; EXCEPTION WHEN OTHERS THEN RAISE NOTICE 'Failed to call discord edge function: %', SQLERRM; RETURN NEW; END; $function$; -- Update Function 2: notify_moderators_submission_new() CREATE OR REPLACE FUNCTION public.notify_moderators_submission_new() RETURNS trigger LANGUAGE plpgsql SECURITY DEFINER SET search_path = 'public' AS $function$ DECLARE base_url text; edge_function_url text; payload jsonb; BEGIN -- Get base URL from settings SELECT setting_value::text INTO base_url FROM admin_settings WHERE setting_key = 'supabase_api_url'; base_url := trim(both '"' from base_url); IF base_url IS NULL THEN base_url := 'https://api.thrillwiki.com'; END IF; edge_function_url := base_url || '/functions/v1/notify-moderators'; payload := jsonb_build_object( 'event_type', 'new_submission', 'submission_id', NEW.id, 'submission_type', NEW.submission_type, 'user_id', NEW.user_id ); PERFORM public.pg_net.http_post( edge_function_url, payload::text, 'application/json' ); RETURN NEW; EXCEPTION WHEN OTHERS THEN RAISE NOTICE 'Failed to notify moderators: %', SQLERRM; RETURN NEW; END; $function$; -- Update Function 3: notify_moderators_report_new() CREATE OR REPLACE FUNCTION public.notify_moderators_report_new() RETURNS trigger LANGUAGE plpgsql SECURITY DEFINER SET search_path = 'public' AS $function$ DECLARE base_url text; edge_function_url text; payload jsonb; BEGIN -- Get base URL from settings SELECT setting_value::text INTO base_url FROM admin_settings WHERE setting_key = 'supabase_api_url'; base_url := trim(both '"' from base_url); IF base_url IS NULL THEN base_url := 'https://api.thrillwiki.com'; END IF; edge_function_url := base_url || '/functions/v1/notify-moderators'; payload := jsonb_build_object( 'event_type', 'new_report', 'report_id', NEW.id, 'reported_content_type', NEW.content_type, 'reporter_id', NEW.reporter_id ); PERFORM public.pg_net.http_post( edge_function_url, payload::text, 'application/json' ); RETURN NEW; EXCEPTION WHEN OTHERS THEN RAISE NOTICE 'Failed to notify moderators: %', SQLERRM; RETURN NEW; END; $function$; -- Update Function 4: notify_user_submission_status_change() CREATE OR REPLACE FUNCTION public.notify_user_submission_status_change() RETURNS trigger LANGUAGE plpgsql SECURITY DEFINER SET search_path = 'public' AS $function$ DECLARE base_url text; edge_function_url text; payload jsonb; BEGIN -- Only notify on status changes IF OLD.status IS NOT DISTINCT FROM NEW.status THEN RETURN NEW; END IF; -- Get base URL from settings SELECT setting_value::text INTO base_url FROM admin_settings WHERE setting_key = 'supabase_api_url'; base_url := trim(both '"' from base_url); IF base_url IS NULL THEN base_url := 'https://api.thrillwiki.com'; END IF; edge_function_url := base_url || '/functions/v1/notify-user'; payload := jsonb_build_object( 'event_type', 'submission_status_change', 'submission_id', NEW.id, 'user_id', NEW.user_id, 'old_status', OLD.status, 'new_status', NEW.status ); PERFORM public.pg_net.http_post( edge_function_url, payload::text, 'application/json' ); RETURN NEW; EXCEPTION WHEN OTHERS THEN RAISE NOTICE 'Failed to notify user: %', SQLERRM; RETURN NEW; END; $function$; -- Update Function 5: manage_moderator_topic_trigger() CREATE OR REPLACE FUNCTION public.manage_moderator_topic_trigger() RETURNS trigger LANGUAGE plpgsql SECURITY DEFINER SET search_path = 'public' AS $function$ DECLARE base_url text; edge_function_url text; payload jsonb; operation_type text; BEGIN -- Get base URL from settings SELECT setting_value::text INTO base_url FROM admin_settings WHERE setting_key = 'supabase_api_url'; base_url := trim(both '"' from base_url); IF base_url IS NULL THEN base_url := 'https://api.thrillwiki.com'; END IF; edge_function_url := base_url || '/functions/v1/manage-moderator-topics'; IF TG_OP = 'INSERT' THEN operation_type := 'subscribe'; ELSIF TG_OP = 'DELETE' THEN operation_type := 'unsubscribe'; ELSE RETURN NEW; END IF; payload := jsonb_build_object( 'operation', operation_type, 'user_id', COALESCE(NEW.user_id, OLD.user_id), 'role', COALESCE(NEW.role, OLD.role) ); PERFORM public.pg_net.http_post( edge_function_url, payload::text, 'application/json' ); RETURN COALESCE(NEW, OLD); EXCEPTION WHEN OTHERS THEN RAISE NOTICE 'Failed to manage moderator topics: %', SQLERRM; RETURN COALESCE(NEW, OLD); END; $function$; -- Update Function 6: create_novu_subscriber_trigger() CREATE OR REPLACE FUNCTION public.create_novu_subscriber_trigger() RETURNS trigger LANGUAGE plpgsql SECURITY DEFINER SET search_path = 'public' AS $function$ DECLARE base_url text; edge_function_url text; payload jsonb; user_email text; BEGIN -- Get user email from auth.users SELECT email INTO user_email FROM auth.users WHERE id = NEW.user_id; IF user_email IS NULL THEN RAISE NOTICE 'No email found for user %', NEW.user_id; RETURN NEW; END IF; -- Get base URL from settings SELECT setting_value::text INTO base_url FROM admin_settings WHERE setting_key = 'supabase_api_url'; base_url := trim(both '"' from base_url); IF base_url IS NULL THEN base_url := 'https://api.thrillwiki.com'; END IF; edge_function_url := base_url || '/functions/v1/create-novu-subscriber'; payload := jsonb_build_object( 'user_id', NEW.user_id, 'email', user_email, 'username', NEW.username ); PERFORM public.pg_net.http_post( edge_function_url, payload::text, 'application/json' ); RETURN NEW; EXCEPTION WHEN OTHERS THEN RAISE NOTICE 'Failed to create Novu subscriber: %', SQLERRM; RETURN NEW; END; $function$; -- Add comments for documentation COMMENT ON FUNCTION public.notify_discord_via_edge() IS 'Trigger function to notify Discord via edge function - uses dynamic URL from admin_settings'; COMMENT ON FUNCTION public.notify_moderators_submission_new() IS 'Trigger function to notify moderators of new submissions - uses dynamic URL from admin_settings'; COMMENT ON FUNCTION public.notify_moderators_report_new() IS 'Trigger function to notify moderators of new reports - uses dynamic URL from admin_settings'; COMMENT ON FUNCTION public.notify_user_submission_status_change() IS 'Trigger function to notify users of submission status changes - uses dynamic URL from admin_settings'; COMMENT ON FUNCTION public.manage_moderator_topic_trigger() IS 'Trigger function to manage Novu moderator topic subscriptions - uses dynamic URL from admin_settings'; COMMENT ON FUNCTION public.create_novu_subscriber_trigger() IS 'Trigger function to create Novu subscriber on profile creation - uses dynamic URL from admin_settings';