8d4ffa7ef1
Claude-Session: https://claude.ai/code/session_01MtdgwpEeCUn6cUA5f1LMPj
94 lines
4.5 KiB
C#
94 lines
4.5 KiB
C#
namespace ZB.MOM.WW.ScadaBridge.Commons.Messages.Management;
|
|
|
|
// ============================================================================
|
|
// Two-person ("secured") write commands.
|
|
//
|
|
// An Operator SUBMITS a pending secured write against an MxGateway data
|
|
// connection; a distinct Verifier later APPROVES (executes) or
|
|
// REJECTS it. Separation of duties is enforced at the handler: a write may not
|
|
// be verified by the same principal that submitted it. ListSecuredWrites is a
|
|
// read-only query (any authenticated user). Role gating lives in
|
|
// ManagementActor.GetRequiredRole (Operator for submit; Verifier for
|
|
// reject/approve).
|
|
// ============================================================================
|
|
|
|
/// <summary>
|
|
/// Operator request to submit a pending secured write. The target connection
|
|
/// must exist within the site and use the MxGateway protocol; the value is
|
|
/// captured as <paramref name="ValueJson"/> interpreted per <paramref name="ValueType"/>.
|
|
/// Returns the newly-created <see cref="SecuredWriteDto"/>.
|
|
/// </summary>
|
|
/// <param name="SiteId">Site identifier the write targets.</param>
|
|
/// <param name="ConnectionName">Data connection name within the site.</param>
|
|
/// <param name="TagPath">Fully-qualified tag path the value is written to.</param>
|
|
/// <param name="ValueJson">JSON-serialised value to write.</param>
|
|
/// <param name="ValueType">Target data type name (e.g. <c>Boolean</c>, <c>Double</c>).</param>
|
|
/// <param name="Comment">Optional free-text comment supplied by the operator.</param>
|
|
public record SubmitSecuredWriteCommand(
|
|
string SiteId,
|
|
string ConnectionName,
|
|
string TagPath,
|
|
string ValueJson,
|
|
string ValueType,
|
|
string? Comment);
|
|
|
|
/// <summary>
|
|
/// Verifier request to approve (and execute) a pending
|
|
/// secured write. Declared here so the secured-write contract is complete; the
|
|
/// approve→execute relay handler and dispatch arm are implemented separately.
|
|
/// </summary>
|
|
/// <param name="Id">Identity of the pending secured write.</param>
|
|
/// <param name="Comment">Optional free-text comment supplied by the verifier.</param>
|
|
public record ApproveSecuredWriteCommand(long Id, string? Comment);
|
|
|
|
/// <summary>
|
|
/// Verifier request to reject a pending secured write. The write must still be
|
|
/// <c>Pending</c>, and the verifier must differ from the submitting operator
|
|
/// (separation of duties). Returns the updated <see cref="SecuredWriteDto"/>.
|
|
/// </summary>
|
|
/// <param name="Id">Identity of the pending secured write.</param>
|
|
/// <param name="Comment">Optional free-text comment supplied by the verifier.</param>
|
|
public record RejectSecuredWriteCommand(long Id, string? Comment);
|
|
|
|
/// <summary>
|
|
/// Read-only query for secured writes, optionally filtered by status and site,
|
|
/// with offset paging. A <c>null</c> filter matches every row. The <paramref name="Skip"/>
|
|
/// / <paramref name="Take"/> defaults preserve the historical unpaged wire behaviour
|
|
/// (first 200 rows) for callers that omit them (additive evolution).
|
|
/// </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); clamped to >= 0 server-side.</param>
|
|
/// <param name="Take">Maximum rows to return; clamped to 1..500 server-side. Default 200.</param>
|
|
public record ListSecuredWritesCommand(string? Status, string? SiteId, int Skip = 0, int Take = 200);
|
|
|
|
/// <summary>
|
|
/// Result projection of a single pending secured write row, mirroring the
|
|
/// <c>PendingSecuredWrite</c> entity shape.
|
|
/// </summary>
|
|
public record SecuredWriteDto(
|
|
long Id,
|
|
string SiteId,
|
|
string ConnectionName,
|
|
string TagPath,
|
|
string ValueJson,
|
|
string ValueType,
|
|
string Status,
|
|
string OperatorUser,
|
|
string? OperatorComment,
|
|
DateTime SubmittedAtUtc,
|
|
string? VerifierUser,
|
|
string? VerifierComment,
|
|
DateTime? DecidedAtUtc,
|
|
DateTime? ExecutedAtUtc,
|
|
string? ExecutionError);
|
|
|
|
/// <summary>
|
|
/// Result wrapper for <see cref="ListSecuredWritesCommand"/>. <paramref name="TotalCount"/>
|
|
/// is the count of rows matching the query filters ignoring paging, so the UI can render
|
|
/// a pager independent of the returned page size.
|
|
/// </summary>
|
|
/// <param name="Items">The page of matching secured-write rows.</param>
|
|
/// <param name="TotalCount">Total number of rows matching the filters (unpaged).</param>
|
|
public record SecuredWriteListResult(IReadOnlyList<SecuredWriteDto> Items, int TotalCount);
|