Update Component-KpiHistory.md with the KpiRollupHourly schema, the third recorder rollup tick + one-shot backfill, dual raw/rollup purge retention, raw-vs-rollup query routing by RollupThresholdHours, per-metric gauge-vs-rate aggregation (KpiMetricAggregationCatalog), the four new options + bounds, and 30d/90d trend windows. Append a Delivered-2026-07-10 note to the m6 design plan, move register row #22 from Deferred to Resolved, and note rollups in the CLAUDE.md KPI History bullet. Docs-only; no code changed. Claude-Session: https://claude.ai/code/session_01MtdgwpEeCUn6cUA5f1LMPj
This commit is contained in:
@@ -212,7 +212,7 @@ Other peers in the `scadaproj` family (see `scadaproj/CLAUDE.md` for details): `
|
||||
- Stuck = `Pending`/`Retrying` older than a configurable age threshold (default 10 min) — display-only (KPI count + row badge), no escalation/alerting.
|
||||
- Headline KPI tiles surface on the Health dashboard; a new Central UI Notification Outbox page offers a queryable list with Retry/Discard actions on parked notifications.
|
||||
- Site Call Audit KPIs are central-computed point-in-time from the `SiteCalls` table (global + per-site), mirroring the Notification Outbox KPI shape; tiles surface on the Health dashboard alongside a queryable Central UI Site Calls page with Retry/Discard on parked rows.
|
||||
- KPI History & Trends (#26, M6): a reusable central KPI-history backbone — supersedes the prior "point-in-time only, no time-series store" stance — backed by a tall/EAV `KpiSample` table in central MS SQL (no new infra). A `KpiHistoryRecorderActor` cluster singleton (`kpi-history-recorder`, **not readiness-gated**, best-effort with per-source isolation) samples every minute by enumerating DI-registered `IKpiSampleSource`s (each lives with its owner, registered via `TryAddEnumerable`, reusing existing KPI/aggregator reads); daily purge after `RetentionDays` (default 90). Querying is `IKpiHistoryRepository.GetRawSeriesAsync` → `KpiSeriesBucketer` (last-value-per-bucket) → scoped dual-ctor `KpiHistoryQueryService` → a reusable **custom-SVG** `KpiTrendChart` (no third-party charting lib). Trends ship on four surfaces: Notification Outbox, Site Calls, Audit Log pages + a per-site Health-dashboard panel. `KpiHistoryOptions` (`ScadaBridge:KpiHistory`): SampleInterval 60s, RetentionDays 90, PurgeInterval 1d, DefaultMaxSeriesPoints 200; validated. M6's T9 and T10 were originally deferred. **T9/T10 delivered 2026-06-19** as an SMS (Twilio) adapter — Teams was evaluated and dropped (outbound-only backends cannot send 1:1 chat bodies via Graph without a Bot Framework inbound endpoint; SMS is inherently per-person and outbound-only). `NotificationType.Sms` added; `SmsNotificationDeliveryAdapter` (Twilio REST, no SDK) registered alongside Email; Central UI Type selector (adapter-gated) + SMS recipient input; CLI `--type sms --phones` on list create/update; `notification sms list|update` commands.
|
||||
- KPI History & Trends (#26, M6): a reusable central KPI-history backbone — supersedes the prior "point-in-time only, no time-series store" stance — backed by a tall/EAV `KpiSample` table in central MS SQL (no new infra). A `KpiHistoryRecorderActor` cluster singleton (`kpi-history-recorder`, **not readiness-gated**, best-effort with per-source isolation) samples every minute by enumerating DI-registered `IKpiSampleSource`s (each lives with its owner, registered via `TryAddEnumerable`, reusing existing KPI/aggregator reads); daily purge after `RetentionDays` (default 90). Querying is `IKpiHistoryRepository.GetRawSeriesAsync` → `KpiSeriesBucketer` (last-value-per-bucket) → scoped dual-ctor `KpiHistoryQueryService` → a reusable **custom-SVG** `KpiTrendChart` (no third-party charting lib). Trends ship on four surfaces: Notification Outbox, Site Calls, Audit Log pages + a per-site Health-dashboard panel. `KpiHistoryOptions` (`ScadaBridge:KpiHistory`): SampleInterval 60s, RetentionDays 90, PurgeInterval 1d, DefaultMaxSeriesPoints 200; validated. **Hourly rollups shipped 2026-07-10 (deferred #22):** a second `KpiRollupHourly` table folded by a third recorder tick (`kpi-rollup`, `RollupInterval` 1h, re-folds `RollupLookbackHours` window via idempotent failover-self-healing upsert + one-shot backfill on start), per-metric gauge-vs-rate fold (`KpiMetricAggregationCatalog`), and raw-vs-rollup query routing by `RollupThresholdHours` (168h) unblock long-range **30d/90d** trend windows (rollups retained `RollupRetentionDays` 365 ≥ raw 90, dual daily purge). M6's T9 and T10 were originally deferred. **T9/T10 delivered 2026-06-19** as an SMS (Twilio) adapter — Teams was evaluated and dropped (outbound-only backends cannot send 1:1 chat bodies via Graph without a Bot Framework inbound endpoint; SMS is inherently per-person and outbound-only). `NotificationType.Sms` added; `SmsNotificationDeliveryAdapter` (Twilio REST, no SDK) registered alongside Email; Central UI Type selector (adapter-gated) + SMS recipient input; CLI `--type sms --phones` on list create/update; `notification sms list|update` commands.
|
||||
|
||||
### Code Organization
|
||||
- Entity classes are persistence-ignorant POCOs in Commons; EF mappings in Configuration Database.
|
||||
|
||||
Reference in New Issue
Block a user