feat(db): PendingSecuredWrite entity + migration + repository (T14b)

This commit is contained in:
Joseph Doherty
2026-06-18 02:09:31 -04:00
parent a0ce8b6c44
commit c799f41d53
10 changed files with 2477 additions and 0 deletions
@@ -0,0 +1,57 @@
using ZB.MOM.WW.ScadaBridge.Commons.Entities.SecuredWrites;
namespace ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Repositories;
/// <summary>
/// Operational-state data access for the central <c>PendingSecuredWrites</c> table
/// (M7 OPC UA / MxGateway UX, Task T14b). One row per pending two-person secured
/// write; rows are inserted at submission and mutated as the request is decided and
/// executed. Mirrors the <c>SiteCalls</c> (Site Call Audit #22) repository shape.
/// </summary>
public interface ISecuredWriteRepository
{
/// <summary>
/// Inserts <paramref name="securedWrite"/> and returns the store-generated
/// <see cref="PendingSecuredWrite.Id"/>.
/// </summary>
/// <param name="securedWrite">The pending secured write to persist.</param>
/// <param name="ct">Cancellation token.</param>
/// <returns>A task that resolves to the generated identity of the inserted row.</returns>
Task<long> AddAsync(PendingSecuredWrite securedWrite, CancellationToken ct = default);
/// <summary>
/// Returns the row for the given id, or <c>null</c> if none exists.
/// </summary>
/// <param name="id">The identity to look up.</param>
/// <param name="ct">Cancellation token.</param>
/// <returns>A task that resolves to the matching <see cref="PendingSecuredWrite"/>, or <c>null</c> if no row exists.</returns>
Task<PendingSecuredWrite?> GetAsync(long id, CancellationToken ct = default);
/// <summary>
/// Persists the current state of <paramref name="securedWrite"/> (matched by
/// <see cref="PendingSecuredWrite.Id"/>).
/// </summary>
/// <param name="securedWrite">The tracked entity whose changes to persist.</param>
/// <param name="ct">Cancellation token.</param>
/// <returns>A task that represents the asynchronous operation.</returns>
Task UpdateAsync(PendingSecuredWrite securedWrite, CancellationToken ct = default);
/// <summary>
/// Returns up to <paramref name="take"/> rows (skipping <paramref name="skip"/>)
/// optionally filtered by <paramref name="status"/> and <paramref name="siteId"/>,
/// ordered by <c>SubmittedAtUtc DESC, Id DESC</c>. A <c>null</c> filter argument
/// matches every row.
/// </summary>
/// <param name="status">Status filter; <c>null</c> matches every status.</param>
/// <param name="siteId">Site id filter; <c>null</c> matches every site.</param>
/// <param name="skip">Number of rows to skip (offset paging).</param>
/// <param name="take">Maximum number of rows to return.</param>
/// <param name="ct">Cancellation token.</param>
/// <returns>A task that resolves to a page of matching rows, newest submission first.</returns>
Task<IReadOnlyList<PendingSecuredWrite>> QueryAsync(
string? status,
string? siteId,
int skip,
int take,
CancellationToken ct = default);
}