using ScadaLink.Commons.Types; namespace ScadaLink.Commons.Interfaces; /// /// Site-local source of truth for cached-operation tracking /// (ExternalSystem.CachedCall / Database.CachedWrite) — alongside the /// Store-and-Forward buffer, this is the row that Tracking.Status(id) /// reads (Audit Log #23 / M3). One row per ; /// terminal rows are purged after a configurable retention window /// (default 7 days). /// /// /// /// The store is intentionally a thin write-API on top of SQLite — not a /// dispatcher. Status transitions follow /// Submitted → Retrying → Delivered / Parked / Failed / Discarded; rows /// in a terminal state never roll back. Implementations must: /// /// is insert-if-not-exists /// (caller-supplied id is the idempotency key — duplicate enqueues are no-ops). /// only updates non-terminal rows. /// only flips a non-terminal row to terminal. /// deletes terminal rows whose /// TerminalAtUtc is strictly older than the supplied threshold. /// /// /// public interface IOperationTrackingStore { /// /// Insert a new tracking row in Submitted state with RetryCount = 0. /// Idempotent — a duplicate id is silently ignored (the existing row is left /// untouched), matching the at-least-once semantics of the calling site /// store-and-forward path. /// Task RecordEnqueueAsync( TrackedOperationId id, string kind, string? targetSummary, string? sourceInstanceId, string? sourceScript, string? sourceNode, CancellationToken ct = default); /// /// Advance an in-flight tracking row's status, retry counter, and most- /// recent error/HTTP-status. Terminal rows ( /// already applied) are NOT mutated — the operation has reached its final /// outcome and any late-arriving attempt telemetry is dropped on the floor. /// Task RecordAttemptAsync( TrackedOperationId id, string status, int retryCount, string? lastError, int? httpStatus, CancellationToken ct = default); /// /// Flip a non-terminal tracking row to terminal — sets /// TerminalAtUtc = now and writes the final status / error. A row /// already in terminal state is left untouched (first-write-wins). /// Task RecordTerminalAsync( TrackedOperationId id, string status, string? lastError, int? httpStatus, CancellationToken ct = default); /// /// Return the latest snapshot for the supplied id, or null when no /// tracking row exists (purged or never recorded). /// Task GetStatusAsync( TrackedOperationId id, CancellationToken ct = default); /// /// Delete terminal rows whose TerminalAtUtc is strictly older than /// . Non-terminal rows are kept regardless /// of age (the operation is still in flight). /// Task PurgeTerminalAsync( DateTime olderThanUtc, CancellationToken ct = default); }