Rewrites StatsRepository to be fully async and collapses the ~30 synchronous round-trips into a bounded set of aggregated queries: - Single grouped pass over non-deleted assets computes totals, storage, visibility breakdown, orphans, 7/30-day activity, and all data-completeness counts (missing metadata/thumbnail/preview/phash). - AssetsByType + StorageByType come from one GROUP BY on Type. - UsersByAccessLevel, TotalUsers, and users registered in 30 days come from one GROUP BY on AccessLevel. - MIME breakdown and resolution buckets are now GROUP BY'd in SQL; the resolution bucket key is a translatable CASE expression on the max dimension, so no more loading every asset's dimensions into memory. - AssetsWithNoAlbum / AssetsWithNoPerson use set-based NOT IN anti-joins over the Album.Assets navigation instead of per-row NOT EXISTS. - TopTags uses the Tag.Assets navigation (join table indexed on TagsId). - Drops IDisposable/Dispose() so the transient repo no longer disposes the shared scoped DbContext. - StatsController action is now async. StatsDto shape is unchanged, so the existing .http tests remain valid. Refs #173
15 lines
499 B
C#
15 lines
499 B
C#
using Butter.Dtos.Stats;
|
|
|
|
namespace Lactose.Repositories;
|
|
|
|
/// <summary>
|
|
/// Repository for gathering aggregate statistics from the database.
|
|
/// </summary>
|
|
public interface IStatsRepository {
|
|
/// <summary>
|
|
/// Gathers all aggregate statistics into a single DTO.
|
|
/// </summary>
|
|
/// <param name="cancellationToken">Cancellation token.</param>
|
|
/// <returns>A fully populated <see cref="StatsDto"/>.</returns>
|
|
Task<StatsDto> GetStatsAsync(CancellationToken cancellationToken);
|
|
} |