using System.Diagnostics; using Microsoft.AspNetCore.Http; using Nexus.Api.Models; namespace Nexus.Api.Services; /// /// Builds the transport-safe result metadata shared by browser, bridge and /// OpenClaw mutation responses. URLs deliberately remain a frontend concern. /// public static class OperationResultFactory { private const int MaxOperationIdLength = 128; public static OperationResultDto FromHttpContext( HttpContext context, string status, EntityRefDto? primaryRef, int revision = 0, IEnumerable? 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? 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? 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); }