using ScadaLink.Commons.Types.Enums; namespace ScadaLink.Commons.Entities.Notifications; /// /// A single notification queued in the central outbox. Created at a site (where the /// GUID is generated) and forwarded to the central cluster /// for delivery, retry, and audit. The lifecycle is tracked by . /// public class Notification { /// GUID primary key, generated at the originating site. public string NotificationId { get; set; } public NotificationType Type { get; set; } public string ListName { get; set; } public string Subject { get; set; } public string Body { get; set; } /// JSON extensibility hook for channel-specific payload data. public string? TypeData { get; set; } public NotificationStatus Status { get; set; } = NotificationStatus.Pending; public int RetryCount { get; set; } public string? LastError { get; set; } /// Resolved delivery targets snapshotted at delivery time, for audit. public string? ResolvedTargets { get; set; } public string SourceSiteId { get; set; } public string? SourceInstanceId { get; set; } public string? SourceScript { get; set; } /// /// The originating script execution's ExecutionId (Audit Log #23). Carried from /// the site on the so the /// central dispatcher can stamp the same id onto its NotifyDeliver audit rows, /// correlating them with the site-emitted NotifySend row. Null for notifications /// submitted before the column existed, or raised outside a script-execution context. /// public Guid? OriginExecutionId { get; set; } public DateTimeOffset SiteEnqueuedAt { get; set; } /// Central ingest time. public DateTimeOffset CreatedAt { get; set; } public DateTimeOffset? LastAttemptAt { get; set; } public DateTimeOffset? NextAttemptAt { get; set; } public DateTimeOffset? DeliveredAt { get; set; } public Notification(string notificationId, NotificationType type, string listName, string subject, string body, string sourceSiteId) { NotificationId = notificationId ?? throw new ArgumentNullException(nameof(notificationId)); Type = type; ListName = listName ?? throw new ArgumentNullException(nameof(listName)); Subject = subject ?? throw new ArgumentNullException(nameof(subject)); Body = body ?? throw new ArgumentNullException(nameof(body)); SourceSiteId = sourceSiteId ?? throw new ArgumentNullException(nameof(sourceSiteId)); } }