Joseph Doherty
1a7e735149
feat(centralui): Secured Writes page — operator submit + verifier queue + history (T14b)
2026-06-18 03:34:08 -04:00
Joseph Doherty
b08bfae329
feat(audit): SecuredWrite audit kinds + best-effort per-lifecycle central direct-write; guard approve Decode (T14b)
2026-06-18 03:17:56 -04:00
Joseph Doherty
c8d9303031
feat(siteruntime): per-node CertStore actor + trust broadcast to both site nodes (T17)
2026-06-18 03:13:48 -04:00
Joseph Doherty
303385fd98
feat(centralui): Verify-endpoint button + result/cert panel (T17)
2026-06-18 03:12:11 -04:00
Joseph Doherty
45a5a92455
fix(centralui): NodeBrowserDialog — reset load/expand spinner on error + clear stale failure on blank search (T15)
2026-06-18 03:05:23 -04:00
Joseph Doherty
733c7bf66c
feat(dcl): OPC UA verify-endpoint probe with untrusted-cert capture (T17)
2026-06-18 03:00:55 -04:00
Joseph Doherty
90abb4b8e2
feat(centralui): NodeBrowserDialog search + load-more + type column (T15/T16)
2026-06-18 03:00:16 -04:00
Joseph Doherty
1f7bb7ace3
feat(mgmt): secured-write approve relays to site MxGateway write with CAS race guard (T14b)
2026-06-18 02:59:43 -04:00
Joseph Doherty
74dd26eebd
feat: OPC UA address-space search plumbing — actor + comm + BrowseService (T15)
2026-06-18 02:51:57 -04:00
Joseph Doherty
c00c8241b3
feat(dcl): bounded recursive OPC UA address-space search adapter (T15)
2026-06-18 02:45:01 -04:00
Joseph Doherty
9ec2450ad5
feat: thread BrowseNext continuation token through actor + BrowseService (T15)
2026-06-18 02:43:25 -04:00
Joseph Doherty
d5e7e897c0
feat(centralui): InstanceConfigure CSV bulk override import (T16)
2026-06-18 02:30:33 -04:00
Joseph Doherty
25c9240415
feat(mgmt): secured-write submit/reject/list handlers + Operator/Verifier gating (T14b)
2026-06-18 02:29:29 -04:00
Joseph Doherty
586d54359c
feat(cli): instance import-overrides --file (T16)
2026-06-18 02:27:40 -04:00
Joseph Doherty
2cfe0de927
feat(dcl): BrowseNext continuation paging + StubOpcUaClient canned browse (T15)
2026-06-18 02:21:59 -04:00
Joseph Doherty
3c9122bc07
feat(centralui): operator Alarm Summary page + per-instance snapshot fan-out (T13)
2026-06-18 02:21:41 -04:00
Joseph Doherty
6a6f8949b9
fix(commons): OverrideCsvParser — preserve literal mid-field quotes, error on unterminated quoted field (T16 CSV)
2026-06-18 02:13:10 -04:00
Joseph Doherty
c799f41d53
feat(db): PendingSecuredWrite entity + migration + repository (T14b)
2026-06-18 02:09:31 -04:00
Joseph Doherty
a0ce8b6c44
feat(security): add Operator + Verifier roles + policies + LDAP mapping options (T14a)
2026-06-18 02:07:01 -04:00
Joseph Doherty
5fd77c7155
feat(dcl): surface OPC UA DataType/ValueRank/Writable on BrowseNode (T16 type-info)
2026-06-18 02:02:23 -04:00
Joseph Doherty
bf1f2f6892
feat(centralui): extract AlarmStateBadges shared component from DebugView (T13)
2026-06-18 02:02:09 -04:00
Joseph Doherty
77a31ba994
feat(commons): quote-aware OverrideCsvParser (T16 CSV)
2026-06-18 02:01:38 -04:00
Joseph Doherty
a87bf8a459
docs(m7): implementation plan + task graph — 22 tasks across waves A-E (T13-T17)
2026-06-18 01:57:18 -04:00
Joseph Doherty
254e0e729f
docs(m7): approved design — OPC UA / MxGateway UX (T13-T17)
...
Full-M7 scope: operator Alarm Summary (per-instance live snapshots),
MxGateway secured writes (Operator+Verifier roles + PendingSecuredWrite +
central relay), OPC UA BrowseNext paging + bounded recursive search,
type-info surfacing + attribute-override CSV import, Verify-endpoint button +
site-local cert trust (broadcast to both nodes). Builds on the merged
opcua-tag-browser + mxgw-supervisory-write foundations already in main.
2026-06-18 01:44:40 -04:00
Joseph Doherty
241a792e7b
docs(kpi): K17 — #26 KpiHistory component doc + README/CLAUDE + cross-component interactions + completion-design update
2026-06-17 20:52:12 -04:00
Joseph Doherty
3f1f4ed7c6
test(kpi): K17 — Playwright KPI trend-chart spec (tolerant, SkippableFact)
2026-06-17 20:50:23 -04:00
Joseph Doherty
eb4bce3e49
refactor(kpi): K13/K15 trend review fixups — per-metric isolation, disable-during-load + logging, loading-flag finally, test coverage
2026-06-17 20:44:34 -04:00
Joseph Doherty
7d7c6cbb05
feat(kpi): K16 — Health dashboard per-site trend panel
2026-06-17 20:36:09 -04:00
Joseph Doherty
3595a41349
feat(kpi): K15 — Audit Log trend charts
2026-06-17 20:30:38 -04:00
Joseph Doherty
4a88355098
feat(kpi): K14 — Site Calls trend charts
2026-06-17 20:30:36 -04:00
Joseph Doherty
0dc819f191
feat(kpi): K13 — Notification Outbox trend charts (T11 first consumer)
2026-06-17 20:29:30 -04:00
Joseph Doherty
f0177d5073
feat(kpi): K11 — KpiHistoryQueryService (scoped read + bucketing)
2026-06-17 20:21:17 -04:00
Joseph Doherty
e14433cd64
feat(kpi): K5 — Host central wiring + KpiHistoryRecorder cluster singleton + appsettings (not readiness-gated)
...
Wire the M6 KPI History recorder into the central composition path:
- Program.cs: call services.AddKpiHistory(configuration) on the central-only
branch alongside AddNotificationOutbox/AddAuditLog/AddSiteCallAudit.
- AkkaHostedService.cs: register KpiHistoryRecorderActor as a central,
non-role-scoped ClusterSingletonManager + ClusterSingletonProxy + a
PhaseClusterLeave CoordinatedShutdown graceful-stop drain (singleton name
'kpi-history-recorder'), copied/adapted from the audit-log-purge block.
- appsettings.Central.json (Host + docker + docker-env2 central nodes): add a
ScadaBridge:KpiHistory section (SampleInterval 00:01:00, RetentionDays 90,
PurgeInterval 1.00:00:00, DefaultMaxSeriesPoints 200).
KPI history is observability/best-effort and MUST NOT gate readiness: the
recorder is deliberately NOT added to RequiredSingletonsHealthCheck or any
other readiness gate.
2026-06-17 20:20:34 -04:00
Joseph Doherty
601cc6f594
feat(kpi): K9 — SiteHealth sample source (per-site, from aggregator)
2026-06-17 20:20:18 -04:00
Joseph Doherty
cb2a516187
refactor(kpi): K4/K10/K12 review fixups — test data-race + faulted-tick liveness, dead-branch/unused removal, NaN-guard assertions, value clamp + doc
2026-06-17 20:15:47 -04:00
Joseph Doherty
5613a5efb7
feat(kpi): K12 — reusable KpiTrendChart SVG component
2026-06-17 20:06:31 -04:00
Joseph Doherty
9c2e7ab4cb
feat(kpi): K4 — KpiHistoryRecorderActor (best-effort sampling + daily purge)
2026-06-17 20:06:09 -04:00
Joseph Doherty
76f5ed72e4
feat(kpi): K10 — KpiSeriesBucketer last-per-bucket downsampler
2026-06-17 20:04:51 -04:00
Joseph Doherty
e6c15250ce
refactor(kpi): K2/K6/K7 review fixups — empty-batch guard + sealed repo + uniform TryAddEnumerable + KPI-age doc fidelity + coverage
2026-06-17 20:00:43 -04:00
Joseph Doherty
456e61dff3
feat(kpi): K7 — SiteCallAudit sample source
2026-06-17 19:53:49 -04:00
Joseph Doherty
6f6157ce89
feat(kpi): K8 — AuditLog sample source
2026-06-17 19:53:41 -04:00
Joseph Doherty
0d6c026dff
feat(kpi): K6 — NotificationOutbox sample source (global/site/node)
2026-06-17 19:53:39 -04:00
Joseph Doherty
9ffa34d3e7
feat(kpi): K3 — KpiHistory project + options/validator + AddKpiHistory
2026-06-17 19:48:59 -04:00
Joseph Doherty
cabc557629
feat(kpi): K2 — KpiSample EF mapping + KpiHistoryRepository + AddKpiSampleTable migration
2026-06-17 19:44:51 -04:00
Joseph Doherty
460777bffa
feat(kpi): K1 — KpiSample + IKpiSampleSource + IKpiHistoryRepository contracts (Commons)
2026-06-17 19:40:17 -04:00
Joseph Doherty
4c6ae9da0e
docs(m6): KPI History tasks.json (K1-K17 with blockedBy graph)
2026-06-17 19:32:58 -04:00
Joseph Doherty
1809664bcb
docs(m6): KPI History & Trends implementation plan (K1-K17, bite-sized tasks + execution waves)
2026-06-17 19:32:58 -04:00
Joseph Doherty
6084e56c9f
docs(m6): KPI History & Trends design — reusable tall/EAV KPI-history backbone + trend charts for all sources; T9/T10 (Teams) deferred to next major version
2026-06-17 19:32:58 -04:00
Joseph Doherty
59e094ada3
test(playwright): DebugViewTree — tolerate empty alarm forest (TreeView renders EmptyContent, not role=tree, when no alarms)
2026-06-17 16:08:37 -04:00
Joseph Doherty
e7660134f2
fix(communication): drop IsConfiguredPlaceholder rows in StreamRelayActor before gRPC pack
...
Placeholder AlarmStateChanged rows are a DebugView snapshot-only concept emitted
by InstanceActor.BuildAlarmStatesSnapshot; they are never a real alarm transition.
Their timestamp may be DateTimeOffset.MinValue (the Protobuf Timestamp lower boundary),
which can throw when packed via Timestamp.FromDateTimeOffset.
Added early-return guard at the top of HandleAlarmStateChanged before any timestamp
pack or channel write. Updated the existing NativeBindingLinkage round-trip test to
use a real (non-placeholder) native alarm; added DropsAlarmStateChanged_WhenIsConfiguredPlaceholder
to assert placeholders are silently dropped (15/15 pass).
2026-06-17 15:44:28 -04:00