fix(console): 403 blamed on the network, ⌘K search capped at 8 objects, nav gating fields inert - #3044
Merged
Merged
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
Contributor
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
…s, nav gating fields inert
Three real-user console failures from platform dogfooding:
1. plugin-list: a 403/401 rendered the same 'check your connection' panel
as a genuine outage. The error panel now classifies by status/code and
shows permission-denied / sign-in-required copy (all nine locales).
2. react/useRecordSearch: maxObjectsQueried caps the per-object fanout,
not the search scope — it used to truncate the objects whitelist sent
to /api/v1/search to the first 8 nav objects, so which sidebar group
came first decided which records were findable.
3. app-shell: evaluateVisibility now evaluates the { dialect: 'cel' }
envelopes the spec normalizes nav visible predicates into (they used
to fall through to a blanket 'visible'), and the sidebars'
requiredPermissions check treats a bare name as an ADR-0066 system
capability against the user's permission-set systemPermissions union,
matching the server's AppSchema.requiredPermissions rule.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.
Closes #3046, closes #3047, closes #3048
Summary
Three real-user console failures found via platform dogfooding (each reproduced with request-level evidence before fixing):
1. A 403 rendered as "check your network connection" (
plugin-list,i18n)ListViewrendered one generic connectivity message for every failed fetch, so a permission denial was indistinguishable from an outage — users (and ops) were sent to debug their network while the server was correctly denying access. The error panel now classifies the failure viahttpStatus/status/statusCode, thePERMISSION_DENIED/FORBIDDEN/UNAUTHORIZED/UNAUTHENTICATEDcodes, or anHTTP <status>message prefix, and renders dedicated permission-denied (403) / sign-in-required (401) copy in all nine locales. The panel exposesdata-error-kindfor tests.2. ⌘K / full-page search silently capped at the first 8 nav objects (
react)useRecordSearchsliced its candidate pool tomaxObjectsQueried(8) — which also truncated theobjectswhitelist sent to the single-request/api/v1/search. Measured symptom: in an app with 40+ searchable objects, which sidebar group happened to come first decided which records were findable; an existing record code returned "no results" while the same query against the API directly matched. The cap now applies only where it belongs: the per-object fanout fallback. The searchAll path sends the full whitelist.3. Both nav gating fields were inert (
app-shell)visible(CEL):evaluateVisibilityonly evaluated${…}template strings. The{ dialect: 'cel', source }envelopes the spec'sExpressionInputSchemanormalizes every authored predicate into fell through to a blanket "visible" — a constant-false predicate still rendered for everyone. It now delegates toExpressionEvaluator.evaluateCondition, which routes CEL envelopes to the canonical@objectstack/formulaengine (current_user.positionsetc. already in scope).requiredPermissions: the sidebars misread a bare name ascan(<name>, 'read')— an object-CRUD check on a name that usually isn't an object — so requiring a capability hid the item from everyone, including holders of the permission set that granted it and admins. A bare name is now checked as an ADR-0066 system capability against the user's permission-setsystemPermissionsunion from/me/permissions— the same subset rule the server applies toAppSchema.requiredPermissions— with theobject:actionform and the legacy object-read fallback preserved. (The server has returnedsystemPermissionssince 17.0.0-rc.0; the client just never consulted it.)Tests
ListView.loadErrorKind.test.tsx(5 classification cases),ExpressionProvider.evaluateVisibility.test.ts(CEL envelope true/false, template, literals, fail-open), twouseRecordSearchregressions (full whitelist to searchAll beyond the cap; fanout still capped).pnpm vitest run— plugin-list/react/i18n: 59 files / 747 tests green; app-shell: 243 files / 2024 tests green.pnpm build: 43/43 tasks green.🤖 Generated with Claude Code