Compare commits

...

1 Commits

5 changed files with 103 additions and 13 deletions

View File

@@ -4,20 +4,23 @@ using GozareshgirProgramManager.Domain.ProjectAgg.Events;
using MediatR;
using Microsoft.Extensions.Logging;
namespace GozareshgirProgramManager.Application.DomainEventHandlers.ProjectSection;
namespace GozareshgirProgramManager.Application.DomainEventHandlers.TaskSection;
public class ProjectSectionAddedHandler:INotificationHandler<DomainEventNotification<ProjectSectionAddedEvent>>
public class ProjectSectionAddedHandler:INotificationHandler<DomainEventNotification<TaskSectionAddedEvent>>
{
private readonly ILogger<CustomerRegisteredHandler> _logger;
private readonly IBoardNotificationPublisher _boardNotificationPublisher;
public ProjectSectionAddedHandler(ILogger<CustomerRegisteredHandler> logger)
public ProjectSectionAddedHandler(ILogger<CustomerRegisteredHandler> logger, IBoardNotificationPublisher boardNotificationPublisher)
{
_logger = logger;
_boardNotificationPublisher = boardNotificationPublisher;
}
public Task Handle(DomainEventNotification<ProjectSectionAddedEvent> notification, CancellationToken cancellationToken)
public Task Handle(DomainEventNotification<TaskSectionAddedEvent> notification, CancellationToken cancellationToken)
{
var domainEvent = notification.DomainEvent;
//_boardNotificationPublisher.NotifyTaskCreated()
return Task.CompletedTask;
}
}

View File

@@ -2,7 +2,7 @@ using GozareshgirProgramManager.Application._Common.Models;
using GozareshgirProgramManager.Domain.ProjectAgg.Events;
using MediatR;
namespace GozareshgirProgramManager.Application.DomainEventHandlers.ProjectSection;
namespace GozareshgirProgramManager.Application.DomainEventHandlers.TaskSection;
public class ProjectSectionAssignedHandler:INotificationHandler<DomainEventNotification<ProjectSectionAssignedEvent>>
{

View File

@@ -3,7 +3,7 @@ using GozareshgirProgramManager.Application.Interfaces;
using GozareshgirProgramManager.Domain.ProjectAgg.Events;
using MediatR;
namespace GozareshgirProgramManager.Application.DomainEventHandlers.ProjectSection;
namespace GozareshgirProgramManager.Application.DomainEventHandlers.TaskSection;
public class TaskSectionStatusChangedHandler:INotificationHandler<DomainEventNotification<TaskSectionStatusChangedEvent>>
{
@@ -17,7 +17,7 @@ public class TaskSectionStatusChangedHandler:INotificationHandler<DomainEventNot
public Task Handle(DomainEventNotification<TaskSectionStatusChangedEvent> notification, CancellationToken cancellationToken)
{
var domainEvent = notification.DomainEvent;
_boardNotificationPublisher.SendProjectStatusChanged(domainEvent.UserId,domainEvent.OldStatus,domainEvent.NewStatus,domainEvent.SectionId);
_boardNotificationPublisher.NotifyTaskStatusChanged(domainEvent.UserId,domainEvent.OldStatus,domainEvent.NewStatus,domainEvent.SectionId);
return Task.CompletedTask;
}
}

View File

@@ -1,9 +1,19 @@
using GozareshgirProgramManager.Domain.ProjectAgg.Enums;
using GozareshgirProgramManager.Domain.ProjectAgg.Entities;
using GozareshgirProgramManager.Domain.ProjectAgg.Enums;
namespace GozareshgirProgramManager.Application.Interfaces;
public interface IBoardNotificationPublisher
{
Task SendProjectStatusChanged(long userId, TaskSectionStatus oldStatus,
Task NotifyTaskStatusChanged(long userId, TaskSectionStatus oldStatus,
TaskSectionStatus newStatus, Guid sectionId);
Task NotifyTaskCreated(TaskSection taskSection);
Task NotifyTaskAssigned(long userId, Guid sectionId);
Task NotifyTaskRemoved(long userId, Guid sectionId);
}

View File

@@ -1,12 +1,14 @@
using System.Collections.Concurrent;
using GozareshgirProgramManager.Application._Common.Constants;
using GozareshgirProgramManager.Application.Interfaces;
using GozareshgirProgramManager.Domain.ProjectAgg.Entities;
using GozareshgirProgramManager.Domain.ProjectAgg.Enums;
using Microsoft.AspNetCore.SignalR;
using ServiceHost.Hubs.ProgramManager;
namespace ServiceHost.Notifications.ProgramManager;
public class SignalRBoardNotificationPublisher:IBoardNotificationPublisher
public class SignalRBoardNotificationPublisher : IBoardNotificationPublisher
{
private readonly IHubContext<ProjectBoardHub> _hubContext;
@@ -15,12 +17,12 @@ public class SignalRBoardNotificationPublisher:IBoardNotificationPublisher
_hubContext = hubContext;
}
public Task SendProjectStatusChanged(long userId, TaskSectionStatus oldStatus,
public Task NotifyTaskStatusChanged(long userId, TaskSectionStatus oldStatus,
TaskSectionStatus newStatus, Guid sectionId)
{
var payload = new
{
UserId= userId,
UserId = userId,
OldStatus = oldStatus,
NewStatus = newStatus,
SectionId = sectionId
@@ -36,4 +38,79 @@ public class SignalRBoardNotificationPublisher:IBoardNotificationPublisher
return _hubContext.Clients.Groups(taskGroup, permissionGroup)
.SendAsync("ReceiveProjectStatusChanged", payload);
}
public async Task NotifyTaskCreated(TaskSection taskSection)
{
var sectionId = taskSection.Id;
var userId = taskSection.CurrentAssignedUserId;
var taskGroup = $"pm.task:{taskSection.Id}";
var adminGroup = $"pm.perm:{ProgramManagerPermissionCode.Board.All.ViewAll}";
// Add assignee connections to task group automatically
await AddAssigneeConnectionsToTaskGroup(userId, sectionId);
var payload = new
{
TaskId = sectionId,
AssignedTo = userId,
};
await _hubContext.Clients.Groups(taskGroup, adminGroup)
.SendAsync("TaskCreated", payload);
}
public Task NotifyTaskAssigned(long userId, Guid sectionId)
{
throw new NotImplementedException();
}
public Task NotifyTaskRemoved(long userId, Guid sectionId)
{
throw new NotImplementedException();
}
private async Task AddAssigneeConnectionsToTaskGroup(long userId, Guid taskId)
{
// Retrieve all connectionIds that have this claim
var connections = ConnectionMapping.GetConnectionsByClaim("pm.userId", userId.ToString());
var taskGroup = $"pm.task:{taskId}";
var joinTasks = connections
.Select(connId => _hubContext.Groups.AddToGroupAsync(connId, taskGroup));
await Task.WhenAll(joinTasks);
}
}
public static class ConnectionMapping
{
private static readonly ConcurrentDictionary<string, HashSet<string>> _map = new();
public static void Add(string claimType, string claimValue, string connectionId)
{
var key = $"{claimType}:{claimValue}";
_map.AddOrUpdate(key,
_ => new HashSet<string> { connectionId },
(_, set) => { set.Add(connectionId); return set; });
}
public static void Remove(string claimType, string claimValue, string connectionId)
{
var key = $"{claimType}:{claimValue}";
if (_map.TryGetValue(key, out var set))
{
set.Remove(connectionId);
if (!set.Any()) _map.TryRemove(key, out _);
}
}
public static IEnumerable<string> GetConnectionsByClaim(string claimType, string claimValue)
{
var key = $"{claimType}:{claimValue}";
return _map.TryGetValue(key, out var set) ? set : Enumerable.Empty<string>();
}
}