From ae002692fd5fc46307fbc43b772ed0675e2a36ed Mon Sep 17 00:00:00 2001 From: Felipe Truman Date: Tue, 16 Jun 2026 14:17:57 -0300 Subject: [PATCH] fix(db): unique index parcial em inbox_messages.whatsapp_message_id MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Companion no nível do banco da guard app-level (#58). O índice do baseline era não-unique (só performance), permitindo duplicatas em retries do Meta. Troca por UNIQUE INDEX parcial (WHERE whatsapp_message_id IS NOT NULL), garantindo dedup no DB mesmo se a guard app-level falhar. Inclui nota de deduplicação prévia para bases já em uso (UNIQUE falha se houver duplicatas existentes). --- ...616000001_unique_inbox_whatsapp_msg_id.sql | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 supabase/migrations/20260616000001_unique_inbox_whatsapp_msg_id.sql diff --git a/supabase/migrations/20260616000001_unique_inbox_whatsapp_msg_id.sql b/supabase/migrations/20260616000001_unique_inbox_whatsapp_msg_id.sql new file mode 100644 index 00000000..de541ea8 --- /dev/null +++ b/supabase/migrations/20260616000001_unique_inbox_whatsapp_msg_id.sql @@ -0,0 +1,24 @@ +-- Dedup de mensagens inbound no nível do banco (companion da guard app-level em +-- lib/inbox/inbox-webhook.ts handleInboundMessage). +-- +-- O Meta reenvia o webhook (retry) com o mesmo whatsapp_message_id. O índice do +-- baseline era apenas para performance (não-unique), então duplicatas conseguiam +-- ser inseridas. Esta migration troca por um UNIQUE INDEX parcial, garantindo no +-- DB que o mesmo whatsapp_message_id não seja persistido duas vezes. +-- +-- Pré-requisito: não pode haver duplicatas existentes (a criação do UNIQUE INDEX +-- falha se houver). Em instalações novas a tabela está vazia. Para bases já em uso, +-- deduplicar antes, por exemplo: +-- DELETE FROM public.inbox_messages WHERE id IN ( +-- SELECT id FROM ( +-- SELECT id, row_number() OVER ( +-- PARTITION BY whatsapp_message_id ORDER BY created_at ASC, id ASC +-- ) AS rn FROM public.inbox_messages WHERE whatsapp_message_id IS NOT NULL +-- ) t WHERE rn > 1 +-- ); + +DROP INDEX IF EXISTS public.idx_inbox_messages_whatsapp_msg_id; + +CREATE UNIQUE INDEX IF NOT EXISTS ux_inbox_messages_whatsapp_msg_id + ON public.inbox_messages (whatsapp_message_id) + WHERE whatsapp_message_id IS NOT NULL;