Commit Graph

19 Commits

Author SHA1 Message Date
Joseph Doherty
f80eea375c feat(commons): add Audit{Channel,Kind,Status,ForwardState} enums for #23 2026-05-20 09:55:13 -04:00
Joseph Doherty
67b86aa683 feat(notification-outbox): per-site KPI snapshot type + repository contract 2026-05-19 05:22:45 -04:00
Joseph Doherty
926ca902bd test(notification-outbox): fold notification enum tests into EnumTests convention 2026-05-19 00:47:23 -04:00
Joseph Doherty
f9b942bb94 feat(notification-outbox): add NotificationType and NotificationStatus enums 2026-05-19 00:45:05 -04:00
Joseph Doherty
7da303d7bb fix(configuration-database): resolve ConfigurationDatabase-012 — store inbound-API keys as HMAC-SHA256 hashes
Inbound-API bearer credentials are no longer persisted in plaintext. ApiKey now
holds a KeyHash (peppered HMAC-SHA256); the key is shown once at creation and
only its hash is stored. Lookup and validation hash the presented candidate.
Cross-module: Commons (ApiKey, ApiKeyHasher), ConfigurationDatabase (mapping +
HashApiKeyValue migration), InboundAPI (ApiKeyValidator), ManagementService
(key creation), CentralUI (ApiKeys.razor). Existing keys must be re-issued.
2026-05-17 05:42:52 -04:00
Joseph Doherty
a78c3bcb6f fix(commons): resolve Commons-013,014 — integral JSON index handling, distinguish Malformed vs Legacy OPC UA config 2026-05-17 03:18:17 -04:00
Joseph Doherty
c07f524ca4 fix(commons): resolve Commons-005..007,009..012 — OPC UA parse status, TryConvert correctness, Result null guard, invariant formatting, doc refresh 2026-05-16 22:04:21 -04:00
Joseph Doherty
3e7a3d7e31 fix(commons): resolve Commons-001..004 — stale-fire race, JsonDocument lifetime, GetNullable strictness, registry symmetry 2026-05-16 20:58:03 -04:00
Joseph Doherty
d63d412461 test(triggers): expect AlarmTriggerType.Expression in the enum membership test 2026-05-16 06:42:17 -04:00
Joseph Doherty
751248feb6 feat(alarms): HiLo trigger type with per-band level, hysteresis, messages, overrides
Adds a new HiLo alarm trigger type with four configurable setpoints
(LoLo / Lo / Hi / HiHi). Each setpoint carries an optional priority,
deadband (for hysteresis), and operator message. The site runtime emits
AlarmStateChanged with an AlarmLevel field so consumers can differentiate
warning vs critical bands.

Plumbing:
  - new AlarmLevel enum + AlarmStateChanged.Level/Message init properties
  - AlarmTriggerEditor (Blazor) gets a HiLo render with severity tinting
  - AlarmTriggerConfigCodec extracted from the editor for testability
  - sitestream.proto carries level + message over gRPC
  - SemanticValidator enforces numeric attribute, setpoint ordering,
    non-negative deadband
  - on-trigger scripts get an Alarm global (Name/Level/Priority/Message)
    so notification routing can branch by severity
  - per-instance InstanceAlarmOverride entity + EF migration + flattening
    step + CLI commands; HiLo overrides merge setpoint-by-setpoint, binary
    types whole-replace
  - DebugView shows a Level badge + per-band message tooltip
  - App.razor auto-reloads on permanent Blazor circuit failure
  - docker/regen-proto.sh automates the proto regen workflow (the linux/arm64
    protoc segfault means generated files are checked in for now)
2026-05-13 03:23:32 -04:00
Joseph Doherty
91450ec390 test(commons): failing tests for Layer B serializer + validator extensions
Adds 11 new tests covering:
- Roundtrip of DiscardOldest/SubscriptionPriority/SubscriptionDisplayName/TimestampsToReturn
- Roundtrip of UserIdentity sub-object across all three TokenTypes
- Roundtrip of Deadband sub-object
- ToFlatDict/FromFlatDict for UserIdentity.* and Deadband.* dotted keys
- Validator rules: empty SubscriptionDisplayName, UsernamePassword w/o Username,
  X509 w/o CertificatePath, Deadband Value <= 0, prefix propagation

Build passes; tests fail because serializer/validator have not been extended yet
(TDD red phase). Task B2 will implement the changes to drive them green.
2026-05-12 02:21:33 -04:00
Joseph Doherty
084da55ad6 fix(commons): LoadLegacy handles mixed-type JSON values (number/bool/string) 2026-05-12 02:08:32 -04:00
Joseph Doherty
4608adcd53 refactor(commons): defensive legacy-parse + FromFlatDict starts from POCO defaults 2026-05-12 00:48:17 -04:00
Joseph Doherty
90b252047e test(commons): decouple serializer tests from JSON whitespace and verify defaults symmetrically 2026-05-12 00:41:55 -04:00
Joseph Doherty
2220bfcf58 test(commons): failing tests for OpcUaEndpointConfigSerializer 2026-05-12 00:38:56 -04:00
Joseph Doherty
d4397910f0 feat(dcl): add StaleTagMonitor for heartbeat-based disconnect detection
Composable StaleTagMonitor class in Commons fires a Stale event when no
value is received within a configurable max silence period. Integrated
into both LmxProxyDataConnection and OpcUaDataConnection adapters via
optional HeartbeatTagPath/HeartbeatMaxSilence connection config keys.
When stale, the adapter fires Disconnected triggering the standard
reconnect cycle. 10 unit tests cover timer behavior.
2026-03-24 16:19:39 -04:00
Joseph Doherty
161dc406ed feat(scripts): add typed Parameters.Get<T>() helpers for script API
Replace raw dictionary casting with ScriptParameters wrapper that provides
Get<T>, Get<T?>, Get<T[]>, and Get<List<T>> with clear error messages,
numeric conversion, and JsonElement support for Inbound API parameters.
2026-03-22 15:47:18 -04:00
Joseph Doherty
6ea38faa6f Phase 3C: Deployment pipeline & Store-and-Forward engine
Deployment Manager (WP-1–8, WP-16):
- DeploymentService: full pipeline (flatten→validate→send→track→audit)
- OperationLockManager: per-instance concurrency control
- StateTransitionValidator: Enabled/Disabled/NotDeployed transition matrix
- ArtifactDeploymentService: broadcast to all sites with per-site results
- Deployment identity (GUID + revision hash), idempotency, staleness detection
- Instance lifecycle commands (disable/enable/delete) with deduplication

Store-and-Forward (WP-9–15):
- StoreAndForwardStorage: SQLite persistence, 3 categories, no max buffer
- StoreAndForwardService: fixed-interval retry, transient-only buffering, parking
- ReplicationService: async best-effort to standby (fire-and-forget)
- Parked message management (query/retry/discard from central)
- Messages survive instance deletion, S&F drains on disable

620 tests pass (+79 new), zero warnings.
2026-03-16 21:27:18 -04:00
Joseph Doherty
22e1eba58a Phase 0 WP-0.2–0.9: Implement Commons (types, entities, interfaces, messages, protocol, tests)
- WP-0.2: Namespace/folder skeleton (26 directories)
- WP-0.3: Shared data types (6 enums, RetryPolicy, Result<T>)
- WP-0.4: 24 domain entity POCOs across 10 domain areas
- WP-0.5: 7 repository interfaces with full CRUD signatures
- WP-0.6: IAuditService cross-cutting interface
- WP-0.7: 26 message contract records across 8 concern areas
- WP-0.8: IDataConnection protocol abstraction with batch ops
- WP-0.9: 8 architectural constraint enforcement tests
All 40 tests pass, zero warnings.
2026-03-16 18:48:24 -04:00