import { SendMessageCommand } from './ChatCommands'; import { IChatRepository } from '../../../Domain/IRepository/IChatRepository'; import { Message } from '../../../Domain/Chat/ChatAggregate'; import { logAuth, logError } from '../../Services/Logger'; import { v4 as uuidv4 } from 'uuid'; export class SendMessageCommandHandler { constructor(private chatRepository: IChatRepository) {} async execute(command: SendMessageCommand): Promise { try { // Validate message is non-empty string if (typeof command.message !== 'string' || !command.message.trim()) { throw new Error('Message must be a non-empty string'); } const chat = await this.chatRepository.findById(command.chatId); if (!chat) { throw new Error('Chat not found'); } // Check if user is member of this chat if (!chat.users.includes(command.userId)) { throw new Error('User is not a member of this chat'); } // Create message const message: Message = { id: uuidv4(), date: new Date(), userid: command.userId, text: command.message.trim() }; // Manage message history (keep last 10 per user, up to 2 weeks) let updatedMessages = [...chat.messages, message]; updatedMessages = this.pruneMessages(updatedMessages); // Update chat await this.chatRepository.update(command.chatId, { messages: updatedMessages, lastActivity: new Date() }); logAuth('Message sent successfully', command.userId, { chatId: command.chatId, messageLength: command.message.length, totalMessages: updatedMessages.length }); return message; } catch (error) { logError('SendMessageCommandHandler error', error as Error); return null; } } private pruneMessages(messages: Message[]): Message[] { const twoWeeksAgo = new Date(Date.now() - 14 * 24 * 60 * 60 * 1000); // Remove messages older than 2 weeks let prunedMessages = messages.filter(msg => new Date(msg.date) > twoWeeksAgo); // Group by user and keep last 10 messages per user const messagesByUser = new Map(); prunedMessages.forEach(msg => { if (!messagesByUser.has(msg.userid)) { messagesByUser.set(msg.userid, []); } messagesByUser.get(msg.userid)!.push(msg); }); // Keep only last 10 messages per user const finalMessages: Message[] = []; messagesByUser.forEach((userMessages, userId) => { const last10 = userMessages.slice(-10); finalMessages.push(...last10); }); // Sort by date return finalMessages.sort((a, b) => new Date(a.date).getTime() - new Date(b.date).getTime()); } }