using Dapper; using SIGCM2.Application.Abstractions.Persistence; using SIGCM2.Domain.Entities; namespace SIGCM2.Infrastructure.Persistence; public sealed class RolRepository : IRolRepository { private readonly SqlConnectionFactory _connectionFactory; public RolRepository(SqlConnectionFactory connectionFactory) { _connectionFactory = connectionFactory; } public async Task> ListAsync(CancellationToken ct = default) { const string sql = """ SELECT Id, Codigo, Nombre, Descripcion, Activo, FechaCreacion, FechaModificacion FROM dbo.Rol ORDER BY Id """; await using var connection = _connectionFactory.CreateConnection(); await connection.OpenAsync(ct); var rows = await connection.QueryAsync(sql); return rows.Select(MapRow).ToList(); } public async Task GetByCodigoAsync(string codigo, CancellationToken ct = default) { const string sql = """ SELECT Id, Codigo, Nombre, Descripcion, Activo, FechaCreacion, FechaModificacion FROM dbo.Rol WHERE Codigo = @Codigo """; await using var connection = _connectionFactory.CreateConnection(); await connection.OpenAsync(ct); var row = await connection.QuerySingleOrDefaultAsync(sql, new { Codigo = codigo }); return row is null ? null : MapRow(row); } public async Task ExistsActiveByCodigoAsync(string codigo, CancellationToken ct = default) { const string sql = """ SELECT COUNT(1) FROM dbo.Rol WHERE Codigo = @Codigo AND Activo = 1 """; await using var connection = _connectionFactory.CreateConnection(); await connection.OpenAsync(ct); var count = await connection.ExecuteScalarAsync(sql, new { Codigo = codigo }); return count > 0; } public async Task AddAsync(Rol rol, CancellationToken ct = default) { // DF handles: Activo (1), FechaCreacion (SYSUTCDATETIME()). const string sql = """ INSERT INTO dbo.Rol (Codigo, Nombre, Descripcion) OUTPUT INSERTED.Id VALUES (@Codigo, @Nombre, @Descripcion) """; await using var connection = _connectionFactory.CreateConnection(); await connection.OpenAsync(ct); return await connection.ExecuteScalarAsync(sql, new { rol.Codigo, rol.Nombre, rol.Descripcion, }); } public async Task UpdateAsync(string codigo, string nombre, string? descripcion, bool activo, CancellationToken ct = default) { const string sql = """ UPDATE dbo.Rol SET Nombre = @Nombre, Descripcion = @Descripcion, Activo = @Activo, FechaModificacion = SYSUTCDATETIME() WHERE Codigo = @Codigo; SELECT @@ROWCOUNT; """; await using var connection = _connectionFactory.CreateConnection(); await connection.OpenAsync(ct); var rows = await connection.ExecuteScalarAsync(sql, new { Codigo = codigo, Nombre = nombre, Descripcion = descripcion, Activo = activo }); return rows > 0; } public async Task HasActiveUsuariosAsync(string codigo, CancellationToken ct = default) { const string sql = """ SELECT COUNT(1) FROM dbo.Usuario WHERE Rol = @Codigo AND Activo = 1 """; await using var connection = _connectionFactory.CreateConnection(); await connection.OpenAsync(ct); var count = await connection.ExecuteScalarAsync(sql, new { Codigo = codigo }); return count > 0; } private static Rol MapRow(RolRow row) => new( id: row.Id, codigo: row.Codigo, nombre: row.Nombre, descripcion: row.Descripcion, activo: row.Activo, fechaCreacion: row.FechaCreacion, fechaModificacion: row.FechaModificacion); private sealed record RolRow( int Id, string Codigo, string Nombre, string? Descripcion, bool Activo, DateTime FechaCreacion, DateTime? FechaModificacion); }