using ZB.MOM.WW.ScadaBridge.Commons.Types; using ZB.MOM.WW.ScadaBridge.Commons.Types.Enums; namespace ZB.MOM.WW.ScadaBridge.Commons.Messages.Health; public record SiteHealthReport( string SiteId, long SequenceNumber, DateTimeOffset ReportTimestamp, IReadOnlyDictionary DataConnectionStatuses, IReadOnlyDictionary TagResolutionCounts, int ScriptErrorCount, int AlarmEvaluationErrorCount, IReadOnlyDictionary StoreAndForwardBufferDepths, int DeadLetterCount, int DeployedInstanceCount, int EnabledInstanceCount, int DisabledInstanceCount, string NodeRole = "Unknown", string NodeHostname = "", IReadOnlyDictionary? DataConnectionEndpoints = null, IReadOnlyDictionary? DataConnectionTagQuality = null, int ParkedMessageCount = 0, IReadOnlyList? ClusterNodes = null, // Audit Log (#23) M2 Bundle G: per-interval count of FallbackAuditWriter // primary failures (SQLite throws routed to the drop-oldest ring). Surfaces // a sustained audit-write outage on /monitoring/health. Defaults to 0 so // existing producers / tests that don't construct the field stay valid. int SiteAuditWriteFailures = 0, // Audit Log (#23) M5 Bundle C: per-interval count of payload-filter // redactor over-redactions (header / body / SQL parameter stages all // throwing → field replaced with the "" // marker). Surfaces a misconfigured / catastrophic regex on // /monitoring/health. Defaults to 0 for back-compat with existing // producers and tests that don't construct the field. int AuditRedactionFailure = 0, // Audit Log (#23) M6 Bundle E (T6): point-in-time snapshot of the // site-local SQLite audit-log queue (pending count, oldest pending row, // on-disk bytes). Populated by the site-side SiteAuditBacklogReporter // hosted service every 30 s. Defaults to null so existing producers / // tests that don't refresh the snapshot stay valid; the central health // surface treats null as "no data yet" rather than a zeroed queue. SiteAuditBacklogSnapshot? SiteAuditBacklog = null); /// /// Broadcast wrapper used between central nodes to keep per-node /// CentralHealthAggregator state in sync. ClusterClient load-balances each /// incoming SiteHealthReport to one central node; that node re-publishes /// this wrapper on a DistributedPubSub topic so the peer node's aggregator /// also processes the report (idempotently — sequence numbers guard against /// double-counting). /// public record SiteHealthReportReplica(SiteHealthReport Report);