Files
nexus/backend/Services/OperationResultFactory.cs
AzuTear f5552218bc
CI - Build & Test / Backend (.NET) (push) Successful in 42s
CI - Build & Test / Frontend (Vue/TS) (push) Successful in 2m46s
CI - Build & Test / Security Check (push) Successful in 3s
CI - Build & Test / Deploy Nexus (push) Successful in 56s
feat: ship agent-first mission control v0.2.57
2026-07-31 22:39:47 +02:00

90 lines
2.9 KiB
C#

using System.Diagnostics;
using Microsoft.AspNetCore.Http;
using Nexus.Api.Models;
namespace Nexus.Api.Services;
/// <summary>
/// Builds the transport-safe result metadata shared by browser, bridge and
/// OpenClaw mutation responses. URLs deliberately remain a frontend concern.
/// </summary>
public static class OperationResultFactory
{
private const int MaxOperationIdLength = 128;
public static OperationResultDto FromHttpContext(
HttpContext context,
string status,
EntityRefDto? primaryRef,
int revision = 0,
IEnumerable<EntityRefDto>? affectedRefs = null)
{
var requestedCorrelation = context.Request.Headers["X-Correlation-ID"]
.FirstOrDefault();
var operationId = IsSafeIdentifier(requestedCorrelation)
? requestedCorrelation!.Trim()
: IsSafeIdentifier(context.TraceIdentifier)
? context.TraceIdentifier.Trim()
: Guid.NewGuid().ToString("N");
var traceId = Activity.Current?.Id;
if (string.IsNullOrWhiteSpace(traceId))
{
var traceParent = context.Request.Headers["traceparent"].FirstOrDefault();
traceId = IsSafeIdentifier(traceParent) ? traceParent!.Trim() : null;
}
context.Response.Headers["X-Correlation-ID"] = operationId;
return Create(
operationId,
status,
revision,
primaryRef,
affectedRefs,
traceId);
}
public static OperationResultDto FromInvocation(
OpenClawInvocationContext context,
string status,
EntityRefDto? primaryRef,
int revision = 0,
IEnumerable<EntityRefDto>? affectedRefs = null)
=> Create(
context.CorrelationId,
status,
revision,
primaryRef,
affectedRefs,
Activity.Current?.Id ?? context.TraceParent);
public static OperationResultDto Create(
string operationId,
string status,
int revision,
EntityRefDto? primaryRef,
IEnumerable<EntityRefDto>? affectedRefs = null,
string? traceId = null)
{
var uniqueAffected = (affectedRefs ?? [])
.Where(reference =>
primaryRef is null ||
!string.Equals(reference.Type, primaryRef.Type, StringComparison.Ordinal) ||
!string.Equals(reference.Id, primaryRef.Id, StringComparison.Ordinal))
.DistinctBy(reference => (reference.Type, reference.Id))
.ToArray();
return new OperationResultDto(
operationId,
status,
Math.Max(0, revision),
primaryRef,
uniqueAffected,
traceId);
}
private static bool IsSafeIdentifier(string? value)
=> !string.IsNullOrWhiteSpace(value)
&& value.Length <= MaxOperationIdLength
&& !value.Any(char.IsControl);
}