Skip to content

Commit 4b62d33

Browse files
committed
(#411) notifications: update comment service external events and events handlers
1 parent f84de45 commit 4b62d33

File tree

11 files changed

+171
-53
lines changed

11 files changed

+171
-53
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,16 @@
11
using System;
22
using System.Collections.Generic;
3-
using System.Diagnostics.CodeAnalysis;
43
using System.Linq;
5-
using MiniSpace.Services.Notifications.Core.Entities;
4+
using MiniSpace.Services.Notifications.Application.Dto.Comments;
65

7-
namespace MiniSpace.Services.Notifications.Application.Dto
6+
namespace MiniSpace.Services.Notifications.Application.Dto.Comments
87
{
98
public class CommentDto
109
{
1110
public Guid Id { get; set; }
1211
public Guid ContextId { get; set; }
1312
public string CommentContext { get; set; }
14-
public Guid StudentId { get; set; }
15-
public string StudentName { get; set; }
13+
public Guid UserId { get; set; }
1614
public IEnumerable<Guid> Likes { get; set; }
1715
public Guid ParentId { get; set; }
1816
public string TextContent { get; set; }
@@ -21,5 +19,10 @@ public class CommentDto
2119
public DateTime LastReplyAt { get; set; }
2220
public int RepliesCount { get; set; }
2321
public bool IsDeleted { get; set; }
22+
public IEnumerable<ReplyDto> Replies { get; set; }
23+
24+
public CommentDto()
25+
{
26+
}
2427
}
25-
}
28+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Threading.Tasks;
5+
6+
namespace MiniSpace.Services.Notifications.Application.Dto.Comments
7+
{
8+
public class ReplyDto
9+
{
10+
public Guid Id { get; set; }
11+
public Guid UserId { get; set; }
12+
public Guid CommentId { get; set; }
13+
public string TextContent { get; set; }
14+
public DateTime CreatedAt { get; set; }
15+
}
16+
}

MiniSpace.Services.Notifications/src/MiniSpace.Services.Notifications.Application/Events/External/Comments/CommentCreated.cs

+6-1
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,13 @@ public class CommentCreated : IEvent
1717
public DateTime LastUpdatedAt { get; }
1818
public int RepliesCount { get; }
1919
public bool IsDeleted { get; }
20+
public string UserName { get; }
21+
public string ProfileImageUrl { get; }
2022

2123
public CommentCreated(Guid commentId, Guid contextId, string commentContext, Guid userId,
2224
Guid parentId, string textContent, DateTime createdAt,
23-
DateTime lastUpdatedAt, int repliesCount, bool isDeleted)
25+
DateTime lastUpdatedAt, int repliesCount, bool isDeleted,
26+
string userName, string profileImageUrl)
2427
{
2528
CommentId = commentId;
2629
ContextId = contextId;
@@ -32,6 +35,8 @@ public CommentCreated(Guid commentId, Guid contextId, string commentContext, Gui
3235
LastUpdatedAt = lastUpdatedAt;
3336
RepliesCount = repliesCount;
3437
IsDeleted = isDeleted;
38+
UserName = userName;
39+
ProfileImageUrl = profileImageUrl;
3540
}
3641
}
3742
}

MiniSpace.Services.Notifications/src/MiniSpace.Services.Notifications.Application/Events/External/Comments/CommentUpdated.cs

+6-1
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,19 @@ public class CommentUpdated : IEvent
1212
public string CommentContext { get; }
1313
public DateTime UpdatedAt { get; }
1414
public string CommentContent { get; }
15+
public string UserName { get; }
16+
public string ProfileImageUrl { get; }
1517

16-
public CommentUpdated(Guid commentId, Guid userId, string commentContext, DateTime updatedAt, string commentContent)
18+
public CommentUpdated(Guid commentId, Guid userId, string commentContext,
19+
DateTime updatedAt, string commentContent, string userName, string profileImageUrl)
1720
{
1821
CommentId = commentId;
1922
UserId = userId;
2023
CommentContext = commentContext;
2124
UpdatedAt = updatedAt;
2225
CommentContent = commentContent;
26+
UserName = userName;
27+
ProfileImageUrl = profileImageUrl;
2328
}
2429
}
2530
}

MiniSpace.Services.Notifications/src/MiniSpace.Services.Notifications.Application/Events/External/Comments/Handlers/CommentCreatedHandler.cs

+6-20
Original file line numberDiff line numberDiff line change
@@ -45,22 +45,11 @@ public async Task HandleAsync(CommentCreated @event, CancellationToken cancellat
4545
{
4646
try
4747
{
48-
// Fetch comment details from the comment service
49-
var commentDetails = await _commentsServiceClient.GetCommentAsync(@event.CommentId);
50-
if (commentDetails == null)
51-
{
52-
_logger.LogError("No comment details found for CommentCreated event.");
53-
return;
54-
}
55-
56-
// Initialize entity owner and name variables
5748
var entityOwnerId = Guid.Empty;
5849
string entityName = string.Empty;
5950

60-
// Check if it's an event or post
6151
if (@event.CommentContext.Equals("OrganizationEvent", StringComparison.OrdinalIgnoreCase))
6252
{
63-
// Fetch organization event details
6453
var organizationEvent = await _eventsServiceClient.GetEventAsync(@event.ContextId);
6554
if (organizationEvent != null)
6655
{
@@ -72,8 +61,7 @@ public async Task HandleAsync(CommentCreated @event, CancellationToken cancellat
7261
}
7362
else if (@event.CommentContext.Equals("OrganizationPost", StringComparison.OrdinalIgnoreCase))
7463
{
75-
// Fetch organization post details
76-
var organizationPost = await _postsServiceClient.GetPostAsync(@event.ContextId);
64+
var organizationPost = await _postsServiceClient.GetPostAsync(@event.ContextId);
7765
if (organizationPost != null)
7866
{
7967
entityOwnerId = organizationPost.UserId.HasValue ? organizationPost.UserId.Value : Guid.Empty;
@@ -82,7 +70,6 @@ public async Task HandleAsync(CommentCreated @event, CancellationToken cancellat
8270
}
8371
else if (@event.CommentContext.Equals("UserEvent", StringComparison.OrdinalIgnoreCase))
8472
{
85-
// Fetch user event details
8673
var userEvent = await _eventsServiceClient.GetEventAsync(@event.ContextId);
8774
if (userEvent != null)
8875
{
@@ -92,7 +79,6 @@ public async Task HandleAsync(CommentCreated @event, CancellationToken cancellat
9279
}
9380
else if (@event.CommentContext.Equals("UserPost", StringComparison.OrdinalIgnoreCase))
9481
{
95-
// Fetch user post details
9682
var userPost = await _postsServiceClient.GetPostAsync(@event.ContextId);
9783
if (userPost != null)
9884
{
@@ -112,11 +98,12 @@ public async Task HandleAsync(CommentCreated @event, CancellationToken cancellat
11298
return;
11399
}
114100

115-
// Notify the entity owner (user or organization)
101+
var notificationMessage = $"A new comment has been made on '{entityName}' by {@event.UserName}. <img src='{@event.ProfileImageUrl}' alt='Profile Image' style='width:50px;height:50px;' />";
102+
116103
var notification = new Notification(
117104
notificationId: Guid.NewGuid(),
118105
userId: entityOwnerId,
119-
message: $"A new comment has been made on '{entityName}' by {commentDetails.StudentName}.",
106+
message: notificationMessage,
120107
status: NotificationStatus.Unread,
121108
createdAt: DateTime.UtcNow,
122109
updatedAt: null,
@@ -130,15 +117,14 @@ public async Task HandleAsync(CommentCreated @event, CancellationToken cancellat
130117
userNotifications.AddNotification(notification);
131118
await _userNotificationsRepository.AddOrUpdateAsync(userNotifications);
132119

133-
// Broadcast notification via SignalR
134120
var notificationDto = new NotificationDto
135121
{
136122
UserId = entityOwnerId,
137-
Message = notification.Message,
123+
Message = notificationMessage,
138124
CreatedAt = notification.CreatedAt,
139125
EventType = NotificationEventType.CommentCreated,
140126
RelatedEntityId = @event.CommentId,
141-
Details = $"<p>A new comment was made on '{entityName}'.</p>"
127+
Details = $"<p>{@event.UserName} commented: '{@event.TextContent}' on '{entityName}'.</p><img src='{@event.ProfileImageUrl}' alt='Profile Image' style='width:50px;height:50px;' />"
142128
};
143129

144130
await NotificationHub.BroadcastNotification(_hubContext, notificationDto, _logger);

MiniSpace.Services.Notifications/src/MiniSpace.Services.Notifications.Application/Events/External/Comments/Handlers/CommentUpdatedHandler.cs

+15-10
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
using MiniSpace.Services.Notifications.Application.Dto;
1313
using MiniSpace.Services.Notifications.Application.Events.External.Comments;
1414
using MiniSpace.Services.Notifications.Application.Dto.Events;
15+
using MiniSpace.Services.Notifications.Application.Dto.Comments;
1516

1617
namespace MiniSpace.Services.Notifications.Application.Events.External.Handlers
1718
{
@@ -77,15 +78,16 @@ public async Task HandleAsync(CommentUpdated eventArgs, CancellationToken cancel
7778
throw;
7879
}
7980

80-
var studentNotifications = await _studentNotificationsRepository.GetByUserIdAsync(commentDetails.StudentId);
81+
var studentNotifications = await _studentNotificationsRepository.GetByUserIdAsync(commentDetails.UserId);
8182
if (studentNotifications == null)
8283
{
83-
studentNotifications = new UserNotifications(commentDetails.StudentId);
84+
studentNotifications = new UserNotifications(commentDetails.UserId);
8485
}
8586

87+
// Create notification for the user who updated the comment
8688
var userNotification = new Notification(
8789
notificationId: Guid.NewGuid(),
88-
userId: commentDetails.StudentId,
90+
userId: commentDetails.UserId,
8991
message: $"Your updated comment on the event '{eventDetails.Name}' has been processed.",
9092
status: NotificationStatus.Unread,
9193
createdAt: DateTime.UtcNow,
@@ -114,7 +116,7 @@ public async Task HandleAsync(CommentUpdated eventArgs, CancellationToken cancel
114116
// Broadcast the updated notification via SignalR
115117
var notificationDto = new NotificationDto
116118
{
117-
UserId = commentDetails.StudentId,
119+
UserId = commentDetails.UserId,
118120
Message = userNotification.Message,
119121
CreatedAt = userNotification.CreatedAt,
120122
EventType = NotificationEventType.CommentUpdated,
@@ -123,18 +125,20 @@ public async Task HandleAsync(CommentUpdated eventArgs, CancellationToken cancel
123125
};
124126

125127
await NotificationHub.BroadcastNotification(_hubContext, notificationDto, _logger);
126-
_logger.LogInformation("Broadcasted SignalR notification to all users.");
128+
_logger.LogInformation("Broadcasted SignalR notification to the user.");
127129

130+
// Organizer notification
128131
var organizerNotifications = await _studentNotificationsRepository.GetByUserIdAsync(eventDetails.Organizer.Id);
129132
if (organizerNotifications == null)
130133
{
131134
organizerNotifications = new UserNotifications(eventDetails.Organizer.Id);
132135
}
133136

137+
// Create notification for the organizer
134138
var organizerNotification = new Notification(
135139
notificationId: Guid.NewGuid(),
136140
userId: eventDetails.Organizer.Id,
137-
message: $"{commentDetails.StudentName} has updated their comment on your event '{eventDetails.Name}'.",
141+
message: $"{eventArgs.UserName} has updated their comment on your event '{eventDetails.Name}'.",
138142
status: NotificationStatus.Unread,
139143
createdAt: DateTime.UtcNow,
140144
updatedAt: DateTime.UtcNow,
@@ -145,13 +149,14 @@ public async Task HandleAsync(CommentUpdated eventArgs, CancellationToken cancel
145149
organizerNotifications.AddNotification(organizerNotification);
146150
await _studentNotificationsRepository.AddOrUpdateAsync(organizerNotifications);
147151

148-
// Prepare and send organizer notification details HTML
149-
var organizerNotificationDetailsHtml = $"<p>{commentDetails.StudentName} updated their comment on your event '{eventDetails.Name}': {commentDetails.CommentContext}</p>";
152+
// Prepare and send organizer notification details HTML, including profile image
153+
var organizerNotificationDetailsHtml = $"<p>{eventArgs.UserName} updated their comment on your event '{eventDetails.Name}': {eventArgs.CommentContent}.</p>" +
154+
$"<img src='{eventArgs.ProfileImageUrl}' alt='Profile Image' style='width:50px;height:50px;' />";
150155

151156
var organizerNotificationUpdatedEvent = new NotificationCreated(
152157
notificationId: Guid.NewGuid(),
153158
userId: eventDetails.Organizer.Id,
154-
message: $"{commentDetails.StudentName} has updated their comment on your event '{eventDetails.Name}'.",
159+
message: $"{eventArgs.UserName} has updated their comment on your event '{eventDetails.Name}'.",
155160
createdAt: DateTime.UtcNow,
156161
eventType: NotificationEventType.CommentUpdated.ToString(),
157162
relatedEntityId: eventArgs.CommentId,
@@ -171,7 +176,7 @@ public async Task HandleAsync(CommentUpdated eventArgs, CancellationToken cancel
171176
};
172177

173178
await NotificationHub.BroadcastNotification(_hubContext, organizerNotificationDto, _logger);
174-
_logger.LogInformation("Broadcasted SignalR notification to all users.");
179+
_logger.LogInformation("Broadcasted SignalR notification to the event organizer.");
175180
}
176181
}
177182
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
using System;
2+
using System.Threading;
3+
using System.Threading.Tasks;
4+
using Convey.CQRS.Events;
5+
using MiniSpace.Services.Notifications.Core.Repositories;
6+
using MiniSpace.Services.Notifications.Application.Services.Clients;
7+
using Microsoft.Extensions.Logging;
8+
using MiniSpace.Services.Notifications.Application.Hubs;
9+
using MiniSpace.Services.Notifications.Application.Dto;
10+
using Microsoft.AspNetCore.SignalR;
11+
using MiniSpace.Services.Notifications.Core.Entities;
12+
13+
namespace MiniSpace.Services.Notifications.Application.Events.External.Comments.Handlers
14+
{
15+
public class LikeAddedHandler : IEventHandler<LikeAdded>
16+
{
17+
private readonly ICommentsServiceClient _commentsServiceClient;
18+
private readonly IPostsServiceClient _postsServiceClient;
19+
private readonly IUserNotificationsRepository _userNotificationsRepository;
20+
private readonly ILogger<LikeAddedHandler> _logger;
21+
private readonly IHubContext<NotificationHub> _hubContext;
22+
23+
public LikeAddedHandler(
24+
ICommentsServiceClient commentsServiceClient,
25+
IPostsServiceClient postsServiceClient,
26+
IUserNotificationsRepository userNotificationsRepository,
27+
ILogger<LikeAddedHandler> logger,
28+
IHubContext<NotificationHub> hubContext)
29+
{
30+
_commentsServiceClient = commentsServiceClient;
31+
_postsServiceClient = postsServiceClient;
32+
_userNotificationsRepository = userNotificationsRepository;
33+
_logger = logger;
34+
_hubContext = hubContext;
35+
}
36+
37+
public async Task HandleAsync(LikeAdded @event, CancellationToken cancellationToken = default)
38+
{
39+
try
40+
{
41+
var commentDetails = await _commentsServiceClient.GetCommentAsync(@event.CommentId);
42+
if (commentDetails == null)
43+
{
44+
_logger.LogError($"No comment details found for LikeAdded event. CommentId: {@event.CommentId}");
45+
return;
46+
}
47+
48+
var entityOwnerId = commentDetails.UserId;
49+
var entityName = commentDetails.TextContent;
50+
51+
var notification = new Notification(
52+
notificationId: Guid.NewGuid(),
53+
userId: entityOwnerId,
54+
message: $"{@event.UserName} liked your comment '{entityName}'.",
55+
status: NotificationStatus.Unread,
56+
createdAt: DateTime.UtcNow,
57+
updatedAt: null,
58+
relatedEntityId: @event.CommentId,
59+
eventType: NotificationEventType.CommentLikeAdded
60+
);
61+
62+
var userNotifications = await _userNotificationsRepository.GetByUserIdAsync(entityOwnerId)
63+
?? new UserNotifications(entityOwnerId);
64+
65+
userNotifications.AddNotification(notification);
66+
await _userNotificationsRepository.AddOrUpdateAsync(userNotifications);
67+
68+
var notificationDetails = $"<p>{@event.UserName} liked your comment: '{@event.CommentContext}'.</p>" +
69+
$"<img src='{@event.ProfileImageUrl}' alt='Profile Image' style='width:50px;height:50px;' />";
70+
71+
var notificationDto = new NotificationDto
72+
{
73+
UserId = entityOwnerId,
74+
Message = notification.Message,
75+
CreatedAt = notification.CreatedAt,
76+
EventType = NotificationEventType.CommentLikeAdded,
77+
RelatedEntityId = @event.CommentId,
78+
Details = notificationDetails
79+
};
80+
81+
await NotificationHub.BroadcastNotification(_hubContext, notificationDto, _logger);
82+
}
83+
catch (Exception ex)
84+
{
85+
_logger.LogError($"Failed to handle LikeAdded event: {ex.Message}");
86+
}
87+
}
88+
}
89+
}

MiniSpace.Services.Notifications/src/MiniSpace.Services.Notifications.Application/Events/External/Comments/LikeAdded.cs

+6-1
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,18 @@ public class LikeAdded : IEvent
1111
public Guid UserId { get; }
1212
public string CommentContext { get; }
1313
public DateTime LikedAt { get; }
14+
public string UserName { get; }
15+
public string ProfileImageUrl { get; }
1416

15-
public LikeAdded(Guid commentId, Guid userId, string commentContext, DateTime likedAt)
17+
public LikeAdded(Guid commentId, Guid userId, string commentContext,
18+
DateTime likedAt, string userName, string profileImageUrl)
1619
{
1720
CommentId = commentId;
1821
UserId = userId;
1922
CommentContext = commentContext;
2023
LikedAt = likedAt;
24+
UserName = userName;
25+
ProfileImageUrl = profileImageUrl;
2126
}
2227
}
2328
}

0 commit comments

Comments
 (0)