"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ChatRepository = void 0; const typeorm_1 = require("typeorm"); const ormconfig_1 = require("../ormconfig"); const ChatAggregate_1 = require("../../Domain/Chat/ChatAggregate"); const ChatArchiveAggregate_1 = require("../../Domain/Chat/ChatArchiveAggregate"); const Logger_1 = require("../../Application/Services/Logger"); class ChatRepository { constructor() { this.repo = ormconfig_1.AppDataSource.getRepository(ChatAggregate_1.ChatAggregate); this.archiveRepo = ormconfig_1.AppDataSource.getRepository(ChatArchiveAggregate_1.ChatArchiveAggregate); } async create(chat) { const startTime = Date.now(); try { const result = await this.repo.save(chat); (0, Logger_1.logDatabase)('Chat created successfully', undefined, Date.now() - startTime, { chatId: result.id, type: result.type, participants: result.users?.length || 0 }); return result; } catch (error) { (0, Logger_1.logError)('ChatRepository.create error', error); throw new Error('Failed to create chat in database'); } } async findByPage(from, to) { const startTime = Date.now(); try { const skip = from; const take = to - from + 1; const [chats, totalCount] = await this.repo.findAndCount({ where: { state: (0, typeorm_1.Not)(ChatAggregate_1.ChatState.SOFT_DELETE) }, order: { createDate: 'DESC' }, skip, take }); (0, Logger_1.logDatabase)('Chats page retrieved successfully', undefined, Date.now() - startTime, { from, to, returned: chats.length, totalCount }); return { chats, totalCount }; } catch (error) { (0, Logger_1.logError)('ChatRepository.findByPage error', error); throw new Error('Failed to retrieve chats page from database'); } } async findByPageIncludingDeleted(from, to) { const startTime = Date.now(); try { const skip = from; const take = to - from + 1; const [chats, totalCount] = await this.repo.findAndCount({ order: { createDate: 'DESC' }, skip, take }); (0, Logger_1.logDatabase)('Chats page retrieved successfully (including deleted)', undefined, Date.now() - startTime, { from, to, returned: chats.length, totalCount }); return { chats, totalCount }; } catch (error) { (0, Logger_1.logError)('ChatRepository.findByPageIncludingDeleted error', error); throw new Error('Failed to retrieve chats page from database'); } } async findById(id) { const startTime = Date.now(); try { const result = await this.repo.findOne({ where: { id, state: (0, typeorm_1.Not)(ChatAggregate_1.ChatState.SOFT_DELETE) } }); (0, Logger_1.logDatabase)('Chat findById query completed', undefined, Date.now() - startTime, { found: !!result, chatId: id }); return result; } catch (error) { (0, Logger_1.logError)('ChatRepository.findById error', error); throw new Error('Failed to retrieve chat from database'); } } async findByIdIncludingDeleted(id) { const startTime = Date.now(); try { const result = await this.repo.findOneBy({ id }); (0, Logger_1.logDatabase)('Chat findByIdIncludingDeleted query completed', undefined, Date.now() - startTime, { found: !!result, chatId: id }); return result; } catch (error) { (0, Logger_1.logError)('ChatRepository.findByIdIncludingDeleted error', error); throw new Error('Failed to retrieve chat from database'); } } async findByUserId(userId) { const startTime = Date.now(); try { const result = await this.repo .createQueryBuilder('chat') .where(':userId = ANY(chat.users)', { userId }) .andWhere('chat.state != :softDelete', { softDelete: ChatAggregate_1.ChatState.SOFT_DELETE }) .getMany(); (0, Logger_1.logDatabase)('Chats retrieved by user id', `findByUserId(${userId})`, Date.now() - startTime, { userId, count: result.length }); return result; } catch (error) { (0, Logger_1.logError)('ChatRepository.findByUserId error', error); throw new Error('Failed to find chats by user id'); } } async findByUserIdIncludingDeleted(userId) { const startTime = Date.now(); try { const result = await this.repo .createQueryBuilder('chat') .where(':userId = ANY(chat.users)', { userId }) .getMany(); (0, Logger_1.logDatabase)('Chats retrieved by user id (including deleted)', `findByUserIdIncludingDeleted(${userId})`, Date.now() - startTime, { userId, count: result.length }); return result; } catch (error) { (0, Logger_1.logError)('ChatRepository.findByUserIdIncludingDeleted error', error); throw new Error('Failed to find all chats by user id'); } } async findByGameId(gameId) { const startTime = Date.now(); try { const result = await this.repo.findOneBy({ gameId, type: ChatAggregate_1.ChatType.GAME, state: ChatAggregate_1.ChatState.ACTIVE }); (0, Logger_1.logDatabase)('Chat retrieved by game id', `findByGameId(${gameId})`, Date.now() - startTime, { gameId, found: !!result }); return result; } catch (error) { (0, Logger_1.logError)('ChatRepository.findByGameId error', error); throw new Error('Failed to find chat by game id'); } } async findActiveChatsForUser(userId) { const startTime = Date.now(); try { const result = await this.repo .createQueryBuilder('chat') .where(':userId = ANY(chat.users)', { userId }) .andWhere('chat.state = :state', { state: ChatAggregate_1.ChatState.ACTIVE }) .orderBy('chat.lastActivity', 'DESC') .getMany(); (0, Logger_1.logDatabase)('Active chats retrieved for user', `findActiveChatsForUser(${userId})`, Date.now() - startTime, { userId, count: result.length }); return result; } catch (error) { (0, Logger_1.logError)('ChatRepository.findActiveChatsForUser error', error); throw new Error('Failed to find active chats for user'); } } async findInactiveChats(inactivityMinutes) { const startTime = Date.now(); try { const cutoffDate = new Date(Date.now() - inactivityMinutes * 60 * 1000); const result = await this.repo .createQueryBuilder('chat') .where('chat.state = :state', { state: ChatAggregate_1.ChatState.ACTIVE }) .andWhere('(chat.lastActivity < :cutoffDate OR chat.lastActivity IS NULL)', { cutoffDate }) .getMany(); (0, Logger_1.logDatabase)('Inactive chats retrieved', `findInactiveChats(${inactivityMinutes}min)`, Date.now() - startTime, { inactivityMinutes, count: result.length, cutoffDate }); return result; } catch (error) { (0, Logger_1.logError)('ChatRepository.findInactiveChats error', error); throw new Error('Failed to find inactive chats'); } } async update(id, update) { const startTime = Date.now(); try { await this.repo.update(id, update); const result = await this.findById(id); (0, Logger_1.logDatabase)('Chat updated successfully', `update(${id})`, Date.now() - startTime, { chatId: id, updatedFields: Object.keys(update), success: !!result }); return result; } catch (error) { (0, Logger_1.logError)('ChatRepository.update error', error); throw new Error('Failed to update chat in database'); } } async delete(id) { const startTime = Date.now(); try { const result = await this.repo.delete(id); (0, Logger_1.logDatabase)('Chat deleted', `delete(${id})`, Date.now() - startTime, { chatId: id, affected: result.affected }); return result; } catch (error) { (0, Logger_1.logError)('ChatRepository.delete error', error); throw new Error('Failed to delete chat'); } } async softDelete(id) { const startTime = Date.now(); try { await this.repo.update(id, { state: ChatAggregate_1.ChatState.SOFT_DELETE }); const result = await this.findById(id); (0, Logger_1.logDatabase)('Chat soft deleted', `softDelete(${id})`, Date.now() - startTime, { chatId: id, success: !!result }); return result; } catch (error) { (0, Logger_1.logError)('ChatRepository.softDelete error', error); throw new Error('Failed to soft delete chat'); } } async archiveChat(chat) { const startTime = Date.now(); try { const archive = new ChatArchiveAggregate_1.ChatArchiveAggregate(); archive.chatId = chat.id; archive.archivedMessages = chat.messages; archive.archivedAt = new Date(); archive.chatType = chat.type; archive.chatName = chat.name; archive.gameId = chat.gameId; archive.participants = chat.users; const archivedResult = await this.archiveRepo.save(archive); await this.repo.update(chat.id, { state: ChatAggregate_1.ChatState.ARCHIVE, messages: [], archiveDate: new Date() }); (0, Logger_1.logDatabase)('Chat archived successfully', `archiveChat(${chat.id})`, Date.now() - startTime, { chatId: chat.id, messageCount: chat.messages.length, archiveId: archivedResult.id }); return archivedResult; } catch (error) { (0, Logger_1.logError)('ChatRepository.archiveChat error', error); throw new Error('Failed to archive chat'); } } async getArchivedChat(chatId) { const startTime = Date.now(); try { const result = await this.archiveRepo.findOneBy({ chatId }); (0, Logger_1.logDatabase)('Archived chat retrieved', `getArchivedChat(${chatId})`, Date.now() - startTime, { chatId, found: !!result }); return result; } catch (error) { (0, Logger_1.logError)('ChatRepository.getArchivedChat error', error); throw new Error('Failed to retrieve archived chat'); } } async restoreFromArchive(chatId) { const startTime = Date.now(); try { const archive = await this.archiveRepo.findOneBy({ chatId }); if (!archive) { return null; } // Game chats cannot be restored, only viewed if (archive.chatType === ChatAggregate_1.ChatType.GAME) { (0, Logger_1.logDatabase)('Game chat restore attempt blocked', `restoreFromArchive(${chatId})`, Date.now() - startTime, { chatId, chatType: archive.chatType, blocked: true }); return null; } // Restore messages to the chat await this.repo.update(chatId, { state: ChatAggregate_1.ChatState.ACTIVE, messages: archive.archivedMessages, lastActivity: new Date(), archiveDate: null }); const result = await this.findById(chatId); (0, Logger_1.logDatabase)('Chat restored from archive', `restoreFromArchive(${chatId})`, Date.now() - startTime, { chatId, messageCount: archive.archivedMessages.length, success: !!result }); return result; } catch (error) { (0, Logger_1.logError)('ChatRepository.restoreFromArchive error', error); throw new Error('Failed to restore chat from archive'); } } } exports.ChatRepository = ChatRepository; //# sourceMappingURL=ChatRepository.js.map