< Summary

Information
Class: FAU.Logica.Services.AuditoriaService
Assembly: FAU.Logica
File(s): /home/runner/work/Sistema.Liquidacion.BE/Sistema.Liquidacion.BE/FAU.Logica/Services/AuditoriaService.cs
Line coverage
81%
Covered lines: 31
Uncovered lines: 7
Coverable lines: 38
Total lines: 99
Line coverage: 81.5%
Branch coverage
40%
Covered branches: 4
Total branches: 10
Branch coverage: 40%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)50%44100%
GetPagedAsync(...)100%11100%
LogAuditoriaAsync()100%210%
LogAuditoriaAsync()33.33%6688.88%
LogAuditoria(...)100%11100%

File(s)

/home/runner/work/Sistema.Liquidacion.BE/Sistema.Liquidacion.BE/FAU.Logica/Services/AuditoriaService.cs

#LineLine coverage
 1using System.Text.Json;
 2using FAU.DataAccess.Repositories;
 3using FAU.Entidades;
 4using Serilog;
 5
 6namespace FAU.Logica.Services;
 7
 8public class AuditoriaService : IAuditoriaService
 9{
 10    private readonly IAuditoriaRepository _auditoriaRepository;
 11    private readonly IAuditoriaCatalogoResolver _catalogoResolver;
 12
 213    public AuditoriaService(IAuditoriaRepository auditoriaRepository, IAuditoriaCatalogoResolver catalogoResolver)
 14    {
 215        _auditoriaRepository = auditoriaRepository ?? throw new ArgumentNullException(nameof(auditoriaRepository));
 216        _catalogoResolver = catalogoResolver ?? throw new ArgumentNullException(nameof(catalogoResolver));
 217    }
 18
 19    public Task<(IEnumerable<BitacoraAuditoria> Items, int TotalCount)> GetPagedAsync(
 20        int page,
 21        int pageSize,
 22        string? contexto = null,
 23        string? accion = null,
 24        string? usuario = null,
 25        DateTime? desde = null,
 26        DateTime? hasta = null)
 27    {
 128        return _auditoriaRepository.GetPagedAsync(page, pageSize, contexto, accion, usuario, desde, hasta);
 29    }
 30
 31    /// <summary>
 32    /// Overload recomendado: recibe enums (centralizado) pero resuelve IDs reales por nombre en BD.
 33    /// Esto evita romper auditor�a cuando los IDs de cat�logo est�n corridos entre ambientes.
 34    /// </summary>
 35    public async Task LogAuditoriaAsync(
 36        long usuarioId,
 37        AccionEnum accion,
 38        ContextoEnum contexto,
 39        string? host = null,
 40        string? entidad = null,
 41        long? entidadId = null,
 42        object? detalle = null)
 43    {
 044        var accionId = await _catalogoResolver.GetAccionIdAsync(accion.ToString());
 045        var contextoId = await _catalogoResolver.GetContextoIdAsync(contexto.ToString());
 46
 047        await LogAuditoriaAsync(usuarioId, (int)accionId, (int)contextoId, host, entidad, entidadId, detalle);
 048    }
 49
 50    public async Task LogAuditoriaAsync(
 51        long usuarioId,
 52        int accionId,
 53        int contextoId,
 54        string? host = null,
 55        string? entidad = null,
 56        long? entidadId = null,
 57        object? detalle = null)
 58    {
 159        var hostFinal = string.IsNullOrWhiteSpace(host) ? "Desconocida" : host;
 60
 161        string? detalleJson = null;
 162        if (detalle != null)
 63        {
 064            detalleJson = detalle is string s
 065                ? s
 066                : JsonSerializer.Serialize(detalle, new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.
 67        }
 68
 69        // 1) Persistir en DB (fuente de verdad)
 170        await _auditoriaRepository.CreateAsync(new BitacoraAuditoria
 171        {
 172            UsuarioId = usuarioId,
 173            AccionId = accionId,
 174            ContextoId = contextoId,
 175            Host = hostFinal,
 176            Fecha = DateTime.UtcNow,
 177            Entidad = entidad,
 178            EntidadId = entidadId,
 179            Detalle = detalleJson
 180        });
 81
 82        // 2) Log estructurado (�til para troubleshooting)
 183        Log.Logger
 184            .ForContext("usuario_id", usuarioId)
 185            .ForContext("accion_id", accionId)
 186            .ForContext("contexto_id", contextoId)
 187            .ForContext("host", hostFinal)
 188            .ForContext("entidad", entidad)
 189            .ForContext("entidad_id", entidadId)
 190            .ForContext("detalle", detalleJson)
 191            .Information("Auditoria {usuario_id} {accion_id} {contexto_id} {host}", usuarioId, accionId, contextoId, hos
 192    }
 93
 94    public void LogAuditoria(long usuarioId, int accionId, int contextoId, string host)
 95    {
 96        // Mantener firma anterior: log + persistencia best-effort.
 197        _ = LogAuditoriaAsync(usuarioId, accionId, contextoId, host);
 198    }
 99}