/** * Application Use Case: MarkNotificationReadUseCase * * Marks a notification as read. */ import type { AsyncUseCase , Logger } from '@core/shared/application'; import type { INotificationRepository } from '../../domain/repositories/INotificationRepository'; import { NotificationDomainError } from '../../domain/errors/NotificationDomainError'; export interface MarkNotificationReadCommand { notificationId: string; recipientId: string; // For validation } export class MarkNotificationReadUseCase implements AsyncUseCase { constructor( private readonly notificationRepository: INotificationRepository, private readonly logger: Logger, ) {} async execute(command: MarkNotificationReadCommand): Promise { this.logger.debug(`Attempting to mark notification ${command.notificationId} as read for recipient ${command.recipientId}`); try { const notification = await this.notificationRepository.findById(command.notificationId); if (!notification) { this.logger.warn(`Notification not found for ID: ${command.notificationId}`); throw new NotificationDomainError('Notification not found'); } if (notification.recipientId !== command.recipientId) { this.logger.warn(`Unauthorized attempt to mark notification ${command.notificationId}. Recipient ID mismatch.`); throw new NotificationDomainError('Cannot mark another user\'s notification as read'); } if (!notification.isUnread()) { this.logger.info(`Notification ${command.notificationId} is already read. Skipping update.`); return; // Already read, nothing to do } const updatedNotification = notification.markAsRead(); await this.notificationRepository.update(updatedNotification); this.logger.info(`Notification ${command.notificationId} successfully marked as read.`); } catch (error) { this.logger.error(`Failed to mark notification ${command.notificationId} as read: ${error instanceof Error ? error.message : String(error)}`); throw error; } } } /** * Application Use Case: MarkAllNotificationsReadUseCase * * Marks all notifications as read for a recipient. */ export class MarkAllNotificationsReadUseCase implements AsyncUseCase { constructor( private readonly notificationRepository: INotificationRepository, ) {} async execute(recipientId: string): Promise { await this.notificationRepository.markAllAsReadByRecipientId(recipientId); } } /** * Application Use Case: DismissNotificationUseCase * * Dismisses a notification. */ export interface DismissNotificationCommand { notificationId: string; recipientId: string; } export class DismissNotificationUseCase implements AsyncUseCase { constructor( private readonly notificationRepository: INotificationRepository, ) {} async execute(command: DismissNotificationCommand): Promise { const notification = await this.notificationRepository.findById(command.notificationId); if (!notification) { throw new NotificationDomainError('Notification not found'); } if (notification.recipientId !== command.recipientId) { throw new NotificationDomainError('Cannot dismiss another user\'s notification'); } if (notification.isDismissed()) { return; // Already dismissed } const updatedNotification = notification.dismiss(); await this.notificationRepository.update(updatedNotification); } }