From 79c60eeaeaf1095586d56107b9e7c7ae2e532d47 Mon Sep 17 00:00:00 2001 From: Arnas Donauskas Date: Mon, 22 Jun 2026 09:46:48 +0300 Subject: [PATCH] fix(migrations): make 017 RLS rewrite re-runnable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 017 claimed to be idempotent but only dropped the *legacy* policy names before recreating; the new policies (contacts_select, …) were created unguarded. A second run therefore failed with `42710: policy "contacts_select" for table "contacts" already exists`. Drop every policy on the tables 017 manages (it owns all RLS on them — no later migration adds others) in a DO block before the CREATEs, so the rewrite re-establishes the full set on every run. Co-Authored-By: Claude Opus 4.8 --- supabase/migrations/017_account_sharing.sql | 29 +++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/supabase/migrations/017_account_sharing.sql b/supabase/migrations/017_account_sharing.sql index abb7ad6..fae7cf3 100644 --- a/supabase/migrations/017_account_sharing.sql +++ b/supabase/migrations/017_account_sharing.sql @@ -352,6 +352,35 @@ CREATE UNIQUE INDEX IF NOT EXISTS idx_one_active_run_per_contact -- assignment + audit) but is no longer consulted for isolation. -- ============================================================ +-- Make the RLS rewrite re-runnable. CREATE POLICY has no IF NOT EXISTS +-- form, and the DROP statements below only name the *legacy* policies — +-- the new ones (contacts_select, …) would error with 42710 "policy +-- already exists" on a second run. 017 owns every policy on these tables +-- (no later migration adds others), so drop them all first, then the +-- CREATEs below re-establish the full set. +DO $$ +DECLARE + pol RECORD; +BEGIN + FOR pol IN + SELECT policyname, tablename + FROM pg_policies + WHERE schemaname = 'public' + AND tablename = ANY (ARRAY[ + 'contacts', 'tags', 'custom_fields', 'contact_notes', + 'conversations', 'whatsapp_config', 'message_templates', + 'pipelines', 'deals', 'broadcasts', 'automations', + 'automation_logs', 'flows', 'flow_runs', 'contact_tags', + 'contact_custom_values', 'messages', 'pipeline_stages', + 'broadcast_recipients', 'automation_steps', 'flow_nodes', + 'flow_run_events', 'message_reactions', 'profiles', + 'accounts', 'account_invitations' + ]) + LOOP + EXECUTE format('DROP POLICY IF EXISTS %I ON public.%I', pol.policyname, pol.tablename); + END LOOP; +END $$; + -- ---- contacts --------------------------------------------------- DROP POLICY IF EXISTS "Users can manage own contacts" ON contacts; CREATE POLICY contacts_select ON contacts FOR SELECT USING (is_account_member(account_id));