diff --git a/lib/supabase/persistence.ts b/lib/supabase/persistence.ts index 31244d6f..898c6d05 100644 --- a/lib/supabase/persistence.ts +++ b/lib/supabase/persistence.ts @@ -1,31 +1,50 @@ 'use server' import { getSupabaseServerClient } from '@/lib/supabase/client' +import { getSupabaseServiceRoleClient } from './service-role' import { type Chat, type AIMessage } from '@/lib/types' import { PostgrestError } from '@supabase/supabase-js' export async function saveChat(chat: Chat, userId: string): Promise<{ data: string | null; error: PostgrestError | null }> { - const supabase = getSupabaseServerClient() + const supabase = getSupabaseServiceRoleClient() + + // Insert into chats table + const { data: chatData, error: chatError } = await supabase + .from('chats') + .insert({ + id: chat.id, + user_id: userId, + title: chat.title, + }) + .select('id') + .single() + + if (chatError) { + console.error('Error saving chat:', chatError) + return { data: null, error: chatError } + } + const messagesToInsert = chat.messages.map(message => ({ id: message.id, + chat_id: chat.id, + user_id: userId, role: message.role, content: typeof message.content === 'string' ? message.content : JSON.stringify(message.content), - createdAt: message.createdAt ? new Date(message.createdAt).toISOString() : new Date().toISOString(), + created_at: message.createdAt ? new Date(message.createdAt).toISOString() : new Date().toISOString(), })) - const { data, error } = await supabase.rpc('save_chat_with_messages', { - chat_id: chat.id, - user_id: userId, - title: chat.title, - messages: messagesToInsert, - }) + const { error: messagesError } = await supabase + .from('messages') + .insert(messagesToInsert) - if (error) { - console.error('Error saving chat with messages:', error) - return { data: null, error } + if (messagesError) { + console.error('Error saving messages:', messagesError) + // Attempt to delete the chat if messages fail to save + await supabase.from('chats').delete().eq('id', chat.id) + return { data: null, error: messagesError } } - return { data: data as string, error: null } + return { data: chatData.id, error: null } } export async function getMessagesByChatId(chatId: string): Promise<{ data: any[] | null; error: PostgrestError | null }> { diff --git a/lib/supabase/service-role.ts b/lib/supabase/service-role.ts new file mode 100644 index 00000000..e9f9f77d --- /dev/null +++ b/lib/supabase/service-role.ts @@ -0,0 +1,27 @@ +import { createServerClient, type CookieOptions } from '@supabase/ssr' +import { cookies } from 'next/headers' + +export function getSupabaseServiceRoleClient() { + const cookieStore = cookies() + + return createServerClient( + process.env.NEXT_PUBLIC_SUPABASE_URL!, + process.env.SUPABASE_SERVICE_ROLE_KEY!, + { + cookies: { + async get(name: string) { + const store = await cookieStore + return store.get(name)?.value + }, + async set(name: string, value: string, options: CookieOptions) { + const store = await cookieStore + store.set({ name, value, ...options }) + }, + async remove(name: string, options: CookieOptions) { + const store = await cookieStore + store.set({ name, value: '', ...options }) + }, + }, + } + ) +}