namespace ZB.MOM.WW.OtOpcUa.Core.ScriptedAlarms; /// /// Persistent per-alarm state tracked by the Part 9 state machine. Every field /// carried here either participates in the state machine or contributes to the /// audit trail required by Phase 7 plan decision #14 (GxP / 21 CFR Part 11). /// /// /// /// is re-derived from the predicate at startup per Phase 7 /// decision #14 — the engine runs every alarm's predicate against current tag /// values at Load, overriding whatever Active state is in the store. /// Every other state field persists verbatim across server restarts so /// operators don't re-ack active alarms after an outage + shelved alarms stay /// shelved + audit history survives. /// /// /// is append-only; comments + ack/confirm user identities /// are the audit surface regulators consume. The engine never rewrites past /// entries. /// /// public sealed record AlarmConditionState( string AlarmId, AlarmEnabledState Enabled, AlarmActiveState Active, AlarmAckedState Acked, AlarmConfirmedState Confirmed, ShelvingState Shelving, DateTime LastTransitionUtc, DateTime? LastActiveUtc, DateTime? LastClearedUtc, DateTime? LastAckUtc, string? LastAckUser, string? LastAckComment, DateTime? LastConfirmUtc, string? LastConfirmUser, string? LastConfirmComment, IReadOnlyList Comments) { /// Initial-load state for a newly registered alarm — everything in the "no-event" position. public static AlarmConditionState Fresh(string alarmId, DateTime nowUtc) => new( AlarmId: alarmId, Enabled: AlarmEnabledState.Enabled, Active: AlarmActiveState.Inactive, Acked: AlarmAckedState.Acknowledged, Confirmed: AlarmConfirmedState.Confirmed, Shelving: ShelvingState.Unshelved, LastTransitionUtc: nowUtc, LastActiveUtc: null, LastClearedUtc: null, LastAckUtc: null, LastAckUser: null, LastAckComment: null, LastConfirmUtc: null, LastConfirmUser: null, LastConfirmComment: null, Comments: []); } /// /// Shelving state — kind plus, for , the UTC /// timestamp at which the shelving auto-expires. The engine polls the timer on its /// evaluation cadence; callers should not rely on millisecond-precision expiry. /// public sealed record ShelvingState(ShelvingKind Kind, DateTime? UnshelveAtUtc) { public static readonly ShelvingState Unshelved = new(ShelvingKind.Unshelved, null); } /// /// A single append-only audit record — acknowledgement / confirmation / explicit /// comment / shelving action. Every entry carries a monotonic UTC timestamp plus the /// user identity Phase 6.2 authenticated. /// /// When the action happened. /// OS / LDAP identity of the actor. For engine-internal events (shelving expiry, startup recovery) this is "system". /// Human-readable classification — "Acknowledge", "Confirm", "ShelveOneShot", "ShelveTimed", "Unshelve", "AddComment", "Enable", "Disable", "AutoUnshelve". /// Operator-supplied comment or engine-generated message. public sealed record AlarmComment( DateTime TimestampUtc, string User, string Kind, string Text);