99 lines
3.6 KiB
C#
99 lines
3.6 KiB
C#
using Socialize.Infrastructure.Security;
|
|
using Socialize.Modules.Clients.Data;
|
|
|
|
namespace Socialize.Modules.Clients.Handlers;
|
|
|
|
public record UpdateClientRequest(
|
|
string Name,
|
|
string? PortraitUrl,
|
|
string Status,
|
|
string? PrimaryContactName,
|
|
string? PrimaryContactEmail,
|
|
string? PrimaryContactPortraitUrl);
|
|
|
|
public class UpdateClientRequestValidator
|
|
: Validator<UpdateClientRequest>
|
|
{
|
|
public UpdateClientRequestValidator()
|
|
{
|
|
RuleFor(x => x.Name).NotEmpty().MaximumLength(256);
|
|
RuleFor(x => x.PortraitUrl).MaximumLength(2048);
|
|
RuleFor(x => x.Status).NotEmpty().MaximumLength(64);
|
|
RuleFor(x => x.PrimaryContactName).MaximumLength(256);
|
|
RuleFor(x => x.PrimaryContactEmail).MaximumLength(256).EmailAddress().When(x => !string.IsNullOrWhiteSpace(x.PrimaryContactEmail));
|
|
RuleFor(x => x.PrimaryContactPortraitUrl).MaximumLength(2048);
|
|
}
|
|
}
|
|
|
|
public class UpdateClientHandler(
|
|
AppDbContext clientsDbContext,
|
|
AccessScopeService accessScopeService)
|
|
: Endpoint<UpdateClientRequest, ClientDto>
|
|
{
|
|
public override void Configure()
|
|
{
|
|
Put("/api/clients/{id}");
|
|
Options(o => o.WithTags("Clients"));
|
|
}
|
|
|
|
public override async Task HandleAsync(UpdateClientRequest request, CancellationToken ct)
|
|
{
|
|
Guid id = Route<Guid>("id");
|
|
|
|
Client? client = await clientsDbContext.Clients.SingleOrDefaultAsync(candidate => candidate.Id == id, ct);
|
|
if (client is null)
|
|
{
|
|
await SendNotFoundAsync(ct);
|
|
return;
|
|
}
|
|
|
|
if (!accessScopeService.CanManageWorkspace(User, client.WorkspaceId))
|
|
{
|
|
await SendForbiddenAsync(ct);
|
|
return;
|
|
}
|
|
|
|
string normalizedName = request.Name.Trim();
|
|
string normalizedStatus = request.Status.Trim();
|
|
string? normalizedPortraitUrl = request.PortraitUrl?.Trim();
|
|
string? normalizedPrimaryContactName = request.PrimaryContactName?.Trim();
|
|
string? normalizedPrimaryContactEmail = request.PrimaryContactEmail?.Trim();
|
|
string? normalizedPrimaryContactPortraitUrl = request.PrimaryContactPortraitUrl?.Trim();
|
|
|
|
bool duplicateClient = await clientsDbContext.Clients
|
|
.AnyAsync(
|
|
candidate => candidate.Id != id
|
|
&& candidate.WorkspaceId == client.WorkspaceId
|
|
&& candidate.Name == normalizedName,
|
|
ct);
|
|
|
|
if (duplicateClient)
|
|
{
|
|
AddError(request => request.Name, "A client with this name already exists in the active workspace.");
|
|
await SendErrorsAsync(StatusCodes.Status409Conflict, ct);
|
|
return;
|
|
}
|
|
|
|
client.Name = normalizedName;
|
|
client.Status = normalizedStatus;
|
|
client.PortraitUrl = string.IsNullOrWhiteSpace(normalizedPortraitUrl) ? null : normalizedPortraitUrl;
|
|
client.PrimaryContactName = string.IsNullOrWhiteSpace(normalizedPrimaryContactName) ? null : normalizedPrimaryContactName;
|
|
client.PrimaryContactEmail = string.IsNullOrWhiteSpace(normalizedPrimaryContactEmail) ? null : normalizedPrimaryContactEmail;
|
|
client.PrimaryContactPortraitUrl = string.IsNullOrWhiteSpace(normalizedPrimaryContactPortraitUrl) ? null : normalizedPrimaryContactPortraitUrl;
|
|
|
|
await clientsDbContext.SaveChangesAsync(ct);
|
|
|
|
ClientDto dto = new(
|
|
client.Id,
|
|
client.WorkspaceId,
|
|
client.Name,
|
|
client.Status,
|
|
client.PortraitUrl,
|
|
client.PrimaryContactName,
|
|
client.PrimaryContactEmail,
|
|
client.PrimaryContactPortraitUrl);
|
|
|
|
await SendOkAsync(dto, ct);
|
|
}
|
|
}
|