feat(approvals): register an approvals:inbox component ref and de-hardcode Home's approvals entry - #4071
Merged
Conversation
…ovals link Give the Approvals Inbox an addressable identity — `approvals:inbox` in the component registry — and stop Home's "pending approvals" card from sending every user into the setup app (objectstack#7231). - apps/console: new registerApprovalsComponents module, imported by main.tsx alongside the developer/studio/account registrations. The standalone `system/approvals` route stays: notification and email deep links carry it. - app-shell: HomePage resolves the approvals target from the app the user last had open, re-checked against the live active-app list, then their first available app; `setup` only as the last resort. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L9U1G2piXmYrhYQX96XUyv
`apps/console`'s tsconfig ships no `@types/node`, so the "does main.tsx side-effect-import the registration" guard could not be typechecked there. Dropped rather than widening the app's `types` for a test; the docblock now says so instead of implying coverage that is not present. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L9U1G2piXmYrhYQX96XUyv
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
Contributor
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
This was referenced Aug 10, 2026
os-zhuang
marked this pull request as ready for review
August 10, 2026 04:10
This was referenced Aug 10, 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 objectstack-ai/objectstack#7231
Part of objectstack-ai/objectstack#7213 — entry convergence at the metadata level. This is the objectui half: give the Approvals Inbox an addressable registry key, and stop Home's only approvals entry from routing every user through the setup app.
Premise re-verified against
origin/mainEvery fact the issue states still holds, re-read at
59df371f7:system/approvalsis declared inapps/console/src/AppContent.tsx'ssystemRoutesfragment and passed as bothextraRoutesandextraRoutesNoApp, so/apps/{any app}/system/approvalsalready resolves — the page was never bound tosetup.packages/app-shell/src/console/home/HomePage.tsxhardcodednavigate('/apps/setup/system/approvals').approvals:*key existed in the component registry.One PM assumption was worth measuring rather than assuming, and it held: the
component/:ns/:name/*route and thesystem/approvalsroute are both relative routes under/apps/:appName/*(apps/console/src/App.tsx), soApprovalsInboxPagereads the same:appNameand the same?request={id}on either.ApprovalsInboxPageis therefore unmodified — objectui#2763's rebuild is explicitly not started here.One assumption did not survive contact, and shaped the fix: Home renders at
/home, outside the/apps/:appName/*router, soInboxPopover'scurrentAppName ?? params.appNamecannot be copied literally —params.appNamedoes not exist there.currentAppNameis the only signal, it is published byConsoleLayouton app mount, and it is stale by construction (undefined on a cold landing at/home; it outlives the app it names). See below for what that made the resolution.Changes
1.
approvals:inboxin the component registry — newapps/console/src/registerApprovalsComponents.tsx, lazy-loadingApprovalsInboxPage, side-effect-imported frommain.tsxbeside the developer / studio / account registrations. A{ type: 'component', componentRef: 'approvals:inbox' }nav item now renders the full inbox at/apps/{app}/component/approvals/inbox.The standalone
system/approvalsroute is untouched: server notification and email deep links carry/system/approvals?request={id}andInboxPopoverapp-prefixes them. The ref is purely additive indirection, which is the point — objectui#2763 repoints the key later and no nav metadata churns.2. Home's card navigates within an app the user can actually open. Resolution order:
matchAppBySegment), so a remembered app that has since been deactivated or hidden is not resurrected as a dead link;setup;setup, which is not the zero-app case:activeApps.length === 0returns Home's welcome empty state before the action center exists, so this producer never runs there. What is left is the degenerate app with neither_packageIdnorname— nothing to build a URL from, so the historical target is the least-surprising last resort. That unreachability is pinned as a precondition case, so it goes red if it ever stops being true.InboxPopoveris deliberately untouched — it was already correct, and rewriting it into a shared helper is not this card's scope.Tests
apps/console/src/__tests__/approvalsInboxComponentRef.test.tsx— the ref resolves;componentRefToUrlSegmentsmaps it tocomponent/approvals/inbox(URLs in the test are built from the ref through that helper, so key and URL cannot drift); the page mounted via the component route sees:appNameand?request=; the standalone route hands it the identical inputs. The page is stubbed at its module boundary with a probe echoing exactly those two router inputs — the entry exercised is the real registered one, Suspense wrapper included.packages/app-shell/src/console/home/__tests__/HomePage.approvalsTarget.test.tsx— five cases: remembered app,_packageIdspelling, cold landing at/home, deactivated remembered app, and the zero-app precondition.pnpm exec vitest run apps/console/ packages/app-shell/→ 343 files, 3222 passed, 1 skipped.type-checkgreen for both packages. ESLint on the touched files: 0 errors (theno-explicit-any/react-refreshwarnings are the same ones the siblingregister*Componentsfiles and the rest ofHomePagealready carry).Reverse verification, direction predicted before running: reverting
HomePage.tsxandmain.tsxtoorigin/mainturned the four Home target cases red naming/apps/setup/system/approvals, while the zero-app precondition stayed green (it is about the empty state, not the target). The registry cases stayed green, as expected — the registration module itself was not reverted.Generated by Claude Code