using ZB.MOM.WW.MxGateway.Contracts.Proto; using ZB.MOM.WW.MxGateway.Server.Alarms; namespace ZB.MOM.WW.MxGateway.Server.Dashboard; /// /// Dashboard projection of an message /// carried on the alarm feed. Maps the protobuf provider mode / degraded /// flag into Bootstrap-only display fields so the Alarms page can render a /// status badge without touching protobuf types. /// public sealed record DashboardAlarmProviderStatus( AlarmProviderMode Mode, bool IsDegraded, string Label, string BadgeCssClass, string Reason, DateTimeOffset? SinceUtc) { /// Badge label shown when the alarm-manager provider is healthy. public const string AlarmManagerLabel = "Alarm Manager"; /// Badge label shown when the feed has fallen back to subtag monitoring. public const string DegradedLabel = "Subtag monitoring (degraded)"; /// /// Badge label shown when the feed is in subtag monitoring because it was /// deliberately configured (Fallback:Mode=ForceSubtag), as opposed /// to an unexpected failover. A stable, intended state rather than a fault. /// public const string ForcedSubtagLabel = "Subtag monitoring (forced)"; private const string HealthyBadge = "bg-success"; private const string DegradedBadge = "bg-warning text-dark"; // Cyan/info badge: visually distinct from the amber failover-degraded badge — // forced subtag is an intentional configuration, not an alarm-manager fault. private const string ForcedSubtagBadge = "bg-info text-dark"; /// /// The default status assumed before the first provider-status message /// arrives: healthy alarm-manager mode. /// public static DashboardAlarmProviderStatus Healthy { get; } = new( Mode: AlarmProviderMode.Alarmmgr, IsDegraded: false, Label: AlarmManagerLabel, BadgeCssClass: HealthyBadge, Reason: string.Empty, SinceUtc: null); /// Projects an alarm-feed provider-status payload into a dashboard badge model. /// The provider-status payload from an . /// The projected dashboard status. public static DashboardAlarmProviderStatus FromProviderStatus(AlarmProviderStatus status) { ArgumentNullException.ThrowIfNull(status); // Treat the explicit degraded flag and the SUBTAG mode as equivalent; // the contract sets degraded=true whenever mode == SUBTAG, but guard // against either being set independently. bool degraded = status.Degraded || status.Mode == AlarmProviderMode.Subtag; string reason = status.Reason ?? string.Empty; // A configured ForceSubtag start carries the well-known forced reason and // is a deliberate mode, not a failover — render it distinctly so an // operator isn't alarmed by a "(degraded)" badge for an intended config. bool forced = degraded && status.Mode == AlarmProviderMode.Subtag && string.Equals(reason, AlarmProviderReasons.ForcedSubtag, StringComparison.Ordinal); string label = !degraded ? AlarmManagerLabel : forced ? ForcedSubtagLabel : DegradedLabel; string badge = !degraded ? HealthyBadge : forced ? ForcedSubtagBadge : DegradedBadge; return new DashboardAlarmProviderStatus( Mode: status.Mode, IsDegraded: degraded, Label: label, BadgeCssClass: badge, Reason: reason, SinceUtc: status.Since?.ToDateTimeOffset()); } /// Projects an alarm-feed message into a dashboard badge model. /// An alarm-feed message whose payload is a provider status. /// The projected dashboard status. /// The message does not carry a provider-status payload. public static DashboardAlarmProviderStatus FromFeed(AlarmFeedMessage message) { ArgumentNullException.ThrowIfNull(message); if (message.PayloadCase != AlarmFeedMessage.PayloadOneofCase.ProviderStatus) { throw new ArgumentException( "Alarm-feed message does not carry a provider-status payload.", nameof(message)); } return FromProviderStatus(message.ProviderStatus); } }