Repository navigation
fix(console): the audit log names the actor and filters by a user lookup (objectui#11701) - #11739
Merged
Merged
Conversation
…kup (objectui#11701) The list fetch asks for `$expand=user_id`, so the engine puts each actor's `sys_user` record in place of its id. The actor column shows the user's name with the id on hover, a user the engine could not resolve shows the id, and a change no user made reads "System" with the recorded principal on hover. The drawer shows the name and the full id. The free-text actor box is replaced by the `sys_user` lookup from `@object-ui/fields`. It commits the chosen user's id to `filter.user_id`, and removing the chip clears it. Claude-Session: https://claude.ai/code/session_01FngvPpdrnhHMdHHq6vwwju Co-authored-by: Claude <noreply@anthropic.com>
…i#11701) Claude-Session: https://claude.ai/code/session_01FngvPpdrnhHMdHHq6vwwju Co-authored-by: Claude <noreply@anthropic.com>
…surface (objectui#11701) `check-vi-mock-inherit` refuses a hand-listed factory for a judged workspace package. The mock now spreads the real module and overrides `useAdapter` only. Claude-Session: https://claude.ai/code/session_01FngvPpdrnhHMdHHq6vwwju Co-authored-by: Claude <noreply@anthropic.com>
Contributor
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
This was referenced Oct 6, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #11701
Clause-②: no
The console's Audit Log page (
/system/audit-log, component refaudit:log) printedsys_audit_log.user_idas a truncated raw id, and its actor filter was a free-text box that took an id. This PR makes the page name the actor and turns the filter into a user lookup. The whole change is inapps/console/src/pages/system/AuditLogPage.tsx. The producer side needed no change.What changed
/api/v1/data/sys_audit_logread now sends$expand=user_id. No request is added.title(shown on hover). For a user the server could not resolve, the column shows the id (truncated, with the full id on hover). A row with an emptyuser_idreads "System", and the recordedactorprincipal (such assvc:NAME) shows on hover.LookupFieldfrom@object-ui/fields, withreference: 'sys_user'. It writes the chosen user's id tofilter.user_id. Removing the chip writes null, which removes the filter. "Clear filters" still resets it.Which path, and why (the order's Zone 2 assumptions, measured)
Page shape. It matches the order. The page used a raw
fetchwith$filter/$orderby/$top/$skip, renderedtruncate(r.user_id, 18)in monospace, and had a free-textInputthat wrotefilter.user_id. Confirmed onmainat22b503c.Name source: the expansion, not a batched read. I read objectstack at
1fb274e61c, fetched into a named ref:sys_audit_log.user_idisField.lookup('sys_user', ...)inpackages/plugins/plugin-audit/src/objects/sys-audit-log.object.ts.$expandontoexpand.assertExpandTargetsExistaccepts a reference-typed field that names a target.expandRelatedRecordsinpackages/objectql/src/engine.tsloads the referenced ids in oneid $inread through the engine's ownfind, sosys_user's full read gate applies. It puts each record in place of its id. When the user is missing or the read is refused, it keeps the bare id.sys_userdeclaresnameField: 'name'.user_idor the expansion.So the expansion takes one request, keeps the id visible for deleted users, and applies the permissions of the referenced object. A separate batched
sys_userread would add a request to do what the engine already does.The filter widget:
LookupField, notUserField.@object-ui/fieldsalready exports both, so nothing new is exported.UserFieldservesuser-type fields, and it always adds abannednot-equal-true candidate filter (withBannedFilter). With it, nobody could pick a deactivated user, and that is the user an audit search most often needs.sys_audit_log.user_idis declared as alookuptosys_user, andLookupFieldwithreference: 'sys_user'is the widget for that declaration. The page gets the adapter fromuseAdapter()(@object-ui/app-shell), as the other system pages do. Inline create stays off, which is already the default forsys_references.Copy. The page's labels stay English literals: "Actor", "Any user", "System". No i18n key is added. The lookup uses its existing keys (
common.select,table.search,lookup.*).Tests (at
8e17dbf)The new suite is
apps/console/src/pages/system/AuditLogPage.actorName-11701.test.tsx, with 7 tests. It stubs both data seams the page reads.fetchanswers/data/sys_audit_logthe way the engine answers$expand=user_id, and it applies a$filteronuser_id.useAdapterservessys_userto the lookup. The tests pin these behaviours:$expand=user_id;$filterof the admin'suser_id, and only the admin's row is listed;$filter, and every row is listed again.Every run below went through
os-verify-lock.shwith slotissue-11701:pnpm exec vitest runon the new suite andconsoleFaces.displayLocale-9909.test.tsx(the other suite that renders this page)pnpm exec vitest run apps/console/(the whole console package, run from the repo root)pnpm --workspace-concurrency=2 --filter '@object-ui/console^...' run buildpnpm --filter @object-ui/console run type-checktsc --listFilesOnlylists both changed files.pnpm --filter @object-ui/console run linterr: anyin the catch and theuseEffectthat callsload, are on code that was already there.Ablation: one leg, predicted before the run to turn two pins red. HEAD carried the fix.
ablation-replace.mjschanged theface.namereturn inActorCellso the same span renderstruncate(face.id, 18). That puts the raw id back where the name was. The anchor count went from 1 to 0, and the blob went from970a60a9c060tof13067506aca. The suite read 2 failed, 5 passed. The two failures were "shows the seeded admin's name ..." and "choosing the admin ... lists the admin's row", and both readExpected ... Admin User, Received: usr_admin_0001. After the restore, the blob was970a60a9c060, equal to HEAD,git diff HEADwas empty, andgit statuswas clean. The suite imports the page by relative path, so the ablation hitssrcdirectly and needs nodiststep.Gates (at
8e17dbf, each exit 0)check-changeset-presence,check-changeset-no-major,check-changeset-fixed,check:new-line-citations(0 new),check:control-bytes,check:changeset-claims(its corpus is this change's one changeset),check:pending-changeset-literals,check-governed-queue-guard --testover the three paths (NOT GOVERNED),check:vi-mock-specifiers,check:vi-mock-inherit,check:vi-mock-override-shape,check:test-path-roots,check:i18n-keys,check:phantom-deps,check:unused-deps,check:element-data-source-declaration,check:handler-key-reads,check:metadata-write-doors,check:unreferenced-sources.check:vi-mock-inheritrejected the suite's firstvi.mock('@object-ui/app-shell')factory, which listeduseAdapterby hand. The factory now spreads the real module (commit8e17dbf).NOT MEASURED:
check:eager-closure: exit 2 because a prerequisite is missing. It needsapps/console/dist/eager-closure.json, which comes from a consolevite buildthat was not run here. Both places that mount this page load it through Reactlazywith a dynamicimport(AppContent.tsx,registerSystemComponents.tsx), so the new imports land in the page's lazy chunk. CI measures this gate.$expandpath was therefore checked by reading the source at1fb274e61c, and the page by the stubbed suite above.pnpm testbelong to CI.Changeset
.changeset/11701-audit-actor-name.mddeclares'@object-ui/console': patch. The page is part of an app, and no package entry changes. That matches the console-only precedents11633-verify-email-get.mdand11677-approvals-summary-faces.md. The changeset body saysClause-②: no.Acceptance notes
sys_userrows,LookupFieldpreviews theemailcolumn throughEmailCellRenderer, and that renderer's copy control is a button inside the option button. React logs "button cannot contain a nested button". It showed up in this suite's stderr on a failing run. It does not fail a test, and it comes from@object-ui/fields, not from this page. It was not measured at a public entry point, so it is noted here and not filed.fetchwithcredentials: 'include', not the console adapter. AGENTS.md §7 asks for@objectstack/client. That predates this change, which kept the one fetch and added$expandto it.Generated by Claude Code