diff --git a/supabase/migrations/20251029121347_72334d9e-394b-4c55-9d61-71e6c07bca13.sql b/supabase/migrations/20251029121347_72334d9e-394b-4c55-9d61-71e6c07bca13.sql new file mode 100644 index 00000000..9684aa17 --- /dev/null +++ b/supabase/migrations/20251029121347_72334d9e-394b-4c55-9d61-71e6c07bca13.sql @@ -0,0 +1,329 @@ +-- 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'; \ No newline at end of file