using QuantEngine.Application.Interfaces; using QuantEngine.Core.Interfaces; namespace QuantEngine.Application.Services; public sealed class CollectionReadModelService : ICollectionReadModelService { private readonly ICollectionReadRepository _repository; public CollectionReadModelService(ICollectionReadRepository repository) { _repository = repository; } public Task GetDashboardStateAsync() => _repository.GetDashboardStateAsync(); public Task> GetRecentRunsAsync(int limit = 20) => _repository.GetRecentRunsAsync(NormalizeLimit(limit, 1, 200)); public Task> GetRunSnapshotsAsync(string runId) => _repository.GetRunSnapshotsAsync(RequireValue(runId, nameof(runId))); public Task> GetRunErrorsAsync(string runId, int limit = 50) => _repository.GetRunErrorsAsync(RequireValue(runId, nameof(runId)), NormalizeLimit(limit, 1, 200)); public Task> GetLatestSnapshotsForTickerAsync(string ticker, int limit = 10) => _repository.GetLatestSnapshotsForTickerAsync(RequireValue(ticker, nameof(ticker)), NormalizeLimit(limit, 1, 100)); public Task> GetPriceHistorySummaryAsync() => _repository.GetPriceHistorySummaryAsync(); private static string RequireValue(string value, string parameterName) { if (string.IsNullOrWhiteSpace(value)) { throw new ArgumentException("Value is required.", parameterName); } return value.Trim(); } private static int NormalizeLimit(int limit, int min, int max) => Math.Clamp(limit, min, max); }