using FastEndpoints; using Microsoft.EntityFrameworkCore; using Socialize.Api.Data; using Socialize.Api.Infrastructure.Security; using Socialize.Api.Modules.ContentItems.Data; using Socialize.Api.Modules.Notifications.Data; namespace Socialize.Api.Modules.Notifications.Handlers; public record GetNotificationsRequest(Guid? WorkspaceId, Guid? ContentItemId); public record NotificationEventDto( Guid Id, Guid WorkspaceId, Guid? ContentItemId, string EventType, string EntityType, Guid EntityId, string Message, Guid? RecipientUserId, string? RecipientEmail, string? MetadataJson, DateTimeOffset CreatedAt, DateTimeOffset? ReadAt); public class GetNotificationsHandler( AppDbContext dbContext, AccessScopeService accessScopeService) : Endpoint> { public override void Configure() { Get("/api/notifications"); Options(o => o.WithTags("Notifications")); } public override async Task HandleAsync(GetNotificationsRequest request, CancellationToken ct) { if (request.ContentItemId.HasValue) { ContentItem? item = await dbContext.ContentItems .SingleOrDefaultAsync(candidate => candidate.Id == request.ContentItemId.Value, ct); if (item is null) { await SendNotFoundAsync(ct); return; } if (!await accessScopeService.CanReviewContentAsync(User, item.WorkspaceId, item.ClientId, item.CampaignId, ct)) { await SendForbiddenAsync(ct); return; } } IQueryable query = dbContext.NotificationEvents.AsQueryable(); Guid currentUserId = User.GetUserId(); if (!accessScopeService.IsManager(User)) { IReadOnlyCollection workspaceScopeIds = await accessScopeService.GetAccessibleWorkspaceIdsAsync(User, ct); query = query.Where(notificationEvent => workspaceScopeIds.Contains(notificationEvent.WorkspaceId) || notificationEvent.RecipientUserId == currentUserId); } query = query.Where(notificationEvent => notificationEvent.RecipientUserId == null || notificationEvent.RecipientUserId == currentUserId); if (request.WorkspaceId.HasValue) { query = query.Where(notificationEvent => notificationEvent.WorkspaceId == request.WorkspaceId.Value); } if (request.ContentItemId.HasValue) { query = query.Where(notificationEvent => notificationEvent.ContentItemId == request.ContentItemId.Value); } List notifications = await query .OrderByDescending(notificationEvent => notificationEvent.CreatedAt) .Take(100) .Select(notificationEvent => new NotificationEventDto( notificationEvent.Id, notificationEvent.WorkspaceId, notificationEvent.ContentItemId, notificationEvent.EventType, notificationEvent.EntityType, notificationEvent.EntityId, notificationEvent.Message, notificationEvent.RecipientUserId, notificationEvent.RecipientEmail, notificationEvent.MetadataJson, notificationEvent.CreatedAt, notificationEvent.ReadAt)) .ToListAsync(ct); await SendOkAsync(notifications, ct); } }