using FastEndpoints; using Microsoft.EntityFrameworkCore; using Socialize.Api.Data; using Socialize.Api.Modules.Identity.Contracts; using Socialize.Api.Modules.ReleaseCommunications.Contracts; using Socialize.Api.Modules.ReleaseCommunications.Data; namespace Socialize.Api.Modules.ReleaseCommunications.Handlers; internal record UpdateDeveloperReleaseUpdateRequest( string TitleEn, string DescriptionEn, string TitleFr, string DescriptionFr); internal class UpdateDeveloperReleaseUpdateRequestValidator : Validator { public UpdateDeveloperReleaseUpdateRequestValidator() { RuleFor(x => x.TitleEn).NotEmpty().MaximumLength(160); RuleFor(x => x.DescriptionEn).NotEmpty().MaximumLength(4000); RuleFor(x => x.TitleFr).NotEmpty().MaximumLength(160); RuleFor(x => x.DescriptionFr).NotEmpty().MaximumLength(4000); } } internal class UpdateDeveloperReleaseUpdateHandler(AppDbContext dbContext) : Endpoint { public override void Configure() { Put("/api/developer/release-updates/{id}"); Roles(KnownRoles.Developer); Options(o => o.WithTags("Release Communications")); } public override async Task HandleAsync(UpdateDeveloperReleaseUpdateRequest request, CancellationToken ct) { Guid id = Route("id"); ReleaseUpdate? update = await dbContext.ReleaseUpdates.SingleOrDefaultAsync(candidate => candidate.Id == id, ct); if (update is null) { await SendNotFoundAsync(ct); return; } if (update.Status != ReleaseUpdateStatus.Draft) { AddError("Only draft release updates can be edited."); await SendErrorsAsync(StatusCodes.Status400BadRequest, ct); return; } update.Title = request.TitleEn.Trim(); update.Summary = request.DescriptionEn.Trim(); update.TitleFr = request.TitleFr.Trim(); update.SummaryFr = request.DescriptionFr.Trim(); update.UpdatedAt = DateTimeOffset.UtcNow; await dbContext.SaveChangesAsync(ct); await SendOkAsync(update.ToDto(false), ct); } }