using ColaFlow.Modules.Mcp.Application.DTOs.Notifications; using ColaFlow.Modules.Mcp.Application.Services; using ColaFlow.Modules.Mcp.Domain.Entities; using ColaFlow.Modules.Mcp.Domain.Events; using ColaFlow.Modules.Mcp.Domain.Repositories; using MediatR; using Microsoft.Extensions.Logging; namespace ColaFlow.Modules.Mcp.Application.EventHandlers; /// /// Event handler that sends SignalR notifications when a PendingChange is created /// public class PendingChangeCreatedNotificationHandler : INotificationHandler { private readonly IMcpNotificationService _notificationService; private readonly IPendingChangeRepository _repository; private readonly ILogger _logger; public PendingChangeCreatedNotificationHandler( IMcpNotificationService notificationService, IPendingChangeRepository repository, ILogger logger) { _notificationService = notificationService ?? throw new ArgumentNullException(nameof(notificationService)); _repository = repository ?? throw new ArgumentNullException(nameof(repository)); _logger = logger ?? throw new ArgumentNullException(nameof(logger)); } public async Task Handle(PendingChangeCreatedEvent notification, CancellationToken cancellationToken) { _logger.LogInformation( "Handling PendingChangeCreatedEvent - PendingChangeId={PendingChangeId}, EntityType={EntityType}, Operation={Operation}", notification.PendingChangeId, notification.EntityType, notification.Operation); try { // Get PendingChange for summary var pendingChange = await _repository.GetByIdAsync(notification.PendingChangeId, cancellationToken); if (pendingChange == null) { _logger.LogWarning( "PendingChange not found - PendingChangeId={PendingChangeId}", notification.PendingChangeId); return; } // Create notification DTO var notificationDto = new PendingChangeCreatedNotification { NotificationType = "PendingChangeCreated", PendingChangeId = notification.PendingChangeId, ToolName = notification.ToolName, EntityType = notification.EntityType, Operation = notification.Operation, Summary = pendingChange.GetSummary(), TenantId = notification.TenantId, Timestamp = DateTime.UtcNow }; // Send notification via SignalR await _notificationService.NotifyPendingChangeCreatedAsync(notificationDto, cancellationToken); _logger.LogInformation( "PendingChangeCreated notification sent successfully - PendingChangeId={PendingChangeId}", notification.PendingChangeId); } catch (Exception ex) { _logger.LogError(ex, "Failed to send PendingChangeCreated notification - PendingChangeId={PendingChangeId}", notification.PendingChangeId); // Don't rethrow - notification failure shouldn't break the main flow } } }