feat(auditlog): AuditLogIngestActor + gRPC handler (#23)

This commit is contained in:
Joseph Doherty
2026-05-20 12:48:26 -04:00
parent b679430d13
commit 87cae88f92
6 changed files with 579 additions and 0 deletions

View File

@@ -0,0 +1,20 @@
using ScadaLink.Commons.Entities.Audit;
namespace ScadaLink.Commons.Messages.Audit;
/// <summary>
/// Akka message sent to the central <c>AuditLogIngestActor</c> (Audit Log #23,
/// M2 site-sync pipeline) carrying a batch of <see cref="AuditEvent"/> rows
/// decoded by the <c>SiteStreamGrpcServer</c> from a site's
/// <c>IngestAuditEvents</c> gRPC RPC. The actor stamps
/// <see cref="AuditEvent.IngestedAtUtc"/> and writes the rows idempotently to
/// the central <c>AuditLog</c> table.
/// </summary>
/// <remarks>
/// Lives in <c>ScadaLink.Commons</c> rather than <c>ScadaLink.AuditLog</c>
/// because the gRPC server in <c>ScadaLink.Communication</c> needs to construct
/// it, and <c>ScadaLink.AuditLog</c> already references
/// <c>ScadaLink.Communication</c> (the proto DTOs live there). Putting the
/// message in Commons avoids a project-reference cycle.
/// </remarks>
public sealed record IngestAuditEventsCommand(IReadOnlyList<AuditEvent> Events);

View File

@@ -0,0 +1,11 @@
namespace ScadaLink.Commons.Messages.Audit;
/// <summary>
/// Reply from the central <c>AuditLogIngestActor</c> for an
/// <see cref="IngestAuditEventsCommand"/>. <see cref="AcceptedEventIds"/> lists
/// every row the actor considers durably persisted at central — including ids
/// that were already present before the call (first-write-wins idempotency).
/// The gRPC handler echoes these ids back over the wire as the <c>IngestAck</c>
/// the site uses to flip rows to <c>Forwarded</c>.
/// </summary>
public sealed record IngestAuditEventsReply(IReadOnlyList<Guid> AcceptedEventIds);