| const Conversation = require('./schema/convoSchema'); |
| const { getMessages, deleteMessages } = require('./Message'); |
| const logger = require('~/config/winston'); |
|
|
| |
| |
| |
| |
| |
| |
| const getConvo = async (user, conversationId) => { |
| try { |
| return await Conversation.findOne({ user, conversationId }).lean(); |
| } catch (error) { |
| logger.error('[getConvo] Error getting single conversation', error); |
| return { message: 'Error getting single conversation' }; |
| } |
| }; |
|
|
| module.exports = { |
| Conversation, |
| saveConvo: async (user, { conversationId, newConversationId, ...convo }) => { |
| try { |
| const messages = await getMessages({ conversationId }, '_id'); |
| const update = { ...convo, messages, user }; |
| if (newConversationId) { |
| update.conversationId = newConversationId; |
| } |
|
|
| return await Conversation.findOneAndUpdate({ conversationId: conversationId, user }, update, { |
| new: true, |
| upsert: true, |
| }); |
| } catch (error) { |
| logger.error('[saveConvo] Error saving conversation', error); |
| return { message: 'Error saving conversation' }; |
| } |
| }, |
| bulkSaveConvos: async (conversations) => { |
| try { |
| const bulkOps = conversations.map((convo) => ({ |
| updateOne: { |
| filter: { conversationId: convo.conversationId, user: convo.user }, |
| update: convo, |
| upsert: true, |
| timestamps: false, |
| }, |
| })); |
|
|
| const result = await Conversation.bulkWrite(bulkOps); |
| return result; |
| } catch (error) { |
| logger.error('[saveBulkConversations] Error saving conversations in bulk', error); |
| throw new Error('Failed to save conversations in bulk.'); |
| } |
| }, |
| getConvosByPage: async (user, pageNumber = 1, pageSize = 25, isArchived = false) => { |
| const query = { user }; |
| if (isArchived) { |
| query.isArchived = true; |
| } else { |
| query.$or = [{ isArchived: false }, { isArchived: { $exists: false } }]; |
| } |
| try { |
| const totalConvos = (await Conversation.countDocuments(query)) || 1; |
| const totalPages = Math.ceil(totalConvos / pageSize); |
| const convos = await Conversation.find(query) |
| .sort({ updatedAt: -1 }) |
| .skip((pageNumber - 1) * pageSize) |
| .limit(pageSize) |
| .lean(); |
| return { conversations: convos, pages: totalPages, pageNumber, pageSize }; |
| } catch (error) { |
| logger.error('[getConvosByPage] Error getting conversations', error); |
| return { message: 'Error getting conversations' }; |
| } |
| }, |
| getConvosQueried: async (user, convoIds, pageNumber = 1, pageSize = 25) => { |
| try { |
| if (!convoIds || convoIds.length === 0) { |
| return { conversations: [], pages: 1, pageNumber, pageSize }; |
| } |
|
|
| const cache = {}; |
| const convoMap = {}; |
| const promises = []; |
|
|
| convoIds.forEach((convo) => |
| promises.push( |
| Conversation.findOne({ |
| user, |
| conversationId: convo.conversationId, |
| }).lean(), |
| ), |
| ); |
|
|
| const results = (await Promise.all(promises)).filter(Boolean); |
|
|
| results.forEach((convo, i) => { |
| const page = Math.floor(i / pageSize) + 1; |
| if (!cache[page]) { |
| cache[page] = []; |
| } |
| cache[page].push(convo); |
| convoMap[convo.conversationId] = convo; |
| }); |
|
|
| const totalPages = Math.ceil(results.length / pageSize); |
| cache.pages = totalPages; |
| cache.pageSize = pageSize; |
| return { |
| cache, |
| conversations: cache[pageNumber] || [], |
| pages: totalPages || 1, |
| pageNumber, |
| pageSize, |
| convoMap, |
| }; |
| } catch (error) { |
| logger.error('[getConvosQueried] Error getting conversations', error); |
| return { message: 'Error fetching conversations' }; |
| } |
| }, |
| getConvo, |
| |
| getConvoTitle: async (user, conversationId) => { |
| try { |
| const convo = await getConvo(user, conversationId); |
| |
| if (convo && !convo.title) { |
| return null; |
| } else { |
| |
| return convo?.title || 'New Chat'; |
| } |
| } catch (error) { |
| logger.error('[getConvoTitle] Error getting conversation title', error); |
| return { message: 'Error getting conversation title' }; |
| } |
| }, |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| deleteConvos: async (user, filter) => { |
| let toRemove = await Conversation.find({ ...filter, user }).select('conversationId'); |
| const ids = toRemove.map((instance) => instance.conversationId); |
| let deleteCount = await Conversation.deleteMany({ ...filter, user }); |
| deleteCount.messages = await deleteMessages({ conversationId: { $in: ids } }); |
| return deleteCount; |
| }, |
| }; |
|
|