feat(udt-001): infrastructure (Dapper, BCrypt, JWT RS256, dispatcher)

This commit is contained in:
2026-04-13 21:36:02 -03:00
parent 8c26cd3ac5
commit ca57ce33b5
9 changed files with 347 additions and 0 deletions

View File

@@ -0,0 +1,60 @@
using Dapper;
using SIGCM2.Application.Abstractions.Persistence;
using SIGCM2.Domain.Entities;
namespace SIGCM2.Infrastructure.Persistence;
public sealed class UsuarioRepository : IUsuarioRepository
{
private readonly SqlConnectionFactory _connectionFactory;
public UsuarioRepository(SqlConnectionFactory connectionFactory)
{
_connectionFactory = connectionFactory;
}
public async Task<Usuario?> GetByUsernameAsync(string username)
{
const string sql = """
SELECT
Id, Username, PasswordHash,
Nombre, Apellido, Email,
Rol, PermisosJson, Activo
FROM dbo.Usuario
WHERE Username = @Username
AND Activo = 1
""";
await using var connection = _connectionFactory.CreateConnection();
await connection.OpenAsync();
var row = await connection.QuerySingleOrDefaultAsync<UsuarioRow>(sql, new { Username = username });
if (row is null) return null;
return new Usuario(
id: row.Id,
username: row.Username,
passwordHash: row.PasswordHash,
nombre: row.Nombre,
apellido: row.Apellido,
email: row.Email,
rol: row.Rol,
permisosJson: row.PermisosJson,
activo: row.Activo
);
}
// Flat DTO for Dapper mapping (avoids polluting domain entity with Dapper attributes)
private sealed record UsuarioRow(
int Id,
string Username,
string PasswordHash,
string Nombre,
string Apellido,
string? Email,
string Rol,
string PermisosJson,
bool Activo
);
}