using FastEndpoints; using Microsoft.EntityFrameworkCore; using Socialize.Api.Data; using Socialize.Api.Infrastructure.Security; using Socialize.Api.Modules.ReleaseCommunications.Contracts; using Socialize.Api.Modules.ReleaseCommunications.Data; using Socialize.Api.Modules.ReleaseCommunications.Services; namespace Socialize.Api.Modules.ReleaseCommunications.Handlers; internal class ListReleaseUpdatesHandler(AppDbContext dbContext) : EndpointWithoutRequest> { public override void Configure() { Get("/api/release-updates"); Options(o => o.WithTags("Release Communications")); } public override async Task HandleAsync(CancellationToken ct) { Guid userId = User.GetUserId(); ReleaseUpdateAudienceContext audienceContext = await ReleaseUpdateVisibility.GetAudienceContextAsync(dbContext, User, userId, ct); List updates = await dbContext.ReleaseUpdates .VisibleTo(audienceContext) .OrderByDescending(update => update.PublishedAt) .ThenByDescending(update => update.CreatedAt) .ToListAsync(ct); HashSet readUpdateIds = await GetReadUpdateIdsAsync(userId, updates.Select(update => update.Id), ct); await SendOkAsync( updates.Select(update => update.ToDto(readUpdateIds.Contains(update.Id))).ToArray(), ct); } private async Task> GetReadUpdateIdsAsync( Guid userId, IEnumerable updateIds, CancellationToken ct) { Guid[] ids = updateIds.ToArray(); return await dbContext.ReleaseUpdateReadReceipts .Where(receipt => receipt.UserId == userId && ids.Contains(receipt.ReleaseUpdateId)) .Select(receipt => receipt.ReleaseUpdateId) .ToHashSetAsync(ct); } }