merge(r2): r2-plan04
This commit is contained in:
@@ -51,6 +51,14 @@ public partial class KpiTrendChart
|
||||
/// The series to plot, assumed ordered ascending by
|
||||
/// <see cref="KpiSeriesPoint.BucketStartUtc"/>. <c>null</c> or empty renders
|
||||
/// the unavailable placeholder rather than an empty chart.
|
||||
/// <para>
|
||||
/// The per-point value's meaning depends on the metric's
|
||||
/// <see cref="ZB.MOM.WW.ScadaBridge.Commons.Types.Kpi.KpiMetricAggregationCatalog"/>
|
||||
/// classification: a Rate-classified series carries <b>per-bucket totals</b> (the
|
||||
/// bucketer sums each bucket's deltas), while a Gauge series carries
|
||||
/// last-value-per-bucket readings. The chart is agnostic to which — it plots the
|
||||
/// supplied values verbatim (arch-review 04 round 2, R3).
|
||||
/// </para>
|
||||
/// </summary>
|
||||
[Parameter] public IReadOnlyList<KpiSeriesPoint>? Points { get; set; }
|
||||
|
||||
@@ -58,7 +66,10 @@ public partial class KpiTrendChart
|
||||
/// <c>data-test</c> slug. Required-ish; defaults to "Trend" if blank.</summary>
|
||||
[Parameter] public string Title { get; set; } = "Trend";
|
||||
|
||||
/// <summary>Optional unit suffix appended to value labels (e.g. "s").</summary>
|
||||
/// <summary>Optional unit suffix appended to value labels (e.g. "s"). For a
|
||||
/// Rate-classified metric the supplied text must state the per-bucket-total
|
||||
/// semantics (e.g. "delivered/bucket"), not a per-minute/per-interval reading,
|
||||
/// so the label matches the summed values in <see cref="Points"/> (R3).</summary>
|
||||
[Parameter] public string? Unit { get; set; }
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -76,12 +76,18 @@ public sealed class KpiHistoryQueryService : IKpiHistoryQueryService
|
||||
{
|
||||
var effectiveMax = maxPoints ?? _options.DefaultMaxSeriesPoints;
|
||||
|
||||
// Per-metric reduction intent: the same catalog that drives the hourly fold drives
|
||||
// the chart-time bucket reduction, so a Rate series is summed per bucket on BOTH the
|
||||
// raw-minute and hourly-rollup routes — one unit ("events per chart bucket") on both
|
||||
// sides of the RollupThresholdHours routing boundary (arch-review 04 round 2, R3).
|
||||
var aggregation = KpiMetricAggregationCatalog.Resolve(source, metric);
|
||||
|
||||
// Test-seam ctor: use the injected repository directly.
|
||||
if (_injectedRepository is not null)
|
||||
{
|
||||
var injectedSeries = await FetchSeriesAsync(
|
||||
_injectedRepository, source, metric, scope, scopeKey, fromUtc, toUtc, cancellationToken);
|
||||
return KpiSeriesBucketer.Bucket(injectedSeries, fromUtc, toUtc, effectiveMax);
|
||||
return KpiSeriesBucketer.Bucket(injectedSeries, fromUtc, toUtc, effectiveMax, aggregation);
|
||||
}
|
||||
|
||||
// Production: a fresh scope (and thus a fresh DbContext) per query so a
|
||||
@@ -90,7 +96,7 @@ public sealed class KpiHistoryQueryService : IKpiHistoryQueryService
|
||||
var repository = serviceScope.ServiceProvider.GetRequiredService<IKpiHistoryRepository>();
|
||||
var series = await FetchSeriesAsync(
|
||||
repository, source, metric, scope, scopeKey, fromUtc, toUtc, cancellationToken);
|
||||
return KpiSeriesBucketer.Bucket(series, fromUtc, toUtc, effectiveMax);
|
||||
return KpiSeriesBucketer.Bucket(series, fromUtc, toUtc, effectiveMax, aggregation);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -103,6 +109,13 @@ public sealed class KpiHistoryQueryService : IKpiHistoryQueryService
|
||||
/// the caller's <see cref="KpiSeriesBucketer.Bucket"/> step is agnostic to the source
|
||||
/// (a 90 d rollup can still exceed the point ceiling, so bucketing still applies).
|
||||
/// The boundary is strict: exactly <c>RollupThresholdHours</c> stays on the raw path.
|
||||
/// <para>
|
||||
/// The routing boundary no longer changes a Rate chart's magnitude: both paths reduce to
|
||||
/// per-bucket sums via the catalog-driven aggregation applied in
|
||||
/// <see cref="GetSeriesAsync"/>. A residual ≤~1.2× native-resolution difference exists only
|
||||
/// for an unbucketed just-over-threshold rollup series (plotted at native per-hour sums) vs.
|
||||
/// an at-threshold bucketed raw series — documented, not hidden (arch-review 04 round 2, R3).
|
||||
/// </para>
|
||||
/// </summary>
|
||||
private Task<IReadOnlyList<KpiSeriesPoint>> FetchSeriesAsync(
|
||||
IKpiHistoryRepository repository,
|
||||
|
||||
Reference in New Issue
Block a user