< 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
 10017    private LiabilityHandshakeRequest(
 10018        string handshakeId,
 10019        string? schemaVersion,
 10020        string actorId,
 10021        AsiBackboneActorType actorType,
 10022        string? actorDisplayName,
 10023        string operationName,
 10024        string reasonCode,
 10025        string message,
 10026        string requiredAcknowledgmentCode,
 10027        string requiredAcknowledgmentText,
 10028        LiabilityHandshakeRiskLevel riskLevel,
 10029        string? riskCategory,
 10030        string? correlationId,
 10031        string? traceId,
 10032        string? policyVersion,
 10033        string? policyHash,
 10034        IReadOnlyDictionary<string, string> metadata)
 35    {
 10036        ArgumentException.ThrowIfNullOrWhiteSpace(handshakeId);
 10037        ArgumentException.ThrowIfNullOrWhiteSpace(actorId);
 10038        ArgumentException.ThrowIfNullOrWhiteSpace(operationName);
 9839        ArgumentException.ThrowIfNullOrWhiteSpace(reasonCode);
 9640        ArgumentException.ThrowIfNullOrWhiteSpace(message);
 9641        ArgumentException.ThrowIfNullOrWhiteSpace(requiredAcknowledgmentCode);
 9442        ArgumentException.ThrowIfNullOrWhiteSpace(requiredAcknowledgmentText);
 43
 9444        HandshakeId = handshakeId.Trim();
 9445        SchemaVersion = AsiBackboneSchemaVersions.Normalize(schemaVersion);
 9446        ActorId = actorId.Trim();
 9447        ActorType = actorType;
 9448        ActorDisplayName = NormalizeOptional(actorDisplayName);
 9449        OperationName = operationName.Trim();
 9450        ReasonCode = reasonCode.Trim();
 9451        Message = message.Trim();
 9452        RequiredAcknowledgmentCode = requiredAcknowledgmentCode.Trim();
 9453        RequiredAcknowledgmentText = requiredAcknowledgmentText.Trim();
 9454        RiskLevel = riskLevel;
 9455        RiskCategory = NormalizeOptional(riskCategory);
 9456        CorrelationId = NormalizeOptional(correlationId);
 9457        TraceId = NormalizeOptional(traceId);
 9458        PolicyVersion = NormalizeOptional(policyVersion);
 9459        PolicyHash = NormalizeOptional(policyHash);
 9460        Metadata = metadata;
 9461    }
 62
 63    /// <summary>
 64    /// Gets the stable handshake identifier.
 65    /// </summary>
 8866    public string HandshakeId { get; }
 67
 68    /// <summary>
 69    /// Gets the schema version for the serialized handshake request shape.
 70    /// </summary>
 471    public string SchemaVersion { get; }
 72
 73    /// <summary>
 74    /// Gets the stable actor identifier associated with the handshake.
 75    /// </summary>
 476    public string ActorId { get; }
 77
 78    /// <summary>
 79    /// Gets the actor type associated with the handshake.
 80    /// </summary>
 381    public AsiBackboneActorType ActorType { get; }
 82
 83    /// <summary>
 84    /// Gets the optional display name or label associated with the actor.
 85    /// </summary>
 386    public string? ActorDisplayName { get; }
 87
 88    /// <summary>
 89    /// Gets the operation name requiring acknowledgment.
 90    /// </summary>
 5891    public string OperationName { get; }
 92
 93    /// <summary>
 94    /// Gets the machine-readable reason code explaining why the handshake is required.
 95    /// </summary>
 6096    public string ReasonCode { get; }
 97
 98    /// <summary>
 99    /// Gets the human-readable message explaining why the handshake is required.
 100    /// </summary>
 60101    public string Message { get; }
 102
 103    /// <summary>
 104    /// Gets the required acknowledgment code the host may display or require before execution.
 105    /// </summary>
 84106    public string RequiredAcknowledgmentCode { get; }
 107
 108    /// <summary>
 109    /// Gets the required acknowledgment text the host may display before execution.
 110    /// </summary>
 58111    public string RequiredAcknowledgmentText { get; }
 112
 113    /// <summary>
 114    /// Gets the risk level associated with the handshake.
 115    /// </summary>
 60116    public LiabilityHandshakeRiskLevel RiskLevel { get; }
 117
 118    /// <summary>
 119    /// Gets the optional host-defined risk category associated with the handshake.
 120    /// </summary>
 61121    public string? RiskCategory { get; }
 122
 123    /// <summary>
 124    /// Gets the correlation identifier associated with the handshake, when supplied by the host.
 125    /// </summary>
 88126    public string? CorrelationId { get; }
 127
 128    /// <summary>
 129    /// Gets the trace identifier associated with the handshake, when supplied by the host.
 130    /// </summary>
 50131    public string? TraceId { get; }
 132
 133    /// <summary>
 134    /// Gets the policy version associated with the handshake, when supplied by the host.
 135    /// </summary>
 24136    public string? PolicyVersion { get; }
 137
 138    /// <summary>
 139    /// Gets the policy hash associated with the handshake, when supplied by the host.
 140    /// </summary>
 24141    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>
 9151    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    {
 101189        ArgumentNullException.ThrowIfNull(actor);
 190
 100191        return new LiabilityHandshakeRequest(
 100192            NormalizeIdentifier(handshakeId),
 100193            schemaVersion,
 100194            actor.ActorId,
 100195            actor.ActorType,
 100196            actor.DisplayName,
 100197            operationName,
 100198            reasonCode,
 100199            message,
 100200            requiredAcknowledgmentCode,
 100201            requiredAcknowledgmentText,
 100202            riskLevel,
 100203            riskCategory,
 100204            correlationId,
 100205            traceId,
 100206            policyVersion,
 100207            policyHash,
 100208            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    {
 49237        ArgumentNullException.ThrowIfNull(decision);
 238
 49239        string reasonCode = decision.ReasonCodes.Count > 0
 49240            ? decision.ReasonCodes[0]
 49241            : "handshake.required";
 242
 49243        string message = decision.Reasons.Count > 0
 49244            ? decision.Reasons[0].Message
 49245            : "Acknowledgment is required before proceeding.";
 246
 49247        return Create(
 49248            actor,
 49249            operationName,
 49250            reasonCode,
 49251            message,
 49252            requiredAcknowledgmentCode,
 49253            requiredAcknowledgmentText,
 49254            riskLevel,
 49255            riskCategory,
 49256            handshakeId,
 49257            decision.CorrelationId,
 49258            decision.TraceId,
 49259            decision.PolicyVersion,
 49260            decision.PolicyHash,
 49261            metadata,
 49262            schemaVersion);
 263    }
 264
 265    private static string NormalizeIdentifier(string? identifier)
 266    {
 100267        return string.IsNullOrWhiteSpace(identifier)
 100268            ? Guid.NewGuid().ToString("N")
 100269            : identifier.Trim();
 270    }
 271
 272    private static string? NormalizeOptional(string? value)
 273    {
 564274        return string.IsNullOrWhiteSpace(value)
 564275            ? null
 564276            : value.Trim();
 277    }
 278
 279    private static IReadOnlyDictionary<string, string> NormalizeMetadata(
 280        IReadOnlyDictionary<string, string>? metadata)
 281    {
 100282        if (metadata is null || metadata.Count == 0)
 283        {
 91284            return EmptyMetadata;
 285        }
 286
 9287        Dictionary<string, string> normalizedMetadata = new(StringComparer.Ordinal);
 288
 50289        foreach (KeyValuePair<string, string> item in metadata)
 290        {
 16291            if (string.IsNullOrWhiteSpace(item.Key))
 292            {
 293                continue;
 294            }
 295
 11296            normalizedMetadata[item.Key.Trim()] = item.Value?.Trim() ?? string.Empty;
 297        }
 298
 9299        return normalizedMetadata.Count == 0
 9300            ? EmptyMetadata
 9301            : 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>)