< Summary

Information
Class: AsiBackbone.Core.Handshakes.LiabilityHandshakeRequest
Assembly: AsiBackbone.Core
File(s): /home/runner/work/AsiBackbone/AsiBackbone/src/AsiBackbone.Core/Handshakes/LiabilityHandshakeRequest.cs
Line coverage
100%
Covered lines: 121
Uncovered lines: 0
Coverable lines: 121
Total lines: 303
Line coverage: 100%
Branch coverage
100%
Covered branches: 22
Total branches: 22
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.cctor()100%11100%
.ctor(...)100%11100%
get_HandshakeId()100%11100%
get_SchemaVersion()100%11100%
get_ActorId()100%11100%
get_ActorType()100%11100%
get_ActorDisplayName()100%11100%
get_OperationName()100%11100%
get_ReasonCode()100%11100%
get_Message()100%11100%
get_RequiredAcknowledgmentCode()100%11100%
get_RequiredAcknowledgmentText()100%11100%
get_RiskLevel()100%11100%
get_RiskCategory()100%11100%
get_CorrelationId()100%11100%
get_TraceId()100%11100%
get_PolicyVersion()100%11100%
get_PolicyHash()100%11100%
get_Metadata()100%11100%
get_HasMetadata()100%11100%
Create(...)100%11100%
FromDecision(...)100%44100%
NormalizeIdentifier(...)100%22100%
NormalizeOptional(...)100%22100%
NormalizeMetadata(...)100%1414100%

File(s)

/home/runner/work/AsiBackbone/AsiBackbone/src/AsiBackbone.Core/Handshakes/LiabilityHandshakeRequest.cs

#LineLine coverage
 1using System.Collections.ObjectModel;
 2using AsiBackbone.Core.Actors;
 3using AsiBackbone.Core.Decisions;
 4using AsiBackbone.Core.Serialization;
 5
 6namespace AsiBackbone.Core.Handshakes;
 7
 8/// <summary>
 9/// Represents a framework-neutral liability or responsibility handshake request before consequential execution.
 10/// </summary>
 11public sealed class LiabilityHandshakeRequest
 12{
 313    private static readonly IReadOnlyDictionary<string, string> EmptyMetadata =
 314        new ReadOnlyDictionary<string, string>(
 315            new Dictionary<string, string>(StringComparer.Ordinal));
 16
 11417    private LiabilityHandshakeRequest(
 11418        string handshakeId,
 11419        string? schemaVersion,
 11420        string actorId,
 11421        AsiBackboneActorType actorType,
 11422        string? actorDisplayName,
 11423        string operationName,
 11424        string reasonCode,
 11425        string message,
 11426        string requiredAcknowledgmentCode,
 11427        string requiredAcknowledgmentText,
 11428        LiabilityHandshakeRiskLevel riskLevel,
 11429        string? riskCategory,
 11430        string? correlationId,
 11431        string? traceId,
 11432        string? policyVersion,
 11433        string? policyHash,
 11434        IReadOnlyDictionary<string, string> metadata)
 35    {
 11436        ArgumentException.ThrowIfNullOrWhiteSpace(handshakeId);
 11437        ArgumentException.ThrowIfNullOrWhiteSpace(actorId);
 11438        ArgumentException.ThrowIfNullOrWhiteSpace(operationName);
 11039        ArgumentException.ThrowIfNullOrWhiteSpace(reasonCode);
 10640        ArgumentException.ThrowIfNullOrWhiteSpace(message);
 10641        ArgumentException.ThrowIfNullOrWhiteSpace(requiredAcknowledgmentCode);
 10242        ArgumentException.ThrowIfNullOrWhiteSpace(requiredAcknowledgmentText);
 43
 10244        HandshakeId = handshakeId.Trim();
 10245        SchemaVersion = AsiBackboneSchemaVersions.Normalize(schemaVersion);
 10246        ActorId = actorId.Trim();
 10247        ActorType = actorType;
 10248        ActorDisplayName = NormalizeOptional(actorDisplayName);
 10249        OperationName = operationName.Trim();
 10250        ReasonCode = reasonCode.Trim();
 10251        Message = message.Trim();
 10252        RequiredAcknowledgmentCode = requiredAcknowledgmentCode.Trim();
 10253        RequiredAcknowledgmentText = requiredAcknowledgmentText.Trim();
 10254        RiskLevel = riskLevel;
 10255        RiskCategory = NormalizeOptional(riskCategory);
 10256        CorrelationId = NormalizeOptional(correlationId);
 10257        TraceId = NormalizeOptional(traceId);
 10258        PolicyVersion = NormalizeOptional(policyVersion);
 10259        PolicyHash = NormalizeOptional(policyHash);
 10260        Metadata = metadata;
 10261    }
 62
 63    /// <summary>
 64    /// Gets the stable handshake identifier.
 65    /// </summary>
 8566    public string HandshakeId { get; }
 67
 68    /// <summary>
 69    /// Gets the schema version for the serialized handshake request shape.
 70    /// </summary>
 971    public string SchemaVersion { get; }
 72
 73    /// <summary>
 74    /// Gets the stable actor identifier associated with the handshake.
 75    /// </summary>
 976    public string ActorId { get; }
 77
 78    /// <summary>
 79    /// Gets the actor type associated with the handshake.
 80    /// </summary>
 781    public AsiBackboneActorType ActorType { get; }
 82
 83    /// <summary>
 84    /// Gets the optional display name or label associated with the actor.
 85    /// </summary>
 786    public string? ActorDisplayName { get; }
 87
 88    /// <summary>
 89    /// Gets the operation name requiring acknowledgment.
 90    /// </summary>
 3791    public string OperationName { get; }
 92
 93    /// <summary>
 94    /// Gets the machine-readable reason code explaining why the handshake is required.
 95    /// </summary>
 4196    public string ReasonCode { get; }
 97
 98    /// <summary>
 99    /// Gets the human-readable message explaining why the handshake is required.
 100    /// </summary>
 41101    public string Message { get; }
 102
 103    /// <summary>
 104    /// Gets the required acknowledgment code the host may display or require before execution.
 105    /// </summary>
 80106    public string RequiredAcknowledgmentCode { get; }
 107
 108    /// <summary>
 109    /// Gets the required acknowledgment text the host may display before execution.
 110    /// </summary>
 37111    public string RequiredAcknowledgmentText { get; }
 112
 113    /// <summary>
 114    /// Gets the risk level associated with the handshake.
 115    /// </summary>
 38116    public LiabilityHandshakeRiskLevel RiskLevel { get; }
 117
 118    /// <summary>
 119    /// Gets the optional host-defined risk category associated with the handshake.
 120    /// </summary>
 40121    public string? RiskCategory { get; }
 122
 123    /// <summary>
 124    /// Gets the correlation identifier associated with the handshake, when supplied by the host.
 125    /// </summary>
 85126    public string? CorrelationId { get; }
 127
 128    /// <summary>
 129    /// Gets the trace identifier associated with the handshake, when supplied by the host.
 130    /// </summary>
 65131    public string? TraceId { get; }
 132
 133    /// <summary>
 134    /// Gets the policy version associated with the handshake, when supplied by the host.
 135    /// </summary>
 22136    public string? PolicyVersion { get; }
 137
 138    /// <summary>
 139    /// Gets the policy hash associated with the handshake, when supplied by the host.
 140    /// </summary>
 22141    public string? PolicyHash { get; }
 142
 143    /// <summary>
 144    /// Gets additional framework-neutral handshake metadata supplied by the host.
 145    /// </summary>
 81146    public IReadOnlyDictionary<string, string> Metadata { get; }
 147
 148    /// <summary>
 149    /// Gets a value indicating whether this handshake contains metadata.
 150    /// </summary>
 19151    public bool HasMetadata => Metadata.Count > 0;
 152
 153    /// <summary>
 154    /// Creates a liability or responsibility handshake request.
 155    /// </summary>
 156    /// <param name="actor">The actor associated with the handshake.</param>
 157    /// <param name="operationName">The operation name requiring acknowledgment.</param>
 158    /// <param name="reasonCode">The machine-readable reason code.</param>
 159    /// <param name="message">The human-readable reason message.</param>
 160    /// <param name="requiredAcknowledgmentCode">The required acknowledgment code.</param>
 161    /// <param name="requiredAcknowledgmentText">The required acknowledgment text.</param>
 162    /// <param name="riskLevel">The risk level associated with the handshake.</param>
 163    /// <param name="riskCategory">Optional host-defined risk category.</param>
 164    /// <param name="handshakeId">Optional handshake identifier. When omitted, a new identifier is generated.</param>
 165    /// <param name="correlationId">Optional correlation identifier.</param>
 166    /// <param name="traceId">Optional trace identifier.</param>
 167    /// <param name="policyVersion">Optional policy version.</param>
 168    /// <param name="policyHash">Optional policy hash.</param>
 169    /// <param name="metadata">Optional host-provided metadata.</param>
 170    /// <param name="schemaVersion">Optional schema version for serialized or persisted handshake records.</param>
 171    /// <returns>A liability handshake request.</returns>
 172    public static LiabilityHandshakeRequest Create(
 173        IAsiBackboneActorContext actor,
 174        string operationName,
 175        string reasonCode,
 176        string message,
 177        string requiredAcknowledgmentCode,
 178        string requiredAcknowledgmentText,
 179        LiabilityHandshakeRiskLevel riskLevel = LiabilityHandshakeRiskLevel.Unspecified,
 180        string? riskCategory = null,
 181        string? handshakeId = null,
 182        string? correlationId = null,
 183        string? traceId = null,
 184        string? policyVersion = null,
 185        string? policyHash = null,
 186        IReadOnlyDictionary<string, string>? metadata = null,
 187        string? schemaVersion = null)
 188    {
 116189        ArgumentNullException.ThrowIfNull(actor);
 190
 114191        return new LiabilityHandshakeRequest(
 114192            NormalizeIdentifier(handshakeId),
 114193            schemaVersion,
 114194            actor.ActorId,
 114195            actor.ActorType,
 114196            actor.DisplayName,
 114197            operationName,
 114198            reasonCode,
 114199            message,
 114200            requiredAcknowledgmentCode,
 114201            requiredAcknowledgmentText,
 114202            riskLevel,
 114203            riskCategory,
 114204            correlationId,
 114205            traceId,
 114206            policyVersion,
 114207            policyHash,
 114208            NormalizeMetadata(metadata));
 209    }
 210
 211    /// <summary>
 212    /// Creates a liability or responsibility handshake request from a governance decision.
 213    /// </summary>
 214    /// <param name="actor">The actor associated with the handshake.</param>
 215    /// <param name="operationName">The operation name requiring acknowledgment.</param>
 216    /// <param name="decision">The governance decision requiring acknowledgment.</param>
 217    /// <param name="requiredAcknowledgmentCode">The required acknowledgment code.</param>
 218    /// <param name="requiredAcknowledgmentText">The required acknowledgment text.</param>
 219    /// <param name="riskLevel">The risk level associated with the handshake.</param>
 220    /// <param name="riskCategory">Optional host-defined risk category.</param>
 221    /// <param name="handshakeId">Optional handshake identifier. When omitted, a new identifier is generated.</param>
 222    /// <param name="metadata">Optional host-provided metadata.</param>
 223    /// <param name="schemaVersion">Optional schema version for serialized or persisted handshake records.</param>
 224    /// <returns>A liability handshake request.</returns>
 225    public static LiabilityHandshakeRequest FromDecision(
 226        IAsiBackboneActorContext actor,
 227        string operationName,
 228        GovernanceDecision decision,
 229        string requiredAcknowledgmentCode,
 230        string requiredAcknowledgmentText,
 231        LiabilityHandshakeRiskLevel riskLevel = LiabilityHandshakeRiskLevel.Unspecified,
 232        string? riskCategory = null,
 233        string? handshakeId = null,
 234        IReadOnlyDictionary<string, string>? metadata = null,
 235        string? schemaVersion = null)
 236    {
 30237        ArgumentNullException.ThrowIfNull(decision);
 238
 30239        string reasonCode = decision.ReasonCodes.Count > 0
 30240            ? decision.ReasonCodes[0]
 30241            : "handshake.required";
 242
 30243        string message = decision.Reasons.Count > 0
 30244            ? decision.Reasons[0].Message
 30245            : "Acknowledgment is required before proceeding.";
 246
 30247        return Create(
 30248            actor,
 30249            operationName,
 30250            reasonCode,
 30251            message,
 30252            requiredAcknowledgmentCode,
 30253            requiredAcknowledgmentText,
 30254            riskLevel,
 30255            riskCategory,
 30256            handshakeId,
 30257            decision.CorrelationId,
 30258            decision.TraceId,
 30259            decision.PolicyVersion,
 30260            decision.PolicyHash,
 30261            metadata,
 30262            schemaVersion);
 263    }
 264
 265    private static string NormalizeIdentifier(string? identifier)
 266    {
 114267        return string.IsNullOrWhiteSpace(identifier)
 114268            ? Guid.NewGuid().ToString("N")
 114269            : identifier.Trim();
 270    }
 271
 272    private static string? NormalizeOptional(string? value)
 273    {
 612274        return string.IsNullOrWhiteSpace(value)
 612275            ? null
 612276            : value.Trim();
 277    }
 278
 279    private static IReadOnlyDictionary<string, string> NormalizeMetadata(
 280        IReadOnlyDictionary<string, string>? metadata)
 281    {
 114282        if (metadata is null || metadata.Count == 0)
 283        {
 101284            return EmptyMetadata;
 285        }
 286
 13287        Dictionary<string, string> normalizedMetadata = new(StringComparer.Ordinal);
 288
 74289        foreach (KeyValuePair<string, string> item in metadata)
 290        {
 24291            if (string.IsNullOrWhiteSpace(item.Key))
 292            {
 293                continue;
 294            }
 295
 17296            normalizedMetadata[item.Key.Trim()] = item.Value?.Trim() ?? string.Empty;
 297        }
 298
 13299        return normalizedMetadata.Count == 0
 13300            ? EmptyMetadata
 13301            : new ReadOnlyDictionary<string, string>(normalizedMetadata);
 302    }
 303}

Methods/Properties

.cctor()
.ctor(System.String,System.String,System.String,AsiBackbone.Core.Actors.AsiBackboneActorType,System.String,System.String,System.String,System.String,System.String,System.String,AsiBackbone.Core.Handshakes.LiabilityHandshakeRiskLevel,System.String,System.String,System.String,System.String,System.String,System.Collections.Generic.IReadOnlyDictionary`2<System.String,System.String>)
get_HandshakeId()
get_SchemaVersion()
get_ActorId()
get_ActorType()
get_ActorDisplayName()
get_OperationName()
get_ReasonCode()
get_Message()
get_RequiredAcknowledgmentCode()
get_RequiredAcknowledgmentText()
get_RiskLevel()
get_RiskCategory()
get_CorrelationId()
get_TraceId()
get_PolicyVersion()
get_PolicyHash()
get_Metadata()
get_HasMetadata()
Create(AsiBackbone.Core.Actors.IAsiBackboneActorContext,System.String,System.String,System.String,System.String,System.String,AsiBackbone.Core.Handshakes.LiabilityHandshakeRiskLevel,System.String,System.String,System.String,System.String,System.String,System.String,System.Collections.Generic.IReadOnlyDictionary`2<System.String,System.String>,System.String)
FromDecision(AsiBackbone.Core.Actors.IAsiBackboneActorContext,System.String,AsiBackbone.Core.Decisions.GovernanceDecision,System.String,System.String,AsiBackbone.Core.Handshakes.LiabilityHandshakeRiskLevel,System.String,System.String,System.Collections.Generic.IReadOnlyDictionary`2<System.String,System.String>,System.String)
NormalizeIdentifier(System.String)
NormalizeOptional(System.String)
NormalizeMetadata(System.Collections.Generic.IReadOnlyDictionary`2<System.String,System.String>)