using Microsoft.EntityFrameworkCore; using Tiku.Application.Assets; using Tiku.Application.Catalog; namespace Tiku.Infrastructure.Assets; internal sealed class AssetAuditQueryService(AssetManagementDependencies dependencies) : AssetManagementServiceBase(dependencies), IAssetAuditQueryService { public async Task> GetAccessEventsAsync( AssetManagementActor actor, AssetEventFilter filter, CancellationToken cancellationToken = default) { var query = contentAssetPersistence.ContentAssetAccessEvents.AsNoTracking() .Where(item => item.TenantId == actor.TenantId); if (filter.AssetId.HasValue) query = query.Where(item => item.AssetId == filter.AssetId.Value); if (filter.UserId.HasValue) query = query.Where(item => item.UserId == filter.UserId.Value); var items = await query .OrderByDescending(item => item.CreatedAt) .Take(ResolveLimit(filter.Limit)) .Select(item => new ContentAssetAccessEventItem( item.Id, item.AssetId, item.UserId, item.ActorRole, item.AccessType, item.Visibility, item.AssetType, item.StorageProvider, item.Disposition, item.ExpiresInSeconds, item.SignatureMode, item.Result, item.DenyCode, item.IpAddress, item.UserAgent, item.Metadata, item.CreatedAt)) .ToArrayAsync(cancellationToken); return new CatalogList(items); } public async Task> GetSecurityScanEventsAsync( AssetManagementActor actor, AssetEventFilter filter, CancellationToken cancellationToken = default) { var query = contentAssetPersistence.ContentAssetSecurityScanEvents.AsNoTracking() .Where(item => item.TenantId == actor.TenantId); if (filter.AssetId.HasValue) query = query.Where(item => item.AssetId == filter.AssetId.Value); var items = await query .OrderByDescending(item => item.CreatedAt) .Take(ResolveLimit(filter.Limit)) .Select(item => new ContentAssetSecurityScanEventItem( item.Id, item.AssetId, item.Provider, item.ScanStatus, item.RiskLevel, item.IssueCodes, item.Details, item.CreatedAt)) .ToArrayAsync(cancellationToken); return new CatalogList(items); } }