namespace ZB.MOM.WW.OtOpcUa.Configuration.Entities; /// /// Append-only audit log for every config write + authorization-check event. Grants revoked for /// UPDATE / DELETE on all principals (enforced by the authorization migration in B.3). /// public sealed class ConfigAuditLog { /// Gets or sets the unique audit log identifier. public long AuditId { get; set; } /// Gets or sets the timestamp of the audit event. public DateTime Timestamp { get; set; } = DateTime.UtcNow; /// Gets or sets the principal (user or service) that initiated the event. public required string Principal { get; set; } /// DraftCreated | DraftEdited | Published | RolledBack | NodeApplied | CredentialAdded | CredentialDisabled | ClusterCreated | NodeAdded | ExternalIdReleased | CrossClusterNamespaceAttempt | OpcUaAccessDenied | … public required string EventType { get; set; } /// Gets or sets the cluster identifier associated with the event, if applicable. public string? ClusterId { get; set; } /// Gets or sets the node identifier associated with the event, if applicable. public string? NodeId { get; set; } /// Gets or sets the generation identifier associated with the event, if applicable. public long? GenerationId { get; set; } /// Gets or sets additional event details in JSON format. public string? DetailsJson { get; set; } /// /// Stable per-event identifier from AuditEvent.EventId. Filtered unique index on /// this column gives cross-restart idempotency for the batched AuditWriterActor: a flush /// that retries after a process crash can re-send the same EventId without producing a /// duplicate row. Nullable so pre-v2 rows backfill cleanly. /// public Guid? EventId { get; set; } /// Correlation ID from AuditEvent.CorrelationId so an audit row joins to its /// originating request/workflow. Nullable for the same backfill reason as . public Guid? CorrelationId { get; set; } /// Normalized outcome from AuditEvent.Outcome (the canonical /// ZB.MOM.WW.Audit.AuditOutcome: Success | Failure | Denied), /// stored as its enum member name. Nullable so pre-Outcome rows backfill cleanly and the /// bespoke stored-procedure audit path (which does not derive an outcome) writes NULL. public string? Outcome { get; set; } }