Repository navigation
SPA: Audit has no date-range filter, and an audit trail is the screen that most needs one #666
Description
Activity
- addedenhancementNew feature or requestNew feature or requestarea:frontendReact/Vite web clientReact/Vite web client
on Sep 2, 2026 Scope note: the API side is already done, and the index question is answered
Investigated before planning. Recording it here because this issue's body asks two questions that turn out to have answers in the shipped code.
1. Does the audit endpoint accept a date range? Yes, already.
AuditEndpoints.cs:29-30takesDateOnly? from/DateOnly? to,IAuditEventRepository.ListAsynccarries them, andlistAuditEventsinweb/src/api/cluckwork.ts:918-930already types and serialises them.AuditPage.tsx:132simply never sends them. So this is SPA-only — no endpoint, handler, validator or repository change.2. The index question. This issue says a date-filtered audit query is "exactly the read that decision says the table is not optimised for". That rests on a conflation, and it is worth correcting on the record: #505 is about partitioning, not indexing. It argues that range-partitioning by month is the wrong axis, because pruning only helps a query filtering on the partition key while the dominant read (
AccountId+EntityId) does not — turning one lookup onIX_AuditEvents_AccountId_EntityIdinto one per partition. It never says the table has no date index.It has one.
AuditEventConfiguration.cs:24declaresHasIndex(e => new { e.AccountId, e.OccurredAtUtc }), beside(AccountId, EntityId)on line 25. A date-narrowed audit read under a resolved tenant is an index lookup today. So: no migration, no index, no amendment to #505 — not as a deferral to be measured later, but because the schema already supports the read.One thing this issue did not ask for and is getting. Audit's zero-row state currently says "No audit events yet." Under an active date filter that is a false statement — the log is not empty, the window is. A third message ships with the filter.
Day-boundary semantics, stated so it is not a surprise: audit's
from/toare inclusive calendar days over the UTC timestamp (AuditEventRepository.cs:15-25), matching this screen's own "When (UTC)" column header. Expenses' equivalent control filters farm-local business dates. Same-looking controls, different windows, both correct.Design:
docs/designs/666-667-spa-date-range-filters.md. Shipping together with #667 and a Stock fix in one PR.- added 11 commits that reference this issue
on Sep 3, 2026 - added a commit that references this issue
on Sep 4, 2026 - added a commit that references this issue
on Sep 12, 2026
Found while implementing #653, which lists Audit among the screens whose date-range filters move into a bounded toolbar. It has none to move.
AuditPage.tsxfilters on entity type and action — two<select>s — and nothing else. #653's acceptance criterion "date-range filters sit in a toolbar at a bounded width on every screen that has one" is therefore satisfied there vacuously, which is not the same as satisfied.Why it matters more here than on the screens that do have one
An audit trail is read to answer "what happened, and when" — almost always about a window. Every other question the screen supports (which entity, which action) narrows a haystack that is still unbounded in time. Feed, Water, Expenses, History and Reports all have a date filter; the one screen whose entire purpose is chronological does not.
It also grows without bound.
AuditEventsis deliberately not time-partitioned (#505) because the dominant read filters onAccountId+EntityType+EntityIdwith no date predicate — a decision worth re-reading before adding a date filter, because a date-filtered audit query is exactly the read that decision says the table is not optimised for. Whether the filter should be added is partly a query-shape question, not only a UI one.Scope
.toolbarthat SPA: table layout — provenance column to one line, date-range filters into a bounded toolbar #653 introduces, matching the other screens.Related: #653 (which established the toolbar pattern), #505 (audit partitioning decision).