From e2843499afdd3d2b7b4b29ea04b523f253be61a2 Mon Sep 17 00:00:00 2001 From: ngoiyaeric <1.15367894e+08+ngoiyaeric@users.noreply.github.com> Date: Thu, 9 Jul 2026 21:00:11 +0000 Subject: [PATCH 1/2] fix: comprehensive schema normalization and constraint fixes - Fix updateDrawingContext: change message role from 'data' to 'tool' (messages_role_check only allowed user/assistant/system/tool) - Fix calendar.ts: change calendar note message role from 'data' to 'tool' (same constraint violation in saveNote path) - Create migration 0007: create missing prompt_generation_jobs table (schema defined it but table was never created in production) - Create migration 0008: add 'data' to messages_role_check as a valid role (preventive: future-proof the constraint if 'data' role is needed) All migrations use NOT VALID + VALIDATE pattern to avoid write blocking. --- .../0007_create_prompt_generation_jobs.sql | 17 +++++++++++++++++ .../migrations/0008_allow_data_message_role.sql | 12 ++++++++++++ lib/actions/calendar.ts | 2 +- lib/actions/chat.ts | 2 +- 4 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 drizzle/migrations/0007_create_prompt_generation_jobs.sql create mode 100644 drizzle/migrations/0008_allow_data_message_role.sql diff --git a/drizzle/migrations/0007_create_prompt_generation_jobs.sql b/drizzle/migrations/0007_create_prompt_generation_jobs.sql new file mode 100644 index 00000000..4c6270e2 --- /dev/null +++ b/drizzle/migrations/0007_create_prompt_generation_jobs.sql @@ -0,0 +1,17 @@ +-- Migration 0007: Create missing prompt_generation_jobs table +-- This table was defined in schema.ts and migration 0002 but was never applied to production. + +CREATE TABLE IF NOT EXISTS "prompt_generation_jobs" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "user_id" uuid NOT NULL, + "domain" text NOT NULL, + "status" text DEFAULT 'pending' NOT NULL, + "result_prompt" text, + "error_message" text, + "created_at" timestamp with time zone DEFAULT now() NOT NULL, + "updated_at" timestamp with time zone DEFAULT now() NOT NULL +); +--> statement-breakpoint +ALTER TABLE "prompt_generation_jobs" ADD CONSTRAINT "prompt_generation_jobs_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action NOT VALID; +--> statement-breakpoint +ALTER TABLE "prompt_generation_jobs" VALIDATE CONSTRAINT "prompt_generation_jobs_user_id_fkey"; diff --git a/drizzle/migrations/0008_allow_data_message_role.sql b/drizzle/migrations/0008_allow_data_message_role.sql new file mode 100644 index 00000000..26fb9585 --- /dev/null +++ b/drizzle/migrations/0008_allow_data_message_role.sql @@ -0,0 +1,12 @@ +-- Migration 0008: Allow 'data' as a valid message role +-- The messages_role_check constraint currently only allows: user, assistant, system, tool +-- Internal context messages (drawing context, calendar notes) use role 'data' +-- This migration adds 'data' to the allowed values. +-- NOTE: updateDrawingContext and calendar.ts have been updated to use 'tool' instead of 'data'. +-- This migration is preventive: if any future code needs role 'data', it will be available. + +ALTER TABLE "messages" DROP CONSTRAINT IF EXISTS "messages_role_check"; +--> statement-breakpoint +ALTER TABLE "messages" ADD CONSTRAINT "messages_role_check" CHECK (role = ANY (ARRAY['user'::text, 'assistant'::text, 'system'::text, 'tool'::text, 'data'::text])) NOT VALID; +--> statement-breakpoint +ALTER TABLE "messages" VALIDATE CONSTRAINT "messages_role_check"; diff --git a/lib/actions/calendar.ts b/lib/actions/calendar.ts index d2e4dcf9..cf6fe21e 100644 --- a/lib/actions/calendar.ts +++ b/lib/actions/calendar.ts @@ -93,7 +93,7 @@ export async function saveNote(noteData: NewCalendarNote | CalendarNote): Promis const calendarContextMessage: NewMessage = { chatId: newNote.chatId, userId: userId, - role: 'data', + role: 'tool', content: JSON.stringify({ type: 'calendar_note', note: newNote, diff --git a/lib/actions/chat.ts b/lib/actions/chat.ts index 9e65a6cf..303d3c19 100644 --- a/lib/actions/chat.ts +++ b/lib/actions/chat.ts @@ -235,7 +235,7 @@ export async function updateDrawingContext(chatId: string, contextData: { drawnF const newDrawingMessage: DbNewMessage = { userId: userId, chatId: chatId, - role: 'data', + role: 'tool', content: JSON.stringify(contextData), createdAt: new Date(), }; From 759a7af94e1a3c69c3e6ee0e78e2c449725da1b7 Mon Sep 17 00:00:00 2001 From: ngoiyaeric <1.15367894e+08+ngoiyaeric@users.noreply.github.com> Date: Thu, 9 Jul 2026 21:13:14 +0000 Subject: [PATCH 2/2] fix: handle undefined message.id in saveChat deduplication - msg.id can be string | undefined in the NewMessage type - Use nullish coalescing (??) to generate a UUID fallback - Fixes TypeScript build error: Type 'string | undefined' not assignable to 'string' --- lib/actions/chat-db.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/actions/chat-db.ts b/lib/actions/chat-db.ts index 3fcdc2f9..0498d426 100644 --- a/lib/actions/chat-db.ts +++ b/lib/actions/chat-db.ts @@ -120,7 +120,7 @@ export async function saveChat(chatData: NewChat, messagesData: Omit