using ZB.MOM.WW.ScadaBridge.Commons.Messages.Management;
namespace ZB.MOM.WW.ScadaBridge.CentralUI.Services;
///
/// Outcome of a single secured-write command dispatch. Wraps either the resulting
/// (on success) or a human-readable error, so the page
/// can render an inline result/toast rather than reasoning about transport exceptions
/// or the three management response shapes.
///
/// Whether the command succeeded.
/// The resulting secured-write row when is true; otherwise null.
/// A human-readable error message when is false; otherwise null.
public record SecuredWriteActionResult(bool Success, SecuredWriteDto? Dto, string? Error)
{
/// Creates a successful result wrapping .
/// The secured-write row the command produced.
/// A successful .
public static SecuredWriteActionResult Ok(SecuredWriteDto dto) => new(true, dto, null);
/// Creates a failed result carrying .
/// The human-readable failure message.
/// A failed .
public static SecuredWriteActionResult Fail(string error) => new(false, null, error);
}
///
/// CentralUI facade over the two-person ("secured") write management commands.
/// It dispatches the strongly-typed
/// SubmitSecuredWriteCommand / ApproveSecuredWriteCommand /
/// RejectSecuredWriteCommand / ListSecuredWritesCommand to the central
/// ManagementActor through the in-process ManagementActorHolder seam —
/// the SAME path the HTTP /management endpoint uses — so the server remains the
/// single enforcer of role gating, separation-of-duties (no self-approval), the actual
/// MxGateway device relay on approve, and the append-only audit trail.
///
///
/// The page itself performs NO device I/O and re-implements NO security logic: every
/// mutation is a command submitted to the server. The current user's claims are mapped
/// to an so the actor's role check and no-self-approval
/// guard run against the real principal. ManagementUnauthorized /
/// ManagementError / transport failures collapse into a typed
/// so the page renders an inline outcome rather
/// than throwing.
///
public interface ISecuredWriteService
{
///
/// Submits a new pending secured write (Operator action). The target connection
/// must exist within and use the MxGateway protocol —
/// both validated server-side.
///
/// Site identifier the write targets.
/// MxGateway data connection name within the site.
/// Fully-qualified tag path the value is written to.
/// JSON-serialised value to write.
/// Target data type name (e.g. Boolean, Double).
/// Optional free-text comment supplied by the operator.
/// Cancellation token.
/// A task resolving to the submit outcome.
Task SubmitAsync(
string siteId,
string connectionName,
string tagPath,
string valueJson,
string valueType,
string? comment,
CancellationToken cancellationToken = default);
///
/// Approves (and triggers execution of) a pending secured write (Verifier action).
/// The server enforces that the approver differs from the submitter and runs the
/// device relay.
///
/// Identity of the pending secured write.
/// Optional free-text comment supplied by the verifier.
/// Cancellation token.
/// A task resolving to the approve outcome.
Task ApproveAsync(
long id, string? comment, CancellationToken cancellationToken = default);
///
/// Rejects a pending secured write (Verifier action). The server enforces that the
/// rejecter differs from the submitter.
///
/// Identity of the pending secured write.
/// Optional free-text comment supplied by the verifier.
/// Cancellation token.
/// A task resolving to the reject outcome.
Task RejectAsync(
long id, string? comment, CancellationToken cancellationToken = default);
///
/// Lists secured writes, optionally filtered by and
/// with offset paging (read-only — any authenticated user).
/// On any failure an empty result (TotalCount = 0) is returned so the page
/// renders gracefully. The returned is
/// the unpaged match count, so the page can drive a pager independent of page size.
///
/// Status filter; null matches every status.
/// Site id filter; null matches every site.
/// Rows to skip (offset paging); clamped to >= 0 server-side.
/// Maximum rows to return; clamped to 1..500 server-side.
/// Cancellation token.
/// A task resolving to the matching page + total match count, newest submission first.
Task ListAsync(
string? status, string? siteId, int skip = 0, int take = 200,
CancellationToken cancellationToken = default);
}