using PostFundManagement.Domain; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; using PostFundManagement.Infrastructure.Database; namespace PostFundManagement.Application.Services.Shared; public sealed class AuditService(IDbContextFactory contextFactory, ITenantContextService tenantContextService) : IService { public async Task> GetAuditLogsAsync(CancellationToken cancellationToken = default) => await GetAuditLogsAsync(new Pagination { Page = 1, PageSize = 500, Index = 1 }, cancellationToken); public async Task> GetAuditLogsAsync(Pagination pagination, CancellationToken cancellationToken = default) => await Result.Try((Func>>)(async () => { await using var context = await contextFactory.CreateDbContextAsync(cancellationToken); var query = context.AuditLogs.AsQueryable(); if (!tenantContextService.IsAdmin) { var currentTenantId = tenantContextService.TenantId > 0 ? tenantContextService.TenantId : 1L; query = query.Where(o => o.TenantId == currentTenantId); } var logs = await query .OrderByDescending(o => o.Id) .Skip((pagination.Page - 1) * pagination.PageSize) .Take(pagination.PageSize) .ToListAsync(cancellationToken); return Result.Ok(logs.Select(p => p.Map()).ToArray()); })); public async Task LogActionAsync( string entityId, string entityName, string action, string[] changes, Guid performedBy, string? error = null, long? tenantId = null, CancellationToken cancellationToken = default) => await Result.Try((Func>)(async () => { await using var context = await contextFactory.CreateDbContextAsync(cancellationToken); var resolvedTenantId = (tenantId.HasValue && tenantId.Value > 0) ? tenantId.Value : (tenantContextService.TenantId > 0 ? tenantContextService.TenantId : 1L); context.Add(new Domain.Entities.AuditLog { EntityId = entityId, Action = action, Changes = changes, EntityName = entityName, PerformedBy = performedBy, Timestamp = DateTime.UtcNow, TenantId = resolvedTenantId, Error = error, }); return Result.FailIf(await context.SaveChangesAsync(cancellationToken) <= 0, CreateError.New); })); }