From 38278c93c3611982cb7559764620267a0636cd86 Mon Sep 17 00:00:00 2001 From: sepehr Date: Sun, 26 Apr 2026 22:02:04 +0200 Subject: [PATCH] fix: make migration fully idempotent with DO blocks for all ALTER statements The ADD CONSTRAINT for Note.notebookId was not wrapped in an exception handler, causing P3009 on production when the constraint already existed. Co-Authored-By: Claude Opus 4.7 --- .../migration.sql | 34 +++++++++++-------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/memento-note/prisma/migrations/20260426150000_add_missing_settings_and_fix_constraints/migration.sql b/memento-note/prisma/migrations/20260426150000_add_missing_settings_and_fix_constraints/migration.sql index 9525249..bc7925b 100644 --- a/memento-note/prisma/migrations/20260426150000_add_missing_settings_and_fix_constraints/migration.sql +++ b/memento-note/prisma/migrations/20260426150000_add_missing_settings_and_fix_constraints/migration.sql @@ -1,15 +1,21 @@ -- AlterTable: UserAISettings -- Add missing columns: autoLabeling, languageDetection -ALTER TABLE "UserAISettings" ADD COLUMN IF NOT EXISTS "autoLabeling" BOOLEAN NOT NULL DEFAULT true; -ALTER TABLE "UserAISettings" ADD COLUMN IF NOT EXISTS "languageDetection" BOOLEAN NOT NULL DEFAULT true; +DO $$ BEGIN + ALTER TABLE "UserAISettings" ADD COLUMN "autoLabeling" BOOLEAN NOT NULL DEFAULT true; +EXCEPTION WHEN duplicate_column THEN NULL; +END $$; --- Add missing indexes +DO $$ BEGIN + ALTER TABLE "UserAISettings" ADD COLUMN "languageDetection" BOOLEAN NOT NULL DEFAULT true; +EXCEPTION WHEN duplicate_column THEN NULL; +END $$; + +-- Add missing indexes (idempotent) CREATE INDEX IF NOT EXISTS "UserAISettings_memoryEcho_idx" ON "UserAISettings"("memoryEcho"); CREATE INDEX IF NOT EXISTS "UserAISettings_aiProvider_idx" ON "UserAISettings"("aiProvider"); CREATE INDEX IF NOT EXISTS "UserAISettings_memoryEchoFrequency_idx" ON "UserAISettings"("memoryEchoFrequency"); CREATE INDEX IF NOT EXISTS "UserAISettings_preferredLanguage_idx" ON "UserAISettings"("preferredLanguage"); --- Add missing Note indexes CREATE INDEX IF NOT EXISTS "Note_isPinned_idx" ON "Note"("isPinned"); CREATE INDEX IF NOT EXISTS "Note_isArchived_idx" ON "Note"("isArchived"); CREATE INDEX IF NOT EXISTS "Note_order_idx" ON "Note"("order"); @@ -17,44 +23,42 @@ CREATE INDEX IF NOT EXISTS "Note_reminder_idx" ON "Note"("reminder"); CREATE INDEX IF NOT EXISTS "Note_userId_idx" ON "Note"("userId"); CREATE INDEX IF NOT EXISTS "Note_userId_notebookId_idx" ON "Note"("userId", "notebookId"); --- Add missing Label indexes CREATE INDEX IF NOT EXISTS "Label_notebookId_idx" ON "Label"("notebookId"); CREATE INDEX IF NOT EXISTS "Label_userId_idx" ON "Label"("userId"); --- Add missing Notebook indexes CREATE INDEX IF NOT EXISTS "Notebook_userId_order_idx" ON "Notebook"("userId", "order"); CREATE INDEX IF NOT EXISTS "Notebook_userId_idx" ON "Notebook"("userId"); --- Add missing AiFeedback indexes CREATE INDEX IF NOT EXISTS "AiFeedback_noteId_idx" ON "AiFeedback"("noteId"); CREATE INDEX IF NOT EXISTS "AiFeedback_userId_idx" ON "AiFeedback"("userId"); CREATE INDEX IF NOT EXISTS "AiFeedback_feature_idx" ON "AiFeedback"("feature"); --- Add missing MemoryEchoInsight indexes and unique constraint CREATE INDEX IF NOT EXISTS "MemoryEchoInsight_userId_insightDate_idx" ON "MemoryEchoInsight"("userId", "insightDate"); CREATE INDEX IF NOT EXISTS "MemoryEchoInsight_userId_dismissed_idx" ON "MemoryEchoInsight"("userId", "dismissed"); +CREATE INDEX IF NOT EXISTS "NoteShare_userId_idx" ON "NoteShare"("userId"); +CREATE INDEX IF NOT EXISTS "NoteShare_status_idx" ON "NoteShare"("status"); +CREATE INDEX IF NOT EXISTS "NoteShare_sharedBy_idx" ON "NoteShare"("sharedBy"); + -- Add unique constraint for MemoryEchoInsight (idempotent) DO $$ BEGIN ALTER TABLE "MemoryEchoInsight" ADD CONSTRAINT "MemoryEchoInsight_userId_insightDate_key" UNIQUE ("userId", "insightDate"); EXCEPTION WHEN duplicate_object THEN NULL; END $$; --- Add missing NoteShare indexes -CREATE INDEX IF NOT EXISTS "NoteShare_userId_idx" ON "NoteShare"("userId"); -CREATE INDEX IF NOT EXISTS "NoteShare_status_idx" ON "NoteShare"("status"); -CREATE INDEX IF NOT EXISTS "NoteShare_sharedBy_idx" ON "NoteShare"("sharedBy"); - -- Add unique constraint for NoteShare (idempotent) DO $$ BEGIN ALTER TABLE "NoteShare" ADD CONSTRAINT "NoteShare_noteId_userId_key" UNIQUE ("noteId", "userId"); EXCEPTION WHEN duplicate_object THEN NULL; END $$; --- Fix Note.notebookId foreign key to use ON DELETE SET NULL +-- Fix Note.notebookId foreign key to use ON DELETE SET NULL (idempotent) DO $$ BEGIN ALTER TABLE "Note" DROP CONSTRAINT "Note_notebookId_fkey"; EXCEPTION WHEN undefined_object THEN NULL; END $$; -ALTER TABLE "Note" ADD CONSTRAINT "Note_notebookId_fkey" FOREIGN KEY ("notebookId") REFERENCES "Notebook"("id") ON DELETE SET NULL ON UPDATE CASCADE; +DO $$ BEGIN + ALTER TABLE "Note" ADD CONSTRAINT "Note_notebookId_fkey" FOREIGN KEY ("notebookId") REFERENCES "Notebook"("id") ON DELETE SET NULL ON UPDATE CASCADE; +EXCEPTION WHEN duplicate_object THEN NULL; +END $$;