using ZB.MOM.WW.ScadaBridge.Commons.Types.Kpi; namespace ZB.MOM.WW.ScadaBridge.CentralUI.Services; /// /// CentralUI facade over /// /// ("KPI History & Trends"). The reusable trend chart talks to this /// service rather than the repository directly so tests can substitute a fake /// without spinning up EF Core, and so the bucketing / downsampling step lives in /// one place rather than being re-implemented per page. /// /// /// The query path fetches the raw series for one (source, metric, scope, scopeKey) /// tuple over [fromUtc, toUtc] and reduces it with /// to at most maxPoints points. Mirroring /// , the production implementation opens its own /// DI scope per call so a chart's auto-load never contends with the circuit-scoped /// ScadaBridgeDbContext; a second (test-seam) constructor injects the /// repository directly. /// public interface IKpiHistoryQueryService { /// /// Returns the bucketed series for one /// (, , , /// ) tuple over [, /// ], reduced to at most /// points (defaulting to /// KpiHistoryOptions.DefaultMaxSeriesPoints when null). /// /// /// The window must be non-degenerate ( strictly after /// ) and the effective max must be at least 2 — the /// page layer guarantees both; this service passes them straight through to /// , which throws /// on violation. /// /// Source identifier — a value from KpiSources. /// Metric name from the source's catalog. /// Scope discriminator — a value from KpiScopes. /// Scope qualifier (site id / node name); null for the Global scope. /// Inclusive lower bound of the time window (UTC). /// Inclusive upper bound of the time window (UTC); must be after . /// Optional ceiling on returned points; defaults to the configured default when null. /// Cancellation token. /// A task resolving to the bucketed series in ascending bucket-start order. Task> GetSeriesAsync( string source, string metric, string scope, string? scopeKey, DateTime fromUtc, DateTime toUtc, int? maxPoints = null, CancellationToken cancellationToken = default); }