diff --git a/lib/chat/__tests__/setupConversation.test.ts b/lib/chat/__tests__/setupConversation.test.ts index e9e57d9..04dab1f 100644 --- a/lib/chat/__tests__/setupConversation.test.ts +++ b/lib/chat/__tests__/setupConversation.test.ts @@ -21,16 +21,22 @@ vi.mock("@/lib/messages/filterMessageContentForMemories", () => ({ default: vi.fn((msg: unknown) => msg), })); +vi.mock("@/lib/supabase/rooms/selectRoom", () => ({ + default: vi.fn(), +})); + import { generateUUID } from "@/lib/uuid/generateUUID"; import { createNewRoom } from "@/lib/chat/createNewRoom"; import insertMemories from "@/lib/supabase/memories/insertMemories"; import filterMessageContentForMemories from "@/lib/messages/filterMessageContentForMemories"; +import selectRoom from "@/lib/supabase/rooms/selectRoom"; import { setupConversation } from "../setupConversation"; const mockGenerateUUID = vi.mocked(generateUUID); const mockCreateNewRoom = vi.mocked(createNewRoom); const mockInsertMemories = vi.mocked(insertMemories); const mockFilterMessageContentForMemories = vi.mocked(filterMessageContentForMemories); +const mockSelectRoom = vi.mocked(selectRoom); /** * Helper to create a UIMessage for testing. @@ -53,6 +59,8 @@ describe("setupConversation", () => { mockGenerateUUID.mockReturnValue("generated-uuid"); mockCreateNewRoom.mockResolvedValue(undefined); mockInsertMemories.mockResolvedValue(null); + // By default, selectRoom returns an existing room when roomId is provided + mockSelectRoom.mockResolvedValue({ id: "existing-room-id" } as never); }); describe("room creation", () => { @@ -72,7 +80,8 @@ describe("setupConversation", () => { }); }); - it("does NOT create a room when roomId is provided", async () => { + it("does NOT create a room when roomId is provided and room exists", async () => { + mockSelectRoom.mockResolvedValue({ id: "existing-room-id" } as never); const promptMessage = createUIMessage("Hello"); await setupConversation({ @@ -81,9 +90,29 @@ describe("setupConversation", () => { promptMessage, }); + expect(mockSelectRoom).toHaveBeenCalledWith("existing-room-id"); expect(mockCreateNewRoom).not.toHaveBeenCalled(); }); + it("creates a room when roomId is provided but room does NOT exist", async () => { + mockSelectRoom.mockResolvedValue(null); + const promptMessage = createUIMessage("Hello"); + + await setupConversation({ + accountId: "account-123", + roomId: "non-existent-room-id", + promptMessage, + }); + + expect(mockSelectRoom).toHaveBeenCalledWith("non-existent-room-id"); + expect(mockCreateNewRoom).toHaveBeenCalledWith({ + accountId: "account-123", + roomId: "non-existent-room-id", + artistId: undefined, + lastMessage: promptMessage, + }); + }); + it("passes artistId to createNewRoom when provided", async () => { const promptMessage = createUIMessage("Hello"); diff --git a/lib/chat/setupConversation.ts b/lib/chat/setupConversation.ts index 4814562..1894bb3 100644 --- a/lib/chat/setupConversation.ts +++ b/lib/chat/setupConversation.ts @@ -2,6 +2,7 @@ import { UIMessage } from "ai"; import { generateUUID } from "@/lib/uuid/generateUUID"; import { createNewRoom } from "@/lib/chat/createNewRoom"; import insertMemories from "@/lib/supabase/memories/insertMemories"; +import selectRoom from "@/lib/supabase/rooms/selectRoom"; import filterMessageContentForMemories from "@/lib/messages/filterMessageContentForMemories"; interface SetupConversationParams { @@ -44,8 +45,18 @@ export async function setupConversation({ const finalRoomId = roomId || generateUUID(); const finalMemoryId = memoryId || generateUUID(); - // Create room if roomId was not provided - if (!roomId) { + // Create room if needed: + // - If no roomId was provided, create a new room + // - If roomId was provided but doesn't exist, create it (prevents FK constraint errors) + let shouldCreateRoom = !roomId; + if (roomId) { + const existingRoom = await selectRoom(roomId); + if (!existingRoom) { + shouldCreateRoom = true; + } + } + + if (shouldCreateRoom) { await createNewRoom({ accountId, roomId: finalRoomId,