Spaces:
Sleeping
Sleeping
'use server'; | |
import { sessionUser } from '@/auth'; | |
import prisma from './prisma'; | |
import { | |
ChatWithMessages, | |
MessageAssistantResponse, | |
MessageFilterParams, | |
MessageUserInput, | |
} from '../types'; | |
import { revalidatePath } from 'next/cache'; | |
import { Chat } from '@prisma/client'; | |
import { isValidDate } from '../utils'; | |
async function getUserConnect() { | |
const { id: userId } = await sessionUser(); | |
return userId | |
? { | |
user: { | |
connect: { id: userId }, // Connect the chat to an existing user | |
}, | |
} | |
: {}; | |
} | |
/** | |
* Finds or creates a user in the database based on the provided email and name. | |
* If the user already exists, it returns the existing user. | |
* If the user doesn't exist, it creates a new user and returns it. | |
* | |
* @param email - The email of the user. | |
* @param name - The name of the user. | |
* @returns A promise that resolves to the user object. | |
*/ | |
export async function dbFindOrCreateUser( | |
email: string, | |
name: string, | |
avatar?: string | null, | |
) { | |
// Try to find the user by email | |
const user = await prisma.user.findUnique({ | |
where: { email: email }, | |
}); | |
// If the user doesn't exist, create it | |
if (user) { | |
if (!user.avatar && avatar) { | |
await prisma.user.update({ | |
where: { email: email }, | |
data: { avatar: avatar }, | |
}); | |
} | |
return user; | |
} else { | |
return prisma.user.create({ | |
data: { | |
email: email, | |
name: name, | |
avatar: avatar, | |
}, | |
}); | |
} | |
} | |
/** | |
* Retrieves a user from the database based on the provided ID. | |
* @param id - The ID of the user to retrieve. | |
* @returns A Promise that resolves to the user object if found, or null if not found. | |
*/ | |
export async function dbGetUser(id: string) { | |
// Try to find the user by email | |
return await prisma.user.findUnique({ | |
where: { id }, | |
}); | |
} | |
/** | |
* Retrieves all chat records from the database for the current user. | |
* @returns A promise that resolves to an array of Chat objects. | |
*/ | |
export async function dbGetMyChatList(): Promise<Chat[]> { | |
const { id: userId } = await sessionUser(); | |
if (!userId) return []; | |
return prisma.chat.findMany({ | |
where: { userId }, | |
orderBy: { | |
createdAt: 'desc', | |
}, | |
}); | |
} | |
/** | |
* Retrieves a chat with messages from the database based on the provided ID. | |
* @param id - The ID of the chat to retrieve. | |
* @returns A Promise that resolves to a ChatWithMessages object if found, or null if not found. | |
*/ | |
export async function dbGetChat(id: string): Promise<ChatWithMessages | null> { | |
return prisma.chat.findUnique({ | |
where: { id }, | |
include: { | |
messages: { | |
orderBy: { | |
createdAt: 'asc', | |
}, | |
}, | |
}, | |
}); | |
} | |
/** | |
* Creates a new chat in the database with the provided information. | |
* @param {Object} options - The options for creating the chat. | |
* @param {string} options.id - The ID of the chat (optional). | |
* @param {string} options.title - The title of the chat (optional). | |
* @param {MessageUserInput} options.message - The message to be added to the chat. | |
* @returns {Promise<Chat>} - A promise that resolves to the created chat. | |
*/ | |
export async function dbPostCreateChat({ | |
id, | |
title, | |
mediaUrl, | |
message, | |
}: { | |
id?: string; | |
title?: string; | |
mediaUrl: string; | |
message: MessageUserInput; | |
}) { | |
const userConnect = await getUserConnect(); | |
try { | |
const response = await prisma.chat.create({ | |
data: { | |
id, | |
...userConnect, | |
mediaUrl, | |
title, | |
messages: { | |
create: [{ ...message, ...userConnect }], | |
}, | |
}, | |
include: { | |
messages: true, | |
}, | |
}); | |
revalidatePath('/chat'); | |
return response; | |
} catch (error) { | |
console.error(error); | |
} | |
} | |
/** | |
* Creates a new message in the database for a given chat. | |
* @param chatId - The ID of the chat where the message will be created. | |
* @param message - The message to be created. | |
*/ | |
export async function dbPostCreateMessage( | |
chatId: string, | |
message: MessageUserInput, | |
) { | |
const userConnect = await getUserConnect(); | |
const resp = await prisma.message.create({ | |
data: { | |
...message, | |
...userConnect, | |
chat: { | |
connect: { id: chatId }, | |
}, | |
}, | |
}); | |
revalidatePath('/chat'); | |
return resp; | |
} | |
/** | |
* Updates a message in the database with the provided response. | |
* @param messageId - The ID of the message to update. | |
* @param messageResponse - The response to update the message with. | |
*/ | |
export async function dbPostUpdateMessageResponse( | |
messageId: string, | |
messageResponse: MessageAssistantResponse, | |
shouldRevalidatePath = true, | |
) { | |
await prisma.message.update({ | |
data: { | |
response: messageResponse.response, | |
result: messageResponse.result ?? undefined, | |
responseBody: messageResponse.responseBody, | |
streamDuration: messageResponse.streamDuration, | |
}, | |
where: { | |
id: messageId, | |
}, | |
}); | |
shouldRevalidatePath && revalidatePath('/chat'); | |
} | |
export async function dbDeleteChat(chatId: string) { | |
await prisma.chat.delete({ | |
where: { id: chatId }, | |
}); | |
revalidatePath('/chat'); | |
return; | |
} | |
/** | |
* Retrieves all messages from the database based on a given date. | |
* @param date - The date in the format 'YYYY-MM-DD'. | |
* @returns A promise that resolves to an array of messages. | |
* @throws Error if the provided date is not valid. | |
*/ | |
export async function dbInternalGetAllMessageByDate( | |
messageFilter: MessageFilterParams, | |
) { | |
const { date, includeExamples } = messageFilter; | |
// date must be in the format 'YYYY-MM-DD' | |
if (!isValidDate(date)) { | |
throw Error('Not valid date'); | |
} | |
return prisma.message.findMany({ | |
select: { | |
id: true, | |
chatId: true, | |
prompt: true, | |
mediaUrl: true, | |
result: true, | |
}, | |
where: { | |
createdAt: { | |
gte: new Date(date + 'T00:00:00Z'), | |
lt: new Date(date + 'T23:59:59Z'), | |
}, | |
mediaUrl: includeExamples | |
? undefined | |
: { not: { contains: '/examples/' } }, | |
}, | |
}); | |
} | |