From ddf15184c84013b79cd7e2cff9b70e7fabbcaef1 Mon Sep 17 00:00:00 2001 From: Arnas Donauskas Date: Fri, 29 May 2026 12:21:14 +0200 Subject: [PATCH] fix(migration-014): drop subquery from buttons CHECK (Postgres disallows it) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Postgres rejects CHECK constraints that contain subqueries with SQLSTATE 0A000 — `NOT EXISTS (SELECT 1 FROM jsonb_array_elements(...))` inside CHECK is illegal even though it parses. Move per-element validation entirely to the API layer (the upcoming template-validators in PR 3). The DB CHECK keeps the cheap shape guard: NULL or an array of length <= 10. Per-element validation needs specific error messages anyway ("button #3 has no `text` field") which API-layer validators do much better than a CHECK violation. Co-Authored-By: Claude Opus 4.7 (1M context) --- ...014_message_templates_meta_integration.sql | 21 +++++++------------ 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/supabase/migrations/014_message_templates_meta_integration.sql b/supabase/migrations/014_message_templates_meta_integration.sql index b617697..d183cad 100644 --- a/supabase/migrations/014_message_templates_meta_integration.sql +++ b/supabase/migrations/014_message_templates_meta_integration.sql @@ -123,10 +123,14 @@ END $$; -- New default for fresh inserts. ALTER TABLE message_templates ALTER COLUMN status SET DEFAULT 'DRAFT'; --- 4. buttons shape guard. Permissive at the DB level — strict per-type --- validation (max counts per type, QUICK_REPLY-vs-CTA exclusivity, --- URL example required when {{1}} is present) lives in the API --- validators so error messages can be specific. +-- 4. buttons shape guard. Postgres disallows subqueries in CHECK +-- constraints, so we can only assert the outer shape here (is-array +-- + max length). Per-element type validation (recognised `type` +-- values, max counts per type, QUICK_REPLY-vs-CTA exclusivity, URL +-- example required when {{1}} is present) lives in the API +-- validators in src/lib/whatsapp/template-validators.ts — that's +-- where error messages can be specific to the offending button +-- anyway. DO $$ BEGIN IF NOT EXISTS ( @@ -142,15 +146,6 @@ BEGIN OR ( jsonb_typeof(buttons) = 'array' AND jsonb_array_length(buttons) <= 10 - AND NOT EXISTS ( - SELECT 1 - FROM jsonb_array_elements(buttons) AS b - WHERE jsonb_typeof(b) <> 'object' - OR NOT (b ? 'type') - OR (b->>'type') NOT IN ( - 'QUICK_REPLY', 'URL', 'PHONE_NUMBER', 'COPY_CODE' - ) - ) ) ); END IF;