102 lines
3.8 KiB
C#
102 lines
3.8 KiB
C#
using Socialize.Infrastructure.Security;
|
|
namespace Socialize.Modules.Clients.Handlers;
|
|
|
|
public record CreateClientRequest(
|
|
Guid WorkspaceId,
|
|
string Name,
|
|
string? PortraitUrl,
|
|
string? PrimaryContactName,
|
|
string? PrimaryContactEmail,
|
|
string? PrimaryContactPortraitUrl);
|
|
|
|
public class CreateClientRequestValidator
|
|
: Validator<CreateClientRequest>
|
|
{
|
|
public CreateClientRequestValidator()
|
|
{
|
|
RuleFor(x => x.WorkspaceId).NotEmpty();
|
|
RuleFor(x => x.Name).NotEmpty().MaximumLength(256);
|
|
RuleFor(x => x.PortraitUrl).MaximumLength(2048);
|
|
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 CreateClientHandler(
|
|
AppDbContext dbContext,
|
|
AccessScopeService accessScopeService)
|
|
: Endpoint<CreateClientRequest, ClientDto>
|
|
{
|
|
public override void Configure()
|
|
{
|
|
Post("/api/clients");
|
|
Options(o => o.WithTags("Clients"));
|
|
}
|
|
|
|
public override async Task HandleAsync(CreateClientRequest request, CancellationToken ct)
|
|
{
|
|
if (!accessScopeService.CanManageWorkspace(User, request.WorkspaceId))
|
|
{
|
|
await SendForbiddenAsync(ct);
|
|
return;
|
|
}
|
|
|
|
bool workspaceExists = await dbContext.Workspaces
|
|
.AnyAsync(workspace => workspace.Id == request.WorkspaceId, ct);
|
|
|
|
if (!workspaceExists)
|
|
{
|
|
AddError(request => request.WorkspaceId, "The selected workspace does not exist.");
|
|
await SendErrorsAsync(StatusCodes.Status400BadRequest, ct);
|
|
return;
|
|
}
|
|
|
|
string normalizedName = request.Name.Trim();
|
|
string? normalizedPortraitUrl = request.PortraitUrl?.Trim();
|
|
string? normalizedPrimaryContactName = request.PrimaryContactName?.Trim();
|
|
string? normalizedPrimaryContactEmail = request.PrimaryContactEmail?.Trim();
|
|
string? normalizedPrimaryContactPortraitUrl = request.PrimaryContactPortraitUrl?.Trim();
|
|
|
|
bool duplicateClient = await dbContext.Clients
|
|
.AnyAsync(
|
|
client => client.WorkspaceId == request.WorkspaceId && client.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 client = new()
|
|
{
|
|
Id = Guid.NewGuid(),
|
|
WorkspaceId = request.WorkspaceId,
|
|
Name = normalizedName,
|
|
Status = "Active",
|
|
PortraitUrl = string.IsNullOrWhiteSpace(normalizedPortraitUrl) ? null : normalizedPortraitUrl,
|
|
PrimaryContactName = string.IsNullOrWhiteSpace(normalizedPrimaryContactName) ? null : normalizedPrimaryContactName,
|
|
PrimaryContactEmail = string.IsNullOrWhiteSpace(normalizedPrimaryContactEmail) ? null : normalizedPrimaryContactEmail,
|
|
PrimaryContactPortraitUrl = string.IsNullOrWhiteSpace(normalizedPrimaryContactPortraitUrl) ? null : normalizedPrimaryContactPortraitUrl,
|
|
CreatedAt = DateTimeOffset.UtcNow,
|
|
};
|
|
|
|
dbContext.Clients.Add(client);
|
|
await dbContext.SaveChangesAsync(ct);
|
|
|
|
ClientDto dto = new(
|
|
client.Id,
|
|
client.WorkspaceId,
|
|
client.Name,
|
|
client.Status,
|
|
client.PortraitUrl,
|
|
client.PrimaryContactName,
|
|
client.PrimaryContactEmail,
|
|
client.PrimaryContactPortraitUrl);
|
|
|
|
await SendAsync(dto, StatusCodes.Status201Created, ct);
|
|
}
|
|
}
|