using ZB.MOM.WW.ScadaBridge.Commons.Entities.SecuredWrites;
namespace ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Repositories;
///
/// Operational-state data access for the central PendingSecuredWrites table.
/// One row per pending two-person secured
/// write; rows are inserted at submission and mutated as the request is decided and
/// executed. Mirrors the SiteCalls repository shape.
///
public interface ISecuredWriteRepository
{
///
/// Inserts and returns the store-generated
/// .
///
/// The pending secured write to persist.
/// Cancellation token.
/// A task that resolves to the generated identity of the inserted row.
Task AddAsync(PendingSecuredWrite securedWrite, CancellationToken ct = default);
///
/// Returns the row for the given id, or null if none exists.
///
/// The identity to look up.
/// Cancellation token.
/// A task that resolves to the matching , or null if no row exists.
Task GetAsync(long id, CancellationToken ct = default);
///
/// Persists the current state of (matched by
/// ).
///
/// The tracked entity whose changes to persist.
/// Cancellation token.
/// A task that represents the asynchronous operation.
Task UpdateAsync(PendingSecuredWrite securedWrite, CancellationToken ct = default);
///
/// Returns up to rows (skipping )
/// optionally filtered by and ,
/// ordered by SubmittedAtUtc DESC, Id DESC. A null filter argument
/// matches every row.
///
/// Status filter; null matches every status.
/// Site id filter; null matches every site.
/// Number of rows to skip (offset paging).
/// Maximum number of rows to return.
/// When non-null, only rows whose SiteId (site
/// identifier) is in the set match; null matches every site. Applied IN ADDITION
/// to . Used by the ManagementActor to constrain an unfiltered
/// list to a site-scoped caller's permitted sites at the query level (arch-review R2 N3),
/// so paging and totals stay correct.
/// Cancellation token.
/// A task that resolves to a page of matching rows, newest submission first.
Task> QueryAsync(
string? status,
string? siteId,
int skip,
int take,
IReadOnlyCollection? permittedSiteIds = null,
CancellationToken ct = default);
///
/// Atomically flips a row from Pending to Approved, stamping the
/// verifier identity, comment, and decision time, but ONLY if the row is still
/// Pending. This is the compare-and-swap guard for the two-verifier race:
/// two verifiers may approve the same write concurrently, but the
/// conditional WHERE Status='Pending' guarantees exactly one wins. The
/// loser observes false and must not relay the write.
///
/// Identity of the pending secured write.
/// The approving verifier's username.
/// Optional free-text comment from the verifier.
/// UTC instant the approval decision was made.
/// Cancellation token.
///
/// A task resolving to true if this caller won the approval (exactly one
/// row transitioned), or false if the row was no longer Pending
/// (already decided by another verifier).
///
Task TryMarkApprovedAsync(
long id,
string verifierUser,
string? verifierComment,
DateTime decidedAtUtc,
CancellationToken ct = default);
///
/// Atomically flips a row from Pending to Expired, stamping the
/// expiry as the decision time, but ONLY if the row is still Pending.
/// This is the multi-node-safe expiry primitive: the conditional
/// WHERE Status='Pending' makes the Pending->Expired transition atomic at
/// the row level, so two nodes sweeping the same overdue write concurrently
/// produce exactly one winner. The expiry is a system decision — no verifier is
/// recorded and stays null.
/// The loser observes false (the row was already decided or expired).
///
/// Identity of the pending secured write.
/// UTC instant the write was deemed expired.
/// Cancellation token.
///
/// A task resolving to true if this caller won the expiry (exactly one
/// row transitioned), or false if the row was no longer Pending.
///
Task TryMarkExpiredAsync(long id, DateTime expiredAtUtc, CancellationToken ct = default);
///
/// Returns the number of rows matching the optional and
/// filters. A null filter argument matches every
/// row. Mirrors 's filter composition without paging.
///
/// Status filter; null matches every status.
/// Site id filter; null matches every site.
/// When non-null, only rows whose SiteId (site
/// identifier) is in the set match; null matches every site. Applied IN ADDITION
/// to . Used by the ManagementActor to constrain an unfiltered
/// list to a site-scoped caller's permitted sites at the query level (arch-review R2 N3),
/// so paging and totals stay correct.
/// Cancellation token.
/// A task that resolves to the count of matching rows.
Task CountAsync(
string? status,
string? siteId,
IReadOnlyCollection? permittedSiteIds = null,
CancellationToken ct = default);
}