feat(audit): replay/pull include outbound API, DB and notification rows
GetTraceEventsAsync widens its channel filter to ScriptTrace ∪ ApiOutbound ∪ DbOutbound ∪ Notification ∪ (ApiInbound & InboundRequest) (plan D6); SecuredWrite, Cluster and InboundAuthFailure rows in the same tree stay excluded. The site SqliteAuditWriter.ReadByExecutionIdsAsync already had no channel predicate — pinned by a test. Interface doc updated to match. Claude-Session: https://claude.ai/code/session_01NcMG6xXdsJbmD2wYAgkK29
This commit is contained in:
+31
@@ -72,6 +72,37 @@ public class SqliteAuditWriterReadByExecutionTests : IDisposable
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Outbound-calls plan (2026-09-06, D6): the site pull filters by execution id ONLY — an
|
||||
/// ApiOutbound row (or any other channel) stored under the execution id is served alongside
|
||||
/// the ScriptTrace rows, in time order. Pins that no channel predicate creeps in.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public async Task ServesOutboundRows_NoChannelPredicate()
|
||||
{
|
||||
var root = Guid.NewGuid();
|
||||
var siteRun = Guid.NewGuid();
|
||||
var run = Row(T0.AddSeconds(1), siteRun, root);
|
||||
var apiCall = ScadaBridgeAuditEventFactory.Create(AuditChannel.ApiOutbound, AuditKind.CachedSubmit, AuditStatus.Submitted,
|
||||
occurredAtUtc: T0.AddSeconds(2), target: "Delmia.AckRecipe", executionId: siteRun, parentExecutionId: root,
|
||||
sourceSiteId: "site-a", correlationId: Guid.NewGuid());
|
||||
var dbWrite = ScadaBridgeAuditEventFactory.Create(AuditChannel.DbOutbound, AuditKind.DbWrite, AuditStatus.Delivered,
|
||||
occurredAtUtc: T0.AddSeconds(3), target: "MesDb", executionId: siteRun, parentExecutionId: root, sourceSiteId: "site-a");
|
||||
var notify = ScadaBridgeAuditEventFactory.Create(AuditChannel.Notification, AuditKind.NotifySend, AuditStatus.Submitted,
|
||||
occurredAtUtc: T0.AddSeconds(4), target: "Planners", executionId: siteRun, parentExecutionId: root,
|
||||
sourceSiteId: "site-a", correlationId: Guid.NewGuid());
|
||||
|
||||
await using var writer = CreateWriter();
|
||||
foreach (var r in new[] { notify, apiCall, run, dbWrite }) await writer.WriteAsync(r);
|
||||
|
||||
var hits = await writer.ReadByExecutionIdsAsync([siteRun], T0, limit: 100);
|
||||
Assert.Equal(
|
||||
new[] { run.EventId, apiCall.EventId, dbWrite.EventId, notify.EventId },
|
||||
hits.Select(h => h.EventId).ToArray());
|
||||
Assert.Equal(apiCall, hits[1]);
|
||||
Assert.Equal(AuditChannel.ApiOutbound, AuditRowProjection.Decompose(hits[1]).Channel);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Guards_LimitAndIdCap()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user