Summary
admin/app/audit-log/audit-log-screen.tsx hand-rolls its filter and
pagination state with plain useState (model, actorId, offset), even
though nuqs (2.9.5) is already a dependency and already used for exactly
this purpose — URL-persisted, bookmarkable filter state — in
messages-screen.tsx, jobs-screen.tsx, and webhooks-screen.tsx. This
screen appears to have simply been missed when those three adopted it.
Source of truth: docs/design/frontend-package-audit.md ("nuqs for
audit-log-screen.tsx — adopt" section), from the frontend package audit
requested by the maintainer.
Scope
In admin/app/audit-log/audit-log-screen.tsx, replace:
const [model, setModel] = useState("");
const [actorId, setActorId] = useState("");
const [offset, setOffset] = useState(0);
with useQueryStates (nuqs), matching the pattern already established in
admin/app/jobs/jobs-screen.tsx (parseAsString/parseAsStringEnum for the
filters; the offset can use parseAsInteger). Nothing else about the screen
changes — this is a state-management substitution, not a UX change, though
the resulting URL-shareable filter state is a real, incidental improvement
(an operator can now bookmark or share a specific audit-log filter view, the
same way they already can for messages/jobs/webhooks).
Small and mechanical: roughly 15–20 lines of URL-sync boilerplate removed,
replaced by the existing nuqs pattern already proven three times over in
this codebase.
Properties that must survive this change
- Pagination (offset) resets to
0 when a filter changes, matching the
current behavior — check the existing jobs-screen.tsx pattern for how
it handles this (its filter change handlers explicitly reset paging
state) and replicate it here rather than assuming nuqs does it for free.
- The screen's existing
hasFilters/"clear filters" affordance (if present)
keeps working against the new nuqs-backed state.
Verification
pnpm --filter admin typecheck stays green.
- Manually exercise: setting a filter updates the URL query string; a
bookmarked/shared URL with ?model=...&actorId=... reproduces the same
filtered view on load; changing a filter resets offset to 0.
AI Usage Declaration
This issue was filed by an AI agent (Claude) performing a maintainer-
requested audit of packages/* for hand-rolled machinery a well-maintained
library could replace. The scope was derived by reading
audit-log-screen.tsx and comparing it directly against the already-adopted
nuqs pattern in jobs-screen.tsx/messages-screen.tsx/webhooks-screen.tsx,
not inferred. A human should confirm the scope above and verify the manual
checks before merging.
Summary
admin/app/audit-log/audit-log-screen.tsxhand-rolls its filter andpagination state with plain
useState(model,actorId,offset), eventhough
nuqs(2.9.5) is already a dependency and already used for exactlythis purpose — URL-persisted, bookmarkable filter state — in
messages-screen.tsx,jobs-screen.tsx, andwebhooks-screen.tsx. Thisscreen appears to have simply been missed when those three adopted it.
Source of truth:
docs/design/frontend-package-audit.md("nuqsforaudit-log-screen.tsx— adopt" section), from the frontend package auditrequested by the maintainer.
Scope
In
admin/app/audit-log/audit-log-screen.tsx, replace:with
useQueryStates(nuqs), matching the pattern already established inadmin/app/jobs/jobs-screen.tsx(parseAsString/parseAsStringEnumfor thefilters; the offset can use
parseAsInteger). Nothing else about the screenchanges — this is a state-management substitution, not a UX change, though
the resulting URL-shareable filter state is a real, incidental improvement
(an operator can now bookmark or share a specific audit-log filter view, the
same way they already can for messages/jobs/webhooks).
Small and mechanical: roughly 15–20 lines of URL-sync boilerplate removed,
replaced by the existing
nuqspattern already proven three times over inthis codebase.
Properties that must survive this change
0when a filter changes, matching thecurrent behavior — check the existing
jobs-screen.tsxpattern for howit handles this (its filter change handlers explicitly reset paging
state) and replicate it here rather than assuming
nuqsdoes it for free.hasFilters/"clear filters" affordance (if present)keeps working against the new
nuqs-backed state.Verification
pnpm --filter admin typecheckstays green.bookmarked/shared URL with
?model=...&actorId=...reproduces the samefiltered view on load; changing a filter resets
offsetto0.AI Usage Declaration
This issue was filed by an AI agent (Claude) performing a maintainer-
requested audit of
packages/*for hand-rolled machinery a well-maintainedlibrary could replace. The scope was derived by reading
audit-log-screen.tsxand comparing it directly against the already-adoptednuqspattern injobs-screen.tsx/messages-screen.tsx/webhooks-screen.tsx,not inferred. A human should confirm the scope above and verify the manual
checks before merging.