@page "/clusters/{ClusterId}/audit" @attribute [Microsoft.AspNetCore.Authorization.Authorize] @rendermode RenderMode.InteractiveServer @using Microsoft.EntityFrameworkCore @using ZB.MOM.WW.OtOpcUa.Configuration @using ZB.MOM.WW.OtOpcUa.Configuration.Entities @inject IDbContextFactory DbFactory

Audit log · @ClusterId

@if (_rows is null) {

Loading…

} else {
Latest @PageSize audit rows scoped to this cluster, newest first. EventId/CorrelationId columns (F3) make cross-restart deduplication possible — Akka actors that retry an apply won't insert duplicate rows. Details JSON is shown verbatim.
@_rows.Count row@(_rows.Count == 1 ? "" : "s")
@if (_rows.Count == 0) {
No audit rows for this cluster yet.
} else {
@foreach (var a in _rows) { }
Timestamp Principal Event Node Correlation Details
@a.Timestamp.ToString("u") @a.Principal @a.EventType @(a.NodeId ?? "—") @(a.CorrelationId?.ToString("N")[..8] ?? "—") @(a.DetailsJson ?? "")
}
} @code { private const int PageSize = 200; [Parameter] public string ClusterId { get; set; } = ""; private List? _rows; protected override async Task OnInitializedAsync() { await using var db = await DbFactory.CreateDbContextAsync(); _rows = await db.ConfigAuditLogs.AsNoTracking() .Where(a => a.ClusterId == ClusterId) .OrderByDescending(a => a.Timestamp) .Take(PageSize) .ToListAsync(); } }