using LiteCqrs; using Microsoft.EntityFrameworkCore; using TeleWave.Application.Common.Interfaces; using TeleWave.Domain.Media; namespace TeleWave.Application.Media.ManualInbox; public sealed class ListManualInboxQueryHandler(IAppDbContext dbContext, IMediaStorage storage) : IQueryHandler { /// Потолок выдачи: каталог наполняет человек, и он может оказаться огромным. private const int MaxFiles = 500; public async Task Handle( ListManualInboxQuery query, CancellationToken cancellationToken ) { // Просим на один больше лимита — так видно, что каталог не поместился целиком. var files = storage.ListManualInbox(MaxFiles + 1); var truncated = files.Count > MaxFiles; var page = truncated ? files.Take(MaxFiles).ToList() : files; if (page.Count == 0) return new ManualInboxListDto([], false); // Дедуп — по имени файла, тем же правилом, что и при регистрации ассета. var names = page.Select(f => f.Name).Distinct().ToList(); var taken = await dbContext .MediaAssets.AsNoTracking() .Where(a => names.Contains(a.OriginalFileName) && a.Status != MediaAssetStatus.Failed) .Select(a => a.OriginalFileName) .ToListAsync(cancellationToken); var takenSet = taken.ToHashSet(StringComparer.Ordinal); return new ManualInboxListDto( page.Select(f => new ManualInboxFileDto( f.RelativePath, f.Name, f.SizeBytes, MediaFormats.IsAllowed(f.Name), takenSet.Contains(f.Name) )) .ToList(), truncated ); } }