using System.Collections.Concurrent; namespace ZB.MOM.WW.OtOpcUa.Core.ScriptedAlarms; /// /// Persistence for across server restarts. Phase 7 /// plan decision #14: 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 { Task LoadAsync(string alarmId, CancellationToken ct); Task> LoadAllAsync(CancellationToken ct); Task SaveAsync(AlarmConditionState state, CancellationToken ct); 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; } }