Adds the results grid + query facade for the central Audit Log page
(#23 M7-T3):
* IAuditLogQueryService / AuditLogQueryService — CentralUI facade over
IAuditLogRepository.QueryAsync so the grid can be tested with a stubbed
query source. Default page size is 100; callers can override per call.
* AuditResultsGrid.razor + .razor.cs — Blazor Server component (Bootstrap
only, no third-party UI libs). Renders the 10 columns from
Component-AuditLog.md §10 (OccurredAtUtc, Site, Channel, Kind, Status,
Target, Actor, DurationMs, HttpStatus, ErrorMessage). Keyset-paged via
the last visible row's (OccurredAtUtc, EventId) as the cursor; Next-page
button disabled when the current page is short (no count query). Row
clicks emit OnRowSelected(AuditEvent) for Bundle C's drilldown drawer.
Status badges are colour-coded (Delivered=green; Failed/Parked/Discarded
=red; other=gray). Error messages truncated to 80 chars with full text
on hover.
* Column model framework: a ColumnOrder [Parameter] reorders columns by
stable string keys; unknown keys are dropped. M7 scope decision (in the
class doc): the framework is in place but drag-reorder / resize UX is
not implemented — M7.x can add persisted-per-user reordering without
rewriting the column model.
* AuditLogPage wired: hosts AuditFilterBar + AuditResultsGrid, threads
the filter through and stubs OnRowSelected for Bundle C.
* AuditLogQueryService registered as scoped in AddCentralUI.
* Tests: 4 grid bUnit tests (10 columns rendered, next-page cursor
carries last row, row click raises callback, badge classes for
Failed vs Delivered), 2 service tests (filter+paging pass-through,
default page size of 100). AuditLogPageScaffoldTests updated to
provide the new ISiteRepository + IAuditLogQueryService stubs the
page now resolves.
Adds the filter bar for the central Audit Log page (#23 M7-T2):
* AuditQueryModel — UI binding model with chip-style multi-select state for
Channel/Kind/Status/Site, a Channel→Kind narrowing map (CachedSubmit and
CachedResolve appear under both ApiOutbound and DbOutbound per
Component-AuditLog.md §4), time-range presets (5min/1h/24h/Custom),
free-text Instance/Script/Target/Actor searches and an Errors-only toggle.
Collapses to the single-value AuditLogQueryFilter on ToFilter(utcNow);
multi-select chips take the first selected per dimension and the
Errors-only toggle pins Failed when Status chips are empty (chip-set wins
otherwise) — documented Bundle B scope decision.
* AuditFilterBar.razor + .razor.cs — Blazor Server component (Bootstrap
only, no third-party UI libs). Renders the 10 spec elements plus the
Errors-only toggle, populates Site chips from ISiteRepository at
initialisation, exposes [Parameter] EventCallback<AuditLogQueryFilter>
OnFilterChanged and an optional NowUtcProvider seam for time-window tests.
* AuditFilterBarTests — 5 bUnit tests pinning element presence, Apply
callback payload, Channel→Kind narrowing, Errors-only toggle precedence
and the LastHour time-window collapse.