namespace ZB.MOM.WW.ScadaBridge.NotificationOutbox; /// /// Configuration options for the Notification Outbox component: dispatch cadence, /// batch sizing, stuck-message detection, terminal retention, and KPI windowing. /// public class NotificationOutboxOptions { /// /// Interval between dispatch sweeps that pick up pending notifications for delivery. /// Default: 10 seconds. /// public TimeSpan DispatchInterval { get; set; } = TimeSpan.FromSeconds(10); /// /// Maximum number of notifications claimed for delivery in a single dispatch sweep. /// Caps per-sweep batch size to bound memory and per-iteration latency. /// Default: 100. /// public int DispatchBatchSize { get; set; } = 100; /// /// Age past which a still-Pending/Retrying notification is counted as /// "stuck" on the KPI tile and the per-row badge in the Central UI. /// Display-only: rows older than this threshold are flagged in KPIs/UI; there is no /// automatic re-claim, requeue, or escalation — the dispatcher behaviour is unaffected. /// Default: 10 minutes. /// public TimeSpan StuckAgeThreshold { get; set; } = TimeSpan.FromMinutes(10); /// /// Retention period for notifications in a terminal state (Delivered, /// Parked, Discarded) before they are purged from the Notifications table. /// Default: 365 days. /// public TimeSpan TerminalRetention { get; set; } = TimeSpan.FromDays(365); /// /// Interval between background purge sweeps of terminal notifications older than /// . /// Default: 1 day. /// public TimeSpan PurgeInterval { get; set; } = TimeSpan.FromDays(1); /// /// Trailing window used to compute the "delivered (last interval)" throughput KPI /// surfaced on the Health dashboard and the Notification Outbox page. /// Default: 1 minute. /// public TimeSpan DeliveredKpiWindow { get; set; } = TimeSpan.FromMinutes(1); /// /// Maximum number of notifications delivered concurrently within a single dispatch /// sweep. Delivery is I/O-bound (SMTP / Twilio round trips of seconds each), so a /// purely sequential sweep caps throughput at ~1/attempt-latency regardless of batch /// size — an alarm storm queued behind one slow SMTP host would drain far too slowly /// (arch-review 04). Each concurrent delivery runs on its own DI scope/repository, so /// there is no shared-DbContext contention. Set to 1 to preserve the strictly /// sequential behaviour. Clamped to a minimum of 1 via . /// Default: 4. /// public int MaxParallelDeliveries { get; set; } = 4; /// /// Resolves the effective delivery parallelism, clamped to at least 1 so a /// misconfigured 0/negative value cannot stall the dispatcher (a zero-count /// semaphore would deadlock the sweep). /// public int ResolvedMaxParallelDeliveries => MaxParallelDeliveries < 1 ? 1 : MaxParallelDeliveries; }