feat(auditlog): ExecutionId on site SQLite schema + gRPC AuditEventDto
This commit is contained in:
@@ -41,9 +41,9 @@ public class SqliteAuditWriterSchemaTests
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Opens_Creates_AuditLog_Table_With_20Columns_And_PK_On_EventId()
|
||||
public void Opens_Creates_AuditLog_Table_With_21Columns_And_PK_On_EventId()
|
||||
{
|
||||
var (writer, dataSource) = CreateWriter(nameof(Opens_Creates_AuditLog_Table_With_20Columns_And_PK_On_EventId));
|
||||
var (writer, dataSource) = CreateWriter(nameof(Opens_Creates_AuditLog_Table_With_21Columns_And_PK_On_EventId));
|
||||
using (writer)
|
||||
{
|
||||
using var connection = OpenVerifierConnection(dataSource);
|
||||
@@ -57,7 +57,7 @@ public class SqliteAuditWriterSchemaTests
|
||||
columns.Add((reader.GetString(1), reader.GetInt32(5)));
|
||||
}
|
||||
|
||||
Assert.Equal(20, columns.Count);
|
||||
Assert.Equal(21, columns.Count);
|
||||
|
||||
var expected = new[]
|
||||
{
|
||||
@@ -65,7 +65,7 @@ public class SqliteAuditWriterSchemaTests
|
||||
"SourceSiteId", "SourceInstanceId", "SourceScript", "Actor", "Target",
|
||||
"Status", "HttpStatus", "DurationMs", "ErrorMessage", "ErrorDetail",
|
||||
"RequestSummary", "ResponseSummary", "PayloadTruncated", "Extra",
|
||||
"ForwardState",
|
||||
"ForwardState", "ExecutionId",
|
||||
};
|
||||
Assert.Equal(expected.OrderBy(n => n), columns.Select(c => c.Name).OrderBy(n => n));
|
||||
|
||||
|
||||
@@ -353,4 +353,37 @@ public class SqliteAuditWriterWriteTests
|
||||
await writer.MarkReconciledAsync(new[] { Guid.NewGuid(), Guid.NewGuid() });
|
||||
// Completes without throwing.
|
||||
}
|
||||
|
||||
// ----- ExecutionId column (universal per-run correlation value) ----- //
|
||||
|
||||
[Fact]
|
||||
public async Task WriteAsync_NonNullExecutionId_RoundTripsThroughMapRow()
|
||||
{
|
||||
var (writer, _) = CreateWriter(nameof(WriteAsync_NonNullExecutionId_RoundTripsThroughMapRow));
|
||||
await using var _w = writer;
|
||||
|
||||
var executionId = Guid.NewGuid();
|
||||
var evt = NewEvent() with { ExecutionId = executionId };
|
||||
await writer.WriteAsync(evt);
|
||||
|
||||
var rows = await writer.ReadPendingAsync(limit: 10);
|
||||
|
||||
var row = Assert.Single(rows);
|
||||
Assert.Equal(executionId, row.ExecutionId);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task WriteAsync_NullExecutionId_RoundTripsAsNull()
|
||||
{
|
||||
var (writer, _) = CreateWriter(nameof(WriteAsync_NullExecutionId_RoundTripsAsNull));
|
||||
await using var _w = writer;
|
||||
|
||||
var evt = NewEvent() with { ExecutionId = null };
|
||||
await writer.WriteAsync(evt);
|
||||
|
||||
var rows = await writer.ReadPendingAsync(limit: 10);
|
||||
|
||||
var row = Assert.Single(rows);
|
||||
Assert.Null(row.ExecutionId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ public class AuditEventDtoMapperTests
|
||||
var occurredAt = new DateTime(2026, 5, 20, 10, 15, 30, 123, DateTimeKind.Utc);
|
||||
var ingestedAt = new DateTime(2026, 5, 20, 10, 15, 31, 0, DateTimeKind.Utc);
|
||||
var correlationId = Guid.NewGuid();
|
||||
var executionId = Guid.NewGuid();
|
||||
var eventId = Guid.NewGuid();
|
||||
|
||||
var original = new AuditEvent
|
||||
@@ -29,6 +30,7 @@ public class AuditEventDtoMapperTests
|
||||
Channel = AuditChannel.ApiOutbound,
|
||||
Kind = AuditKind.ApiCallCached,
|
||||
CorrelationId = correlationId,
|
||||
ExecutionId = executionId,
|
||||
SourceSiteId = "site-1",
|
||||
SourceInstanceId = "Pump01",
|
||||
SourceScript = "OnDemand",
|
||||
@@ -54,6 +56,7 @@ public class AuditEventDtoMapperTests
|
||||
Assert.Equal(original.Channel, roundTripped.Channel);
|
||||
Assert.Equal(original.Kind, roundTripped.Kind);
|
||||
Assert.Equal(original.CorrelationId, roundTripped.CorrelationId);
|
||||
Assert.Equal(original.ExecutionId, roundTripped.ExecutionId);
|
||||
Assert.Equal(original.SourceSiteId, roundTripped.SourceSiteId);
|
||||
Assert.Equal(original.SourceInstanceId, roundTripped.SourceInstanceId);
|
||||
Assert.Equal(original.SourceScript, roundTripped.SourceScript);
|
||||
@@ -90,6 +93,7 @@ public class AuditEventDtoMapperTests
|
||||
var dto = AuditEventDtoMapper.ToDto(evt);
|
||||
|
||||
Assert.Equal(string.Empty, dto.CorrelationId);
|
||||
Assert.Equal(string.Empty, dto.ExecutionId);
|
||||
Assert.Equal(string.Empty, dto.SourceSiteId);
|
||||
Assert.Equal(string.Empty, dto.SourceInstanceId);
|
||||
Assert.Equal(string.Empty, dto.SourceScript);
|
||||
@@ -113,6 +117,7 @@ public class AuditEventDtoMapperTests
|
||||
Kind = nameof(AuditKind.ApiCall),
|
||||
Status = nameof(AuditStatus.Submitted),
|
||||
CorrelationId = string.Empty,
|
||||
ExecutionId = string.Empty,
|
||||
SourceSiteId = string.Empty,
|
||||
SourceInstanceId = string.Empty,
|
||||
SourceScript = string.Empty,
|
||||
@@ -128,6 +133,7 @@ public class AuditEventDtoMapperTests
|
||||
var evt = AuditEventDtoMapper.FromDto(dto);
|
||||
|
||||
Assert.Null(evt.CorrelationId);
|
||||
Assert.Null(evt.ExecutionId);
|
||||
Assert.Null(evt.SourceSiteId);
|
||||
Assert.Null(evt.SourceInstanceId);
|
||||
Assert.Null(evt.SourceScript);
|
||||
|
||||
Reference in New Issue
Block a user