Skip to content

Commit 3e16774

Browse files
committed
refactor: Refactoring in user creation and database indexes
1 parent 93ac5ec commit 3e16774

18 files changed

+333
-77
lines changed

src/SnackFlow.Application/Abstractions/Services/IAuthService.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,20 @@ public interface IAuthService
4040
/// <returns>Um objeto <see cref="UserDetailsDTO"/> contendo informações detalhadas do usuário se encontrado, ou null se o usuário não existir.</returns>
4141
Task<UserDetailsDTO?> FindByEmailAsync(string email);
4242

43+
/// <summary>
44+
/// Busca um usuário no sistema com base no nome de usuário fornecido.
45+
/// </summary>
46+
/// <param name="userName">O nome de usuário do usuário que está sendo pesquisado no sistema.</param>
47+
/// <returns>Uma tarefa que, quando concluída, contém as informações detalhadas do usuário na forma de um <see cref="UserDetailsDTO"/>, ou null se o usuário não for encontrado.</returns>
48+
Task<UserDetailsDTO?> FindByUserNameAsync(string userName);
49+
50+
/// <summary>
51+
/// Busca e retorna os detalhes de um usuário com base no número de telefone fornecido.
52+
/// </summary>
53+
/// <param name="phoneNumber">O número de telefone do usuário a ser buscado.</param>
54+
/// <returns>Uma tarefa que representa a operação assíncrona. O resultado contém os detalhes do usuário, ou null se nenhum usuário for encontrado.</returns>
55+
Task<UserDetailsDTO?> FindByPhoneAsync(string phoneNumber);
56+
4357
/// <summary>
4458
/// Atribui uma função ao usuário com base na posição empresarial especificada.
4559
/// </summary>
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
namespace SnackFlow.Application.Exceptions;
22

3-
public class ApplicationException(string message, int code) : Exception(message)
3+
public abstract class ApplicationException(string message, int code) : Exception(message)
44
{
5-
public int Code { get; } = code;
5+
public int Code => code;
66
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
using System.Net;
2+
3+
namespace SnackFlow.Application.Exceptions;
4+
5+
public sealed class AuthenticationServiceException(string message)
6+
: ApplicationException(message, (int)HttpStatusCode.InternalServerError);

src/SnackFlow.Application/Exceptions/ConflictException.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22

33
namespace SnackFlow.Application.Exceptions;
44

5-
public class ConflictException(string message)
5+
public sealed class ConflictException(string message)
66
: ApplicationException(message, (int)HttpStatusCode.Conflict);

src/SnackFlow.Application/Exceptions/NotFoundException.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22

33
namespace SnackFlow.Application.Exceptions;
44

5-
public class NotFoundException(string message)
5+
public sealed class NotFoundException(string message)
66
: ApplicationException(message, (int)HttpStatusCode.NotFound);

src/SnackFlow.Application/Exceptions/RequestTimeoutException.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22

33
namespace SnackFlow.Application.Exceptions;
44

5-
public class RequestTimeoutException(string requestName, TimeSpan elapsedTime)
5+
public sealed class RequestTimeoutException(string requestName, TimeSpan elapsedTime)
66
: ApplicationException($"Request '{requestName}' timed out after {elapsedTime.TotalSeconds:F1} seconds", (int)HttpStatusCode.RequestTimeout);

src/SnackFlow.Application/Exceptions/ValidationException.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
namespace SnackFlow.Application.Exceptions;
66

7-
public class ValidationException(IEnumerable<ValidationError> errors)
7+
public sealed class ValidationException(IEnumerable<ValidationError> errors)
88
: ApplicationException("One or more validation errors occurred", (int)HttpStatusCode.BadRequest)
99
{
1010
public IEnumerable<ValidationError> Errors => errors;

src/SnackFlow.Application/Features/Users/Commands/CreateUser/CreateUserCommandHandler.cs

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using SnackFlow.Application.Abstractions.Services;
55
using SnackFlow.Application.Common;
66
using SnackFlow.Application.DTOs;
7+
using SnackFlow.Application.Exceptions;
78
using SnackFlow.Domain.Constants;
89
using SnackFlow.Domain.Entities;
910
using SnackFlow.Domain.Repositories;
@@ -18,20 +19,19 @@ internal sealed class CreateUserCommandHandler(
1819
ILogger<CreateUserCommandHandler> logger)
1920
: ICommandHandler<CreateUserCommand, CreateUserCommandResponse>
2021
{
21-
public async ValueTask<Result<CreateUserCommandResponse>> Handle(CreateUserCommand command, CancellationToken cancellationToken)
22+
public async ValueTask<Result<CreateUserCommandResponse>> Handle(CreateUserCommand command,
23+
CancellationToken cancellationToken)
2224
{
2325
using var transaction = new TransactionScope(
2426
TransactionScopeOption.Required,
25-
new TransactionOptions
26-
{
27-
IsolationLevel = IsolationLevel.ReadCommitted,
28-
Timeout = TimeSpan.FromMinutes(1)
29-
},
27+
new TransactionOptions { IsolationLevel = IsolationLevel.ReadCommitted, Timeout = TimeSpan.FromMinutes(1) },
3028
TransactionScopeAsyncFlowOption.Enabled
3129
);
3230

3331
try
3432
{
33+
await VerifyIfUserExists(command);
34+
3535
var domainUser = User.Create(
3636
fullName: command.FullName,
3737
taxId: command.TaxId,
@@ -48,21 +48,49 @@ public async ValueTask<Result<CreateUserCommandResponse>> Handle(CreateUserComma
4848
PhoneNumber = Phone.Create(command.PhoneNumber).Value,
4949
UserDomainId = domainUser.Id
5050
};
51-
51+
5252
await unitOfWork.Users.CreateAsync(domainUser, cancellationToken);
5353
await unitOfWork.SaveChangesAsync(cancellationToken);
5454
await authService.CreateAsync(applicationUser, cancellationToken);
5555
transaction.Complete();
56-
56+
5757
return new CreateUserCommandResponse(
5858
command.UserName,
5959
command.Email
6060
);
6161
}
62+
catch (ConflictException)
63+
{
64+
throw;
65+
}
6266
catch (Exception ex)
6367
{
6468
logger.LogError(ex, ErrorMessage.Exception.Unexpected(ex.GetType().Name, ex.Message));
6569
throw;
6670
}
6771
}
72+
73+
private async Task VerifyIfUserExists(CreateUserCommand command)
74+
{
75+
Task<UserDetailsDTO?>[] userTasks =
76+
[
77+
authService.FindByEmailAsync(command.Email),
78+
authService.FindByUserNameAsync(command.UserName),
79+
authService.FindByPhoneAsync(command.PhoneNumber)
80+
];
81+
82+
var results = await Task.WhenAll(userTasks);
83+
84+
if (results[0] is not null)
85+
throw new ConflictException(ErrorMessage.Conflict.EmailAlreadyExists);
86+
87+
if (results[1] is not null)
88+
throw new ConflictException(ErrorMessage.Conflict.UserNameAlreadyExists);
89+
90+
if (results[2] is not null)
91+
throw new ConflictException(ErrorMessage.Conflict.PhoneAlreadyExists);
92+
93+
if (await unitOfWork.Users.ExistsAsync(x => x.TaxId.Value == command.TaxId))
94+
throw new ConflictException(ErrorMessage.Conflict.TaxIdAlreadyExists);
95+
}
6896
}

src/SnackFlow.Domain/Constants/ErrorMessage.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ public static class Conflict
8484
public const string PhoneAlreadyExists = "Telefone já cadastrado no sistema";
8585
public const string TaxIdAlreadyExists = "CPF/CNPJ já cadastrado no sistema";
8686
public const string CorporateNameAlreadyExists = "Nome da empresa já cadastrado no sistema";
87+
public const string UserNameAlreadyExists = "Nome de usuário já cadastrado no sistema";
88+
public const string FullNameAlreadyExists = "Nome compleco já cadastrado no sistema";
8789
}
8890

8991
/// <summary>

src/SnackFlow.Infrastructure/Persistence/Mappings/Identity/ApplicationRoleMap.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ public sealed class ApplicationRoleMap : IEntityTypeConfiguration<ApplicationRol
99
public void Configure(EntityTypeBuilder<ApplicationRole> builder)
1010
{
1111
builder.ToTable("aspnet_role");
12+
13+
builder
14+
.HasKey(u => u.Id)
15+
.HasName("pk_aspnet_role_id");
1216

1317
builder
1418
.Property(r => r.Id)

0 commit comments

Comments
 (0)