using System.Transactions; using SIGCM2.Application.Abstractions; using SIGCM2.Application.Abstractions.Persistence; using SIGCM2.Application.Audit; using SIGCM2.Application.Roles.Dtos; using SIGCM2.Domain.Exceptions; namespace SIGCM2.Application.Roles.Deactivate; public sealed class DeactivateRolCommandHandler : ICommandHandler { private readonly IRolRepository _repository; private readonly IAuditLogger _audit; public DeactivateRolCommandHandler(IRolRepository repository, IAuditLogger audit) { _repository = repository; _audit = audit; } public async Task Handle(DeactivateRolCommand command) { var existing = await _repository.GetByCodigoAsync(command.Codigo) ?? throw new RolNotFoundException(command.Codigo); // Guard: block soft-delete when active usuarios reference this rol. if (await _repository.HasActiveUsuariosAsync(command.Codigo)) throw new RolInUseException(command.Codigo); using (var tx = new TransactionScope( TransactionScopeOption.Required, new TransactionOptions { IsolationLevel = IsolationLevel.ReadCommitted }, TransactionScopeAsyncFlowOption.Enabled)) { var updated = await _repository.UpdateAsync( existing.Codigo, existing.Nombre, existing.Descripcion, activo: false); if (!updated) throw new RolNotFoundException(command.Codigo); await _audit.LogAsync( action: "rol.deactivate", targetType: "Rol", targetId: existing.Id.ToString()); tx.Complete(); } var rol = await _repository.GetByCodigoAsync(command.Codigo) ?? throw new RolNotFoundException(command.Codigo); return new RolDto(rol.Id, rol.Codigo, rol.Nombre, rol.Descripcion, rol.Activo, rol.FechaCreacion, rol.FechaModificacion); } }