feat: add release communications
All checks were successful
deploy-socialize / image (push) Successful in 1m12s
deploy-socialize / deploy (push) Successful in 19s

This commit is contained in:
2026-05-07 21:00:59 -04:00
parent 7a8a0a44bf
commit b6eb348605
61 changed files with 8594 additions and 4 deletions

View File

@@ -0,0 +1,50 @@
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<IReadOnlyCollection<ReleaseUpdateDto>>
{
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<ReleaseUpdate> updates = await dbContext.ReleaseUpdates
.VisibleTo(audienceContext)
.OrderByDescending(update => update.PublishedAt)
.ThenByDescending(update => update.CreatedAt)
.ToListAsync(ct);
HashSet<Guid> 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<HashSet<Guid>> GetReadUpdateIdsAsync(
Guid userId,
IEnumerable<Guid> 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);
}
}