Files
social-media/backend/src/Socialize.Api/Modules/Feedback/Handlers/CancelMyFeedback.cs

81 lines
2.7 KiB
C#

using FastEndpoints;
using Microsoft.EntityFrameworkCore;
using Socialize.Api.Data;
using Socialize.Api.Infrastructure.Security;
using Socialize.Api.Modules.Feedback.Contracts;
using Socialize.Api.Modules.Feedback.Data;
using Socialize.Api.Modules.Feedback.Services;
namespace Socialize.Api.Modules.Feedback.Handlers;
public record CancelMyFeedbackRequest(string? Reason);
public class CancelMyFeedbackRequestValidator
: Validator<CancelMyFeedbackRequest>
{
public CancelMyFeedbackRequestValidator()
{
RuleFor(x => x.Reason).MaximumLength(2000);
}
}
public class CancelMyFeedbackHandler(AppDbContext dbContext)
: Endpoint<CancelMyFeedbackRequest, FeedbackReportDto>
{
public override void Configure()
{
Post("/api/my-feedback/{id}/cancel");
Options(o => o.WithTags("Feedback"));
}
public override async Task HandleAsync(CancelMyFeedbackRequest request, CancellationToken ct)
{
Guid id = Route<Guid>("id");
Guid reporterUserId = User.GetUserId();
FeedbackReport? report = await dbContext.FeedbackReports
.Include(candidate => candidate.Tags)
.Include(candidate => candidate.Screenshot)
.SingleOrDefaultAsync(
candidate => candidate.Id == id && candidate.ReporterUserId == reporterUserId,
ct);
if (report is null)
{
await SendNotFoundAsync(ct);
return;
}
if (!FeedbackAccessRules.CanReporterCancel(report, reporterUserId))
{
AddError("The feedback report cannot be cancelled.");
await SendErrorsAsync(StatusCodes.Status400BadRequest, ct);
return;
}
DateTimeOffset now = DateTimeOffset.UtcNow;
FeedbackStatus previousStatus = report.Status;
report.Status = FeedbackStatus.Cancelled;
report.CancelledAt = now;
report.CancelledByUserId = reporterUserId;
report.CancellationReason = string.IsNullOrWhiteSpace(request.Reason) ? null : request.Reason.Trim();
report.LastActivityAt = now;
report.ActivityEntries.Add(new FeedbackActivityEntry
{
Id = Guid.NewGuid(),
FeedbackReportId = report.Id,
ActorUserId = reporterUserId,
ActorDisplayName = User.GetAlias() ?? User.GetName(),
ActorEmail = User.GetEmail(),
ActivityType = FeedbackActivityTypes.Cancelled,
FromValue = previousStatus.ToFeedbackDisplayString(),
ToValue = FeedbackStatus.Cancelled.ToFeedbackDisplayString(),
Note = report.CancellationReason,
CreatedAt = now,
});
await dbContext.SaveChangesAsync(ct);
await SendOkAsync(report.ToDto(), ct);
}
}