using System.Collections.Concurrent; namespace ZB.MOM.WW.OtOpcUa.Core.ScriptedAlarms; /// /// Persistence for across server restarts. /// Operator-supplied state (EnabledState / AckedState / /// ConfirmedState / ShelvingState + audit trail) persists; ActiveState is /// recomputed from the live predicate on startup so operators never re-ack. /// /// /// Stream E wires this to a SQL-backed store against the ScriptedAlarmState /// table with audit logging through IAuditLogger. /// Tests + local dev use . /// public interface IAlarmStateStore { /// Loads the alarm state for a specific alarm identifier. /// The alarm identifier. /// Cancellation token. /// The alarm state if found; otherwise null. Task LoadAsync(string alarmId, CancellationToken ct); /// Loads all alarm states from the store. /// Cancellation token. /// A collection of all alarm states. Task> LoadAllAsync(CancellationToken ct); /// Saves an alarm state to the store. /// The alarm state to save. /// Cancellation token. /// A task representing the save operation. Task SaveAsync(AlarmConditionState state, CancellationToken ct); /// Removes an alarm state from the store. /// The alarm identifier to remove. /// Cancellation token. /// A task representing the remove operation. Task RemoveAsync(string alarmId, CancellationToken ct); } /// In-memory default — used by tests + by dev deployments without a SQL backend. public sealed class InMemoryAlarmStateStore : IAlarmStateStore { private readonly ConcurrentDictionary _map = new(StringComparer.Ordinal); /// public Task LoadAsync(string alarmId, CancellationToken ct) => Task.FromResult(_map.TryGetValue(alarmId, out var v) ? v : null); /// public Task> LoadAllAsync(CancellationToken ct) => Task.FromResult>(_map.Values.ToArray()); /// public Task SaveAsync(AlarmConditionState state, CancellationToken ct) { _map[state.AlarmId] = state; return Task.CompletedTask; } /// public Task RemoveAsync(string alarmId, CancellationToken ct) { _map.TryRemove(alarmId, out _); return Task.CompletedTask; } }