< Summary

Information
Class: AsiBackbone.Core.Audit.DecisionReceiptBuilder
Assembly: AsiBackbone.Core
File(s): /home/runner/work/AsiBackbone/AsiBackbone/src/AsiBackbone.Core/Audit/DecisionReceiptBuilder.cs
Line coverage
100%
Covered lines: 114
Uncovered lines: 0
Coverable lines: 114
Total lines: 392
Line coverage: 100%
Branch coverage
100%
Covered branches: 10
Total branches: 10
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
Create(...)100%11100%
FromDecision(...)100%11100%
FromConstraint(...)100%11100%
WithEventId(...)100%11100%
WithOccurredUtc(...)100%11100%
WithReasonCodes(...)100%22100%
AddReasonCode(...)100%11100%
WithCorrelationId(...)100%11100%
WithTraceId(...)100%11100%
WithPolicyVersion(...)100%11100%
WithPolicyHash(...)100%11100%
WithMetadata(...)100%66100%
AddMetadata(...)100%22100%
WithDecisionReceiptId(...)100%11100%
WithSpanId(...)100%11100%
WithParentSpanId(...)100%11100%
WithDecisionLatencyMs(...)100%11100%
WithConstraintSetHash(...)100%11100%
WithConstraintCount(...)100%11100%
WithRiskScore(...)100%11100%
WithPolicyScope(...)100%11100%
WithTenantHash(...)100%11100%
WithOrganizationHash(...)100%11100%
WithEmitterStatus(...)100%11100%
WithEmitterProvider(...)100%11100%
WithOutboxSequence(...)100%11100%
WithGatewayExecutionId(...)100%11100%
WithDecisionStage(...)100%11100%
WithSchemaVersion(...)100%11100%
Build()100%11100%

File(s)

/home/runner/work/AsiBackbone/AsiBackbone/src/AsiBackbone.Core/Audit/DecisionReceiptBuilder.cs

#LineLine coverage
 1using AsiBackbone.Core.Actors;
 2using AsiBackbone.Core.Constraints;
 3using AsiBackbone.Core.Decisions;
 4using AsiBackbone.Core.Signing;
 5
 6namespace AsiBackbone.Core.Audit;
 7
 8/// <summary>
 9/// Provides a fluent construction path for complex <see cref="DecisionReceipt" /> values.
 10/// </summary>
 11/// <remarks>
 12/// The builder is intended for ergonomic object creation in host code, samples, and tests. It preserves the immutable
 13/// <see cref="DecisionReceipt" /> value model by producing a new residue when <see cref="Build" /> is called.
 14/// </remarks>
 15public sealed class DecisionReceiptBuilder
 16{
 17    private readonly IGovernanceActorContext actor;
 18    private readonly string operationName;
 19    private readonly string outcome;
 2920    private readonly List<string> reasonCodes = [];
 21
 22    private Dictionary<string, string>? metadata;
 23    private string? eventId;
 24    private DateTimeOffset? occurredUtc;
 25    private string? correlationId;
 26    private string? traceId;
 27    private string? policyVersion;
 28    private string? policyHash;
 29    private string? decisionReceiptId;
 30    private string? spanId;
 31    private string? parentSpanId;
 32    private long? decisionLatencyMs;
 33    private string? constraintSetHash;
 34    private int? constraintCount;
 35    private double? riskScore;
 36    private string? policyScope;
 37    private string? tenantHash;
 38    private string? organizationHash;
 39    private string? emitterStatus;
 40    private string? emitterProvider;
 41    private long? outboxSequence;
 42    private string? gatewayExecutionId;
 43    private string? decisionStage;
 44    private string? schemaVersion;
 45
 2946    private DecisionReceiptBuilder(
 2947        IGovernanceActorContext actor,
 2948        string operationName,
 2949        string outcome,
 2950        IEnumerable<string>? reasonCodes = null)
 51    {
 2952        ArgumentNullException.ThrowIfNull(actor);
 53
 2954        this.actor = actor;
 2955        this.operationName = operationName;
 2956        this.outcome = outcome;
 2957        _ = WithReasonCodes(reasonCodes);
 2958    }
 59
 60    /// <summary>
 61    /// Creates a builder for a host-defined audit outcome.
 62    /// </summary>
 63    public static DecisionReceiptBuilder Create(
 64        IGovernanceActorContext actor,
 65        string operationName,
 66        string outcome)
 67    {
 868        return new DecisionReceiptBuilder(actor, operationName, outcome);
 69    }
 70
 71    /// <summary>
 72    /// Creates a builder initialized from a governance decision.
 73    /// </summary>
 74    public static DecisionReceiptBuilder FromDecision(
 75        IGovernanceActorContext actor,
 76        string operationName,
 77        GovernanceDecision decision)
 78    {
 1779        ArgumentNullException.ThrowIfNull(decision);
 80
 1681        return new DecisionReceiptBuilder(
 1682            actor,
 1683            operationName,
 1684            CanonicalEnumWireNames.ForDecisionOutcome(decision.Outcome),
 1685            decision.ReasonCodes)
 1686            .WithCorrelationId(decision.CorrelationId)
 1687            .WithTraceId(decision.TraceId)
 1688            .WithPolicyVersion(decision.PolicyVersion)
 1689            .WithPolicyHash(decision.PolicyHash);
 90    }
 91
 92    /// <summary>
 93    /// Creates a builder initialized from a constraint evaluation result.
 94    /// </summary>
 95    public static DecisionReceiptBuilder FromConstraint(
 96        IGovernanceActorContext actor,
 97        string operationName,
 98        ConstraintEvaluationResult constraintResult)
 99    {
 6100        ArgumentNullException.ThrowIfNull(constraintResult);
 101
 5102        return new DecisionReceiptBuilder(
 5103            actor,
 5104            operationName,
 5105            CanonicalEnumWireNames.ForConstraintOutcome(constraintResult.Outcome),
 5106            constraintResult.ReasonCodes);
 107    }
 108
 109    /// <summary>
 110    /// Sets the audit event identifier.
 111    /// </summary>
 112    public DecisionReceiptBuilder WithEventId(string? value)
 113    {
 22114        eventId = value;
 22115        return this;
 116    }
 117
 118    /// <summary>
 119    /// Sets the event occurrence timestamp.
 120    /// </summary>
 121    public DecisionReceiptBuilder WithOccurredUtc(DateTimeOffset? value)
 122    {
 12123        occurredUtc = value;
 12124        return this;
 125    }
 126
 127    /// <summary>
 128    /// Replaces the reason-code collection.
 129    /// </summary>
 130    public DecisionReceiptBuilder WithReasonCodes(IEnumerable<string>? values)
 131    {
 29132        reasonCodes.Clear();
 133
 29134        if (values is not null)
 135        {
 21136            reasonCodes.AddRange(values);
 137        }
 138
 29139        return this;
 140    }
 141
 142    /// <summary>
 143    /// Adds one reason code to the builder.
 144    /// </summary>
 145    public DecisionReceiptBuilder AddReasonCode(string value)
 146    {
 4147        reasonCodes.Add(value);
 4148        return this;
 149    }
 150
 151    /// <summary>
 152    /// Sets the correlation identifier.
 153    /// </summary>
 154    public DecisionReceiptBuilder WithCorrelationId(string? value)
 155    {
 27156        correlationId = value;
 27157        return this;
 158    }
 159
 160    /// <summary>
 161    /// Sets the trace identifier.
 162    /// </summary>
 163    public DecisionReceiptBuilder WithTraceId(string? value)
 164    {
 27165        traceId = value;
 27166        return this;
 167    }
 168
 169    /// <summary>
 170    /// Sets the policy version.
 171    /// </summary>
 172    public DecisionReceiptBuilder WithPolicyVersion(string? value)
 173    {
 18174        policyVersion = value;
 18175        return this;
 176    }
 177
 178    /// <summary>
 179    /// Sets the policy hash.
 180    /// </summary>
 181    public DecisionReceiptBuilder WithPolicyHash(string? value)
 182    {
 18183        policyHash = value;
 18184        return this;
 185    }
 186
 187    /// <summary>
 188    /// Replaces the metadata collection.
 189    /// </summary>
 190    public DecisionReceiptBuilder WithMetadata(IReadOnlyDictionary<string, string>? values)
 191    {
 15192        metadata = null;
 193
 15194        if (values is not null)
 195        {
 46196            foreach (KeyValuePair<string, string> item in values)
 197            {
 9198                (metadata ??= new Dictionary<string, string>(StringComparer.Ordinal))[item.Key] = item.Value;
 199            }
 200        }
 201
 15202        return this;
 203    }
 204
 205    /// <summary>
 206    /// Adds or replaces one metadata value.
 207    /// </summary>
 208    public DecisionReceiptBuilder AddMetadata(string key, string value)
 209    {
 8210        (metadata ??= new Dictionary<string, string>(StringComparer.Ordinal))[key] = value;
 8211        return this;
 212    }
 213
 214    /// <summary>
 215    /// Sets the stable decision receipt identifier.
 216    /// </summary>
 217    public DecisionReceiptBuilder WithDecisionReceiptId(string? value)
 218    {
 2219        decisionReceiptId = value;
 2220        return this;
 221    }
 222
 223    /// <summary>
 224    /// Sets the span identifier.
 225    /// </summary>
 226    public DecisionReceiptBuilder WithSpanId(string? value)
 227    {
 2228        spanId = value;
 2229        return this;
 230    }
 231
 232    /// <summary>
 233    /// Sets the parent span identifier.
 234    /// </summary>
 235    public DecisionReceiptBuilder WithParentSpanId(string? value)
 236    {
 2237        parentSpanId = value;
 2238        return this;
 239    }
 240
 241    /// <summary>
 242    /// Sets the decision latency in milliseconds.
 243    /// </summary>
 244    public DecisionReceiptBuilder WithDecisionLatencyMs(long? value)
 245    {
 2246        decisionLatencyMs = value;
 2247        return this;
 248    }
 249
 250    /// <summary>
 251    /// Sets the evaluated constraint-set hash.
 252    /// </summary>
 253    public DecisionReceiptBuilder WithConstraintSetHash(string? value)
 254    {
 2255        constraintSetHash = value;
 2256        return this;
 257    }
 258
 259    /// <summary>
 260    /// Sets the evaluated constraint count.
 261    /// </summary>
 262    public DecisionReceiptBuilder WithConstraintCount(int? value)
 263    {
 2264        constraintCount = value;
 2265        return this;
 266    }
 267
 268    /// <summary>
 269    /// Sets the host-defined risk score.
 270    /// </summary>
 271    public DecisionReceiptBuilder WithRiskScore(double? value)
 272    {
 2273        riskScore = value;
 2274        return this;
 275    }
 276
 277    /// <summary>
 278    /// Sets the host-defined policy scope.
 279    /// </summary>
 280    public DecisionReceiptBuilder WithPolicyScope(string? value)
 281    {
 2282        policyScope = value;
 2283        return this;
 284    }
 285
 286    /// <summary>
 287    /// Sets the privacy-preserving tenant hash.
 288    /// </summary>
 289    public DecisionReceiptBuilder WithTenantHash(string? value)
 290    {
 2291        tenantHash = value;
 2292        return this;
 293    }
 294
 295    /// <summary>
 296    /// Sets the privacy-preserving organization hash.
 297    /// </summary>
 298    public DecisionReceiptBuilder WithOrganizationHash(string? value)
 299    {
 2300        organizationHash = value;
 2301        return this;
 302    }
 303
 304    /// <summary>
 305    /// Sets the provider-neutral emitter status.
 306    /// </summary>
 307    public DecisionReceiptBuilder WithEmitterStatus(string? value)
 308    {
 2309        emitterStatus = value;
 2310        return this;
 311    }
 312
 313    /// <summary>
 314    /// Sets the provider-neutral emitter provider name.
 315    /// </summary>
 316    public DecisionReceiptBuilder WithEmitterProvider(string? value)
 317    {
 2318        emitterProvider = value;
 2319        return this;
 320    }
 321
 322    /// <summary>
 323    /// Sets the outbox sequence.
 324    /// </summary>
 325    public DecisionReceiptBuilder WithOutboxSequence(long? value)
 326    {
 2327        outboxSequence = value;
 2328        return this;
 329    }
 330
 331    /// <summary>
 332    /// Sets the gateway execution identifier.
 333    /// </summary>
 334    public DecisionReceiptBuilder WithGatewayExecutionId(string? value)
 335    {
 2336        gatewayExecutionId = value;
 2337        return this;
 338    }
 339
 340    /// <summary>
 341    /// Sets the provider-neutral decision stage.
 342    /// </summary>
 343    public DecisionReceiptBuilder WithDecisionStage(string? value)
 344    {
 2345        decisionStage = value;
 2346        return this;
 347    }
 348
 349    /// <summary>
 350    /// Sets the decision receipt schema version.
 351    /// </summary>
 352    public DecisionReceiptBuilder WithSchemaVersion(string? value)
 353    {
 2354        schemaVersion = value;
 2355        return this;
 356    }
 357
 358    /// <summary>
 359    /// Builds an immutable decision receipt value.
 360    /// </summary>
 361    public DecisionReceipt Build()
 362    {
 31363        return DecisionReceipt.Create(
 31364            actor,
 31365            operationName,
 31366            outcome,
 31367            reasonCodes,
 31368            eventId,
 31369            occurredUtc,
 31370            correlationId,
 31371            traceId,
 31372            policyVersion,
 31373            policyHash,
 31374            metadata,
 31375            decisionReceiptId,
 31376            spanId,
 31377            parentSpanId,
 31378            decisionLatencyMs,
 31379            constraintSetHash,
 31380            constraintCount,
 31381            riskScore,
 31382            policyScope,
 31383            tenantHash,
 31384            organizationHash,
 31385            emitterStatus,
 31386            emitterProvider,
 31387            outboxSequence,
 31388            gatewayExecutionId,
 31389            decisionStage,
 31390            schemaVersion);
 391    }
 392}

Methods/Properties

.ctor(AsiBackbone.Core.Actors.IGovernanceActorContext,System.String,System.String,System.Collections.Generic.IEnumerable`1<System.String>)
Create(AsiBackbone.Core.Actors.IGovernanceActorContext,System.String,System.String)
FromDecision(AsiBackbone.Core.Actors.IGovernanceActorContext,System.String,AsiBackbone.Core.Decisions.GovernanceDecision)
FromConstraint(AsiBackbone.Core.Actors.IGovernanceActorContext,System.String,AsiBackbone.Core.Constraints.ConstraintEvaluationResult)
WithEventId(System.String)
WithOccurredUtc(System.Nullable`1<System.DateTimeOffset>)
WithReasonCodes(System.Collections.Generic.IEnumerable`1<System.String>)
AddReasonCode(System.String)
WithCorrelationId(System.String)
WithTraceId(System.String)
WithPolicyVersion(System.String)
WithPolicyHash(System.String)
WithMetadata(System.Collections.Generic.IReadOnlyDictionary`2<System.String,System.String>)
AddMetadata(System.String,System.String)
WithDecisionReceiptId(System.String)
WithSpanId(System.String)
WithParentSpanId(System.String)
WithDecisionLatencyMs(System.Nullable`1<System.Int64>)
WithConstraintSetHash(System.String)
WithConstraintCount(System.Nullable`1<System.Int32>)
WithRiskScore(System.Nullable`1<System.Double>)
WithPolicyScope(System.String)
WithTenantHash(System.String)
WithOrganizationHash(System.String)
WithEmitterStatus(System.String)
WithEmitterProvider(System.String)
WithOutboxSequence(System.Nullable`1<System.Int64>)
WithGatewayExecutionId(System.String)
WithDecisionStage(System.String)
WithSchemaVersion(System.String)
Build()