using ZB.MOM.WW.Audit; namespace ZB.MOM.WW.MxGateway.Server.Security.Audit; /// /// Best-effort over the MxGateway-owned /// . It honours the canonical /// contract: a failed audit write is swallowed and logged /// rather than propagated, so it can never abort the user-facing action that produced it. /// /// /// This is the single sink through which ALL MxGateway audit flows — the library admin /// verbs (via ) and the gateway's own /// dashboard / constraint-denial producers, which write canonical events directly. The /// best-effort wrapping here also closes the gap that the library's /// SqliteApiKeyAuditStore.AppendAsync propagated exceptions. /// public sealed class CanonicalAuditWriter( SqliteCanonicalAuditStore store, ILogger logger) : IAuditWriter { /// public async Task WriteAsync(AuditEvent auditEvent, CancellationToken cancellationToken = default) { ArgumentNullException.ThrowIfNull(auditEvent); try { await store.InsertAsync(auditEvent, cancellationToken).ConfigureAwait(false); } catch (Exception exception) { // Best-effort: a failed audit write must never abort the action that produced it. // Swallow everything (including OperationCanceledException) and log for diagnosis. logger.LogWarning( exception, "Failed to persist audit event {EventId} (action {Action}); audit write is best-effort and was suppressed.", auditEvent.EventId, auditEvent.Action); } } }