'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 { 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 { 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} - 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/' } }, }, }); }