using ScadaLink.Commons.Entities.Notifications; using ScadaLink.Commons.Types.Notifications; namespace ScadaLink.Commons.Interfaces.Repositories; /// /// Data access for the central notification outbox — the queue of /// rows the outbox actor drains, retries, and audits. Distinct from /// , which manages notification list configuration. /// /// /// Persistence model: and commit /// internally, so each call is its own transaction — suited to the outbox actor committing one /// row's status transition at a time. The standalone is available /// for callers that stage multiple changes and want to flush them together. /// public interface INotificationOutboxRepository { /// /// Inserts only if no row with the same /// exists. Returns true when a new /// row was inserted, false when an existing row was left untouched. /// Commits internally — this call is its own transaction. /// Task InsertIfNotExistsAsync(Notification n, CancellationToken cancellationToken = default); /// /// Returns notifications ready for a delivery attempt: Pending rows, plus /// Retrying rows whose NextAttemptAt is at or before . /// Terminal rows are excluded. Ordered by CreatedAt ascending, capped at /// . /// Task> GetDueAsync(DateTimeOffset now, int batchSize, CancellationToken cancellationToken = default); /// Returns the notification with the given id, or null. Task GetByIdAsync(string notificationId, CancellationToken cancellationToken = default); /// /// Marks modified and persists it (status transitions). /// Commits internally — this call is its own transaction. /// Task UpdateAsync(Notification n, CancellationToken cancellationToken = default); /// /// Returns a page of notifications matching , ordered by /// CreatedAt descending, together with the total matching count. /// Task<(IReadOnlyList Rows, int TotalCount)> QueryAsync( NotificationOutboxFilter filter, int pageNumber, int pageSize, CancellationToken cancellationToken = default); /// /// Bulk-deletes terminal rows (Delivered/Parked/Discarded) whose CreatedAt is /// older than . Returns the number of rows deleted. /// Task DeleteTerminalOlderThanAsync(DateTimeOffset cutoff, CancellationToken cancellationToken = default); /// /// Computes a point-in-time . The stuck and /// delivered cutoffs are supplied by the caller; the current time used for /// OldestPendingAge is captured inside the method. /// Task ComputeKpisAsync( DateTimeOffset stuckCutoff, DateTimeOffset deliveredSince, CancellationToken cancellationToken = default); /// /// Computes a point-in-time per source site. /// Sites with no notification rows at all are omitted. The stuck and delivered cutoffs /// are supplied by the caller; the current time used for OldestPendingAge is /// captured inside the method. /// Task> ComputePerSiteKpisAsync( DateTimeOffset stuckCutoff, DateTimeOffset deliveredSince, CancellationToken cancellationToken = default); /// /// Persists pending changes tracked on the underlying context. Use this when staging /// multiple changes for a single commit; the individual mutating methods on this /// interface already commit on their own. /// Task SaveChangesAsync(CancellationToken cancellationToken = default); }