feat(inbound-api): executor threads the trace flag; endpoint honours ApiMethod.TraceAllCalls

Flow Debugger (design 2026-09-05 §5.2): InboundScriptExecutor.ExecuteAsync gains a trailing
trace parameter that builds the script's Route helper WithTrace(trace); the inbound endpoint
passes method.TraceAllCalls so a flagged integration method is traced on every real call.

Claude-Session: https://claude.ai/code/session_01GSLkkHKz9JrAtmJjmQK3cP
This commit is contained in:
Joseph Doherty
2026-09-05 23:59:08 -04:00
parent 3f582a278c
commit 981deed0fd
3 changed files with 39 additions and 3 deletions
@@ -28,6 +28,35 @@ public class InboundScriptExecutorTests
_route = new RouteHelper(locator, router);
}
[Fact]
public async Task ExecuteAsync_TraceFlag_ReachesTheRoutedCallRequest()
{
// Flow Debugger (design 2026-09-05 §5.2): ExecuteAsync(trace: true) builds the script's
// Route helper WithTrace(true), so a Route.To(...).Call(...) inside the script sends a
// traced RouteToCallRequest; the default stays untraced.
var locator = Substitute.For<IInstanceLocator>();
var router = Substitute.For<IInstanceRouter>();
locator.GetSiteIdForInstanceAsync("inst", Arg.Any<CancellationToken>()).Returns("SiteA");
var captured = new List<RouteToCallRequest>();
router.RouteToCallAsync("SiteA", Arg.Do<RouteToCallRequest>(captured.Add), Arg.Any<CancellationToken>())
.Returns(ci => new RouteToCallResponse(((RouteToCallRequest)ci[1]).CorrelationId, true, 1, null, DateTimeOffset.UtcNow));
var route = new RouteHelper(locator, router);
var method = new ApiMethod("routed", "x") { Id = 9, TimeoutSeconds = 10 };
_executor.RegisterHandler("routed", ctx => ctx.Route.To("inst").Call("work"));
var parent = Guid.NewGuid();
var traced = await _executor.ExecuteAsync(method, new Dictionary<string, object?>(), route,
TimeSpan.FromSeconds(10), parentExecutionId: parent, trace: true);
var plain = await _executor.ExecuteAsync(method, new Dictionary<string, object?>(), route, TimeSpan.FromSeconds(10));
Assert.True(traced.Success, traced.ErrorMessage);
Assert.True(plain.Success, plain.ErrorMessage);
Assert.Equal(2, captured.Count);
Assert.True(captured[0].Trace);
Assert.Equal(parent, captured[0].ParentExecutionId);
Assert.False(captured[1].Trace);
}
[Fact]
public async Task RegisteredHandler_ExecutesSuccessfully()
{