feat(site-runtime): outbound API/DB/notification audit rows ride the flow-trace collector
ScriptRuntimeContext caches a trace sink (null on an untraced run, so the production path is byte-identical) and threads it into the ExternalSystem / Database / Notify helpers and AuditingDbConnection→AuditingDbCommand (onAudit). All eight outbound emit sites hand the SAME AuditEvent instance to the sink first, then to the writer/forwarder. FlowTraceCollector gains Completed + Complete(): ScriptRunLauncher closes the collector where it builds the reply snapshot, so un-awaited calls finishing after the run returned never mutate a list the reply was built from. Cap (500) unchanged. Plan 2026-09-06 D5. Claude-Session: https://claude.ai/code/session_01NcMG6xXdsJbmD2wYAgkK29
This commit is contained in:
@@ -2,6 +2,7 @@ using System.Data;
|
||||
using System.Data.Common;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Services;
|
||||
using AuditEvent = ZB.MOM.WW.Audit.AuditEvent;
|
||||
|
||||
namespace ZB.MOM.WW.ScadaBridge.SiteRuntime.Scripts;
|
||||
|
||||
@@ -46,6 +47,13 @@ internal sealed class AuditingDbConnection : DbConnection
|
||||
/// </summary>
|
||||
private readonly Guid? _parentExecutionId;
|
||||
|
||||
/// <summary>
|
||||
/// Flow Debugger (plan 2026-09-06 D5): optional observer handed the SAME
|
||||
/// <see cref="AuditEvent"/> each <see cref="AuditingDbCommand"/> gives the writer —
|
||||
/// the run's inline trace collector. Null when untraced.
|
||||
/// </summary>
|
||||
private readonly Action<AuditEvent>? _onAudit;
|
||||
|
||||
private readonly ILogger _logger;
|
||||
|
||||
/// <summary>
|
||||
@@ -60,6 +68,7 @@ internal sealed class AuditingDbConnection : DbConnection
|
||||
/// <param name="logger">Logger for diagnostics and warnings.</param>
|
||||
/// <param name="executionId">Unique identifier for this script execution.</param>
|
||||
/// <param name="parentExecutionId">Optional identifier of the parent execution (for routed calls).</param>
|
||||
/// <param name="onAudit">Optional observer of every emitted <see cref="AuditEvent"/> (the Flow Debugger trace collector).</param>
|
||||
// Parameter ordering: executionId sits immediately after the ILogger,
|
||||
// consistent with the other three audit-threaded ctors (ExternalSystemHelper,
|
||||
// DatabaseHelper, AuditingDbCommand). parentExecutionId is a trailing
|
||||
@@ -73,7 +82,8 @@ internal sealed class AuditingDbConnection : DbConnection
|
||||
string? sourceScript,
|
||||
ILogger logger,
|
||||
Guid executionId,
|
||||
Guid? parentExecutionId = null)
|
||||
Guid? parentExecutionId = null,
|
||||
Action<AuditEvent>? onAudit = null)
|
||||
{
|
||||
_inner = inner ?? throw new ArgumentNullException(nameof(inner));
|
||||
_auditWriter = auditWriter ?? throw new ArgumentNullException(nameof(auditWriter));
|
||||
@@ -84,6 +94,7 @@ internal sealed class AuditingDbConnection : DbConnection
|
||||
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
_executionId = executionId;
|
||||
_parentExecutionId = parentExecutionId;
|
||||
_onAudit = onAudit;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -155,7 +166,9 @@ internal sealed class AuditingDbConnection : DbConnection
|
||||
_executionId,
|
||||
// ParentExecutionId: the spawning execution's id,
|
||||
// threaded alongside _executionId. Null for non-routed runs.
|
||||
_parentExecutionId);
|
||||
_parentExecutionId,
|
||||
// Flow Debugger: the DbWrite rows ride the inline collector.
|
||||
_onAudit);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
Reference in New Issue
Block a user