diff --git a/supabase/migrations/20260422172628_59cd91b6-2e03-4e6a-9b92-1bcab3625f23.sql b/supabase/migrations/20260422172628_59cd91b6-2e03-4e6a-9b92-1bcab3625f23.sql new file mode 100644 index 0000000..4585be3 --- /dev/null +++ b/supabase/migrations/20260422172628_59cd91b6-2e03-4e6a-9b92-1bcab3625f23.sql @@ -0,0 +1,72 @@ +-- Trigger para chamar suspend-agent quando subscription fica inactive (canceled/past_due) +-- e resume-agent quando volta para active. + +CREATE OR REPLACE FUNCTION public.trigger_suspend_or_resume_agent() +RETURNS trigger +LANGUAGE plpgsql +SECURITY DEFINER +SET search_path = 'public', 'extensions' +AS $$ +DECLARE + v_supabase_url text; + v_anon_key text; + v_function text; + v_agent_id uuid; +BEGIN + -- Só age em UPDATE, não em INSERT inicial + IF TG_OP <> 'UPDATE' THEN + RETURN NEW; + END IF; + + IF NEW.status = OLD.status THEN + RETURN NEW; + END IF; + + -- Determina ação: active/trialing => resume; canceled/past_due/unpaid => suspend + IF NEW.status IN ('active', 'trialing') AND OLD.status NOT IN ('active', 'trialing') THEN + v_function := 'resume-agent'; + ELSIF NEW.status IN ('canceled', 'past_due', 'unpaid', 'paused') AND OLD.status IN ('active', 'trialing') THEN + v_function := 'suspend-agent'; + ELSE + RETURN NEW; + END IF; + + -- Busca o agent_instance correspondente + SELECT id INTO v_agent_id FROM public.agent_instances WHERE user_id = NEW.user_id LIMIT 1; + IF v_agent_id IS NULL THEN + RETURN NEW; + END IF; + + -- Lê config + BEGIN + SELECT decrypted_secret INTO v_supabase_url + FROM vault.decrypted_secrets WHERE name = 'project_url' LIMIT 1; + SELECT decrypted_secret INTO v_anon_key + FROM vault.decrypted_secrets WHERE name = 'anon_key' LIMIT 1; + EXCEPTION WHEN OTHERS THEN + v_supabase_url := NULL; + END; + + IF v_supabase_url IS NULL OR v_anon_key IS NULL THEN + RAISE LOG 'trigger_suspend_or_resume_agent: vault não configurado, pulando'; + RETURN NEW; + END IF; + + PERFORM net.http_post( + url := v_supabase_url || '/functions/v1/' || v_function, + headers := jsonb_build_object( + 'Content-Type', 'application/json', + 'Authorization', 'Bearer ' || v_anon_key + ), + body := jsonb_build_object('agent_instance_id', v_agent_id) + ); + + RETURN NEW; +END; +$$; + +DROP TRIGGER IF EXISTS subscription_status_change_trigger ON public.subscriptions; +CREATE TRIGGER subscription_status_change_trigger +AFTER UPDATE ON public.subscriptions +FOR EACH ROW +EXECUTE FUNCTION public.trigger_suspend_or_resume_agent(); \ No newline at end of file