From f3a2e4611663a198f46adf438225f793bdb79d72 Mon Sep 17 00:00:00 2001 From: Arthur Belleville Date: Tue, 4 Nov 2025 08:25:35 +0100 Subject: [PATCH] debug trigger --- sql/40_debug_trigger.sql | 160 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 sql/40_debug_trigger.sql diff --git a/sql/40_debug_trigger.sql b/sql/40_debug_trigger.sql new file mode 100644 index 0000000..52dfa43 --- /dev/null +++ b/sql/40_debug_trigger.sql @@ -0,0 +1,160 @@ +create or replace function public.update_profile_subscription_status() +returns trigger as $$ +declare + v_user_id uuid; + v_plan subscription_plan; + v_customer_id text; + v_old_plan subscription_plan; + v_has_trialing boolean; + v_has_active boolean; + v_subscription_status text; + v_period_end timestamp; +begin + raise notice '==================== TRIGGER START ===================='; + raise notice 'Table: %, Operation: %, Time: %', TG_TABLE_NAME, TG_OP, now(); + + -- Get customer ID based on which table triggered this + if TG_TABLE_NAME = 'subscriptions' then + v_customer_id := new.customer; + v_subscription_status := new.status::text; + raise notice 'Source: subscriptions table'; + raise notice ' - Subscription ID: %', new.id; + raise notice ' - Customer ID: %', v_customer_id; + raise notice ' - Status: %', v_subscription_status; + raise notice ' - Cancel at period end: %', new.cancel_at_period_end; + elsif TG_TABLE_NAME = 'subscription_items' then + -- Get customer ID from the subscription + select customer, status::text into v_customer_id, v_subscription_status + from stripe.subscriptions + where id = new.subscription; + raise notice 'Source: subscription_items table'; + raise notice ' - Subscription Item ID: %', new.id; + raise notice ' - Subscription ID: %', new.subscription; + raise notice ' - Customer ID: %', v_customer_id; + raise notice ' - Price ID: %', new.price; + raise notice ' - Period Start: %', to_timestamp(new.current_period_start); + raise notice ' - Period End: %', to_timestamp(new.current_period_end); + else + raise notice 'Unknown table: %, skipping', TG_TABLE_NAME; + return new; + end if; + + -- Skip if no customer_id found + if v_customer_id is null then + raise notice 'SKIP: No customer_id found'; + raise notice '==================== TRIGGER END (SKIPPED) ===================='; + return new; + end if; + + -- Extract user_id from customer metadata + select (metadata->>'user_id')::uuid into v_user_id + from stripe.customers + where id = v_customer_id; + + raise notice 'Customer metadata lookup:'; + raise notice ' - User ID: %', v_user_id; + + -- Skip if no user_id found + if v_user_id is null then + raise notice 'SKIP: No user_id in customer metadata'; + raise notice '==================== TRIGGER END (SKIPPED) ===================='; + return new; + end if; + + -- Get current plan from profile + select plan into v_old_plan + from public.profiles + where id = v_user_id; + + raise notice 'Profile lookup:'; + raise notice ' - Current plan: %', v_old_plan; + + -- Check for trialing subscription with detailed logging + raise notice 'Checking for TRIALING subscription...'; + select exists( + select 1 + from stripe.subscriptions s + inner join stripe.customers c on c.id = s.customer + inner join stripe.subscription_items si on si.subscription = s.id + where (c.metadata->>'user_id')::uuid = v_user_id + and s.status::text = 'trialing' + and si.current_period_end is not null + and to_timestamp(si.current_period_end) > now() + ) into v_has_trialing; + + raise notice ' - Has trialing: %', v_has_trialing; + + -- Check for active/past_due subscription with detailed logging + raise notice 'Checking for ACTIVE/PAST_DUE subscription...'; + select exists( + select 1 + from stripe.subscriptions s + inner join stripe.customers c on c.id = s.customer + inner join stripe.subscription_items si on si.subscription = s.id + where (c.metadata->>'user_id')::uuid = v_user_id + and s.status::text in ('active', 'past_due') + and si.current_period_end is not null + and to_timestamp(si.current_period_end) > now() + ) into v_has_active; + + raise notice ' - Has active/past_due: %', v_has_active; + + -- Show what subscriptions exist for this user + raise notice 'All subscriptions for user %:', v_user_id; + for v_subscription_status, v_period_end in + select + s.status::text, + to_timestamp(si.current_period_end) + from stripe.subscriptions s + inner join stripe.customers c on c.id = s.customer + left join stripe.subscription_items si on si.subscription = s.id + where (c.metadata->>'user_id')::uuid = v_user_id + loop + raise notice ' - Status: %, Period End: %', v_subscription_status, v_period_end; + end loop; + + -- Determine the user's current plan + raise notice 'Calculating new plan...'; + select + case + when exists( + select 1 + from stripe.subscriptions s + inner join stripe.customers c on c.id = s.customer + inner join stripe.subscription_items si on si.subscription = s.id + where (c.metadata->>'user_id')::uuid = v_user_id + and s.status::text = 'trialing' + and si.current_period_end is not null + and to_timestamp(si.current_period_end) > now() + ) then 'trial'::subscription_plan + when exists( + select 1 + from stripe.subscriptions s + inner join stripe.customers c on c.id = s.customer + inner join stripe.subscription_items si on si.subscription = s.id + where (c.metadata->>'user_id')::uuid = v_user_id + and s.status::text in ('active', 'past_due') + and si.current_period_end is not null + and to_timestamp(si.current_period_end) > now() + ) then 'standard'::subscription_plan + else 'none'::subscription_plan + end into v_plan; + + raise notice ' - Calculated plan: %', v_plan; + raise notice ' - Plan change: % → %', v_old_plan, v_plan; + + -- Update the user's profile + if v_old_plan is distinct from v_plan then + raise notice 'UPDATING profile...'; + update public.profiles + set plan = v_plan + where id = v_user_id; + raise notice 'Profile UPDATED successfully'; + else + raise notice 'No plan change needed, skipping update'; + end if; + + raise notice '==================== TRIGGER END (SUCCESS) ===================='; + return new; +end; +$$ language plpgsql security definer; \ No newline at end of file