Skip to content

feat: filter the audit history by action, author and date - #29

Merged
RicardoZambon merged 1 commit into
mainfrom
feature/audit-history-filters
Sep 26, 2026
Merged

RicardoZambon merged 1 commit into
mainfrom
feature/audit-history-filters

Conversation

@RicardoZambon

Copy link
Copy Markdown
Owner

The audit view lists every service that ever touched a record, newest first, with no way to narrow it. On a record with a long history that is a wall of rows.

The filtering machinery was already here — TryFilter, FilterTypes, the JsonElement conversion behind GetFilterValue — but nothing applied it to the two audit lists.

What the lists now honour

List Filter Match
Services Name LIKE
Services ChangedByID equals
Services ChangedOnFrom / ChangedOnTo inclusive range
Operations OnlyCurrentEntity restricts to the audited record

The names are constants on ZWebAPI.Models.Audit.AuditFilters, not literals: a filter crosses to the client as a dictionary key and nothing checks that both sides still spell it the same way. Lookups are case insensitive, so a camelCase form control reaches a PascalCase property.

Two decisions worth stating

OnlyCurrentEntity is off by default. A service writes to more than one table, and listing all of its operations is what shows the related rows a change also touched. The filter exists for when that context is noise, not the other way round. It does not touch the services list, which is already restricted to the services that touched the record.

Both ends of the range are inclusive. A range picked as two dates is read by a person as covering both. ChangedOn is stored UTC and compared as given, so a caller converts before sending.

Tests

8 new, on top of the 11 the audit service already had: each filter alone; the two combined narrowing further rather than replacing one another; a range whose bounds are the rows' own instants, where an exclusive comparison would return nothing; and the operations list keeping its related rows by default, dropping them when asked, and keeping them when the filter is present but off.

274 pass on net8.0, net9.0 and net10.0.

🤖 Generated with Claude Code

The audit view lists every service that ever touched a record, newest first, and offers no way to
narrow it. On a record with a long history that is a wall of rows to read through.

The filtering itself was already here -- TryFilter, FilterTypes and the JsonElement conversion
behind GetFilterValue -- but nothing applied it to the two audit lists. Now the services list
honours Name (LIKE), ChangedByID (equals) and an inclusive ChangedOnFrom/ChangedOnTo range, and the
operations list honours OnlyCurrentEntity.

The names are constants on ZWebAPI.Models.Audit.AuditFilters rather than literals, because a filter
crosses to the client as a dictionary key and nothing checks that both sides still spell it the
same way. Lookups are case insensitive, so a camelCase form control reaches a PascalCase property.

OnlyCurrentEntity is off by default, and deliberately: a service writes to more than one table, and
listing all of its operations is what shows the related rows a change also touched. The filter is
there for when that context is noise, not the other way round -- which is also why it does not
touch the services list, already restricted to the services that touched the record.

The dates are compared as given, and ChangedOn is stored UTC, so a caller converts before sending.
Both ends are inclusive: a range picked as two dates is read by a person as covering both of them.

8 tests, on top of the 11 the audit service already had: each filter alone, the two combined
narrowing further rather than replacing one another, a range whose bounds are the rows' own
instants (an exclusive comparison would return nothing), and the operations list keeping its
related rows by default, dropping them when asked, and keeping them when the filter is present but
off. 274 pass on net8.0, net9.0 and net10.0.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@RicardoZambon
RicardoZambon merged commit 09b04b2 into main Sep 26, 2026
6 checks passed
@github-actions

Copy link
Copy Markdown

🎉 This PR is included in version 1.15.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant