using ECPBLL.Communication.Interfaces;
using ECPDAL.Communication.DTOs;
using Microsoft.AspNetCore.SignalR;
namespace ECPSL.Communication.Hubs;
///
/// Concrete SignalR push implementation of ECPBLL.Communication.Interfaces.ICommunicationPushService.
/// Lives in ECPSL.Communication (where the Hub type must live per CLAUDE.md's SignalR folder rule)
/// and is registered against the BLL-owned interface in CommunicationModule.Register — this is
/// what lets CommentThreadBLL/CommentReactionBLL push via IHubContext without ECPBLL.Communication
/// ever referencing ECPSL.Communication (which would create a circular project reference, since SL
/// already depends on BLL). See ICommunicationPushService's doc-comment for the full rationale.
///
public class CommunicationPushService(
IHubContext _hubContext
) : ICommunicationPushService
{
private static string ObjectGroup(int objectTypeId, int objectId) => $"communication:{objectTypeId}:{objectId}";
private static string UserGroup(int userId) => $"communication:user:{userId}";
public async Task PushCommentAsync(int objectTypeId, int objectId, CommentThreadDTO comment, CancellationToken ct)
=> await _hubContext.Clients.Group(ObjectGroup(objectTypeId, objectId))
.ReceiveComment(comment).WaitAsync(ct).ConfigureAwait(false);
public async Task PushReplyAsync(int objectTypeId, int objectId, CommentThreadDTO reply, CancellationToken ct)
=> await _hubContext.Clients.Group(ObjectGroup(objectTypeId, objectId))
.ReceiveReply(reply).WaitAsync(ct).ConfigureAwait(false);
public async Task PushReactionAsync(int objectTypeId, int objectId, CommentReactionDTO reaction, CancellationToken ct)
=> await _hubContext.Clients.Group(ObjectGroup(objectTypeId, objectId))
.ReceiveReaction(reaction).WaitAsync(ct).ConfigureAwait(false);
public async Task PushStatusChangeAsync(int objectTypeId, int objectId, int commentThreadId, byte newStatus, CancellationToken ct)
=> await _hubContext.Clients.Group(ObjectGroup(objectTypeId, objectId))
.ReceiveStatusChange(commentThreadId, newStatus).WaitAsync(ct).ConfigureAwait(false);
public async Task PushMentionAsync(int mentionedUserId, CommentMentionDTO mention, CancellationToken ct)
=> await _hubContext.Clients.Group(UserGroup(mentionedUserId))
.ReceiveMention(mention).WaitAsync(ct).ConfigureAwait(false);
public async Task PushErrorAsync(int userId, string errorMessage, CancellationToken ct)
=> await _hubContext.Clients.Group(UserGroup(userId))
.ReceiveError("ERROR", errorMessage).WaitAsync(ct).ConfigureAwait(false);
}