Uh oh!
There was an error while loading. Please reload this page.
fix(console): 把已退场的 system/{users,organizations,roles,positions} 四条 URL 声明为重定向,直达框架系统对象 (#3655) - #3673
Merged
Merged
Conversation
…ositions} URLs as redirects (#3655) SystemHubPage's cards and both sidebars' `sys-*` cluster emit five `/apps/setup/system/…` targets whose host declares no route. They fell through to app-shell's tail, where the failure depended on how long the word was, because `looksLikeRecordId` treats any URL-safe segment of 6+ chars as a record id: `users`/`roles` reached `RouteNotFound`, while `organizations`/`positions`/`permissions` were rewritten to `…/system/record/<word>` and rendered a record detail page for an object literally named `system`. Four now forward in one hop to the object the framework's own Setup navigation names — `sys_user`, `sys_organization`, and `sys_position` for both `roles` and `positions` (ADR-0090 D3 renamed `sys_role` to `sys_position`). Same shape as the `system/objects` / `system/metadata` redirects beside them: the URL is translated, the page deleted in cccdf84 is not resurrected, and no navigation producer is touched. `system/permissions` is deliberately unchanged: the framework splits what this console calls "Permissions" into `sys_capability` and `sys_permission_set`, and picking one would silently commit every click and bookmark to a surface nobody chose. Its landing is pinned so the gap stays visible. The new test renders app-shell's REAL AppContent with this host's REAL `systemRoutes`, so the tail routes under test are the shipped ones rather than a transcription; both pre-fix landings and the zero-app branch (no `:objectName` route there, so all five reached `RouteNotFound` and the length split does not exist) are measured rather than asserted away. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GTRjn8xBqp75dk7kFupVRt
The latest updates on your projects. Learn more about Vercel for GitHub. |
Contributor
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
yinlianghui
marked this pull request as ready for review
August 7, 2026 18:45
Uh oh!
There was an error while loading. Please reload this page.
This was referenced Aug 7, 2026
Merged
Closed
Merged
akarma-synetal pushed a commit
to akarma-synetal/objectui
that referenced
this pull request
Aug 10, 2026
…jectstack-ai#3673/objectstack-ai#3699 reality (objectstack-ai#3700) (objectstack-ai#3705) All nine [x] in "ObjectView-Driven System Pages (P1.12.2)" had gone false: the shared component was deleted (PR objectstack-ai#3699), four URLs became redirects onto framework objects (PR objectstack-ai#3673), /system/permissions is deliberately undeclared, the audit page is a standalone REST page, and the 22-test suite is gone. The Permission Management Page block above it drifted from the same source. Rewritten per this file's own retirement convention (an italic _(Retired — …)_ annotation on the sub-header plus rewritten [x] items carrying a bare PR ref, as at :152 ViewDesigner and :1046 tab-drag). The /system/permissions successor stays neutral and unchecked — pending the maintainer's call in objectstack-ai#3655. Claude-Session: https://claude.ai/code/session_01GTRjn8xBqp75dk7kFupVRt Co-authored-by: Claude <noreply@anthropic.com>
akarma-synetal pushed a commit
to akarma-synetal/objectui
that referenced
this pull request
Aug 10, 2026
…n_set (objectstack-ai#3655) (objectstack-ai#3728) Fifth and last of the five `system/*` navigation targets. `system/permissions` and the hub's Permissions count were both held back (PR objectstack-ai#3673 / objectstack-ai#3680) because the framework splits this console's "Permissions" into `sys_capability` (ADR-0066 layer 1, the definition registry) and `sys_permission_set` (layer 2, the grant container the permissions docs call "the only capability container"). objectui#3655 decided it as `sys_permission_set`: the card reads "Manage permission rules and assignments", and rules-and-assignments is layer 2. - route: `system/permissions` -> `SystemObjectRedirect objectName="sys_permission_set"` - count: `dataSource.find('sys_permission')` -> `'sys_permission_set'` - the two MEASUREMENT pins written to be replaced when this landed are replaced; the length-split fact they also carried is re-pinned on segments that are still undeclared in both route tables. Claude-Session: https://claude.ai/code/session_01GTRjn8xBqp75dk7kFupVRt Co-authored-by: Claude <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 freeto 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-part-of #3655(4/5:users/organizations/roles/positions 四条已交付;第五条 permissions 腿按有界授权停手,等维护者在 #3655 裁决 A/B/C 后另行落地 — 详见下文「为什么 permissions 留着不动」)
先复核:issue 结论成立,且比正文更细
issue 的结论来自静态路由表推导,派发单要求先做路由级实测复核。本 PR 的测试文件挂载 app-shell 真实的
AppContent(DefaultAppContent)+ 本宿主真实的systemRoutesfragment,五条 URL 逐条渲染。这一点在这里比平时更要紧:缺陷本身就是「本 fragment 与 app-shell 尾部路由的相互作用」,手抄一份尾部路由等于让它自动同意 fragment 的任何行为。实测落点(有应用分支,即 System Hub 卡片正常可达的那条):
/apps/setup/system/usersRouteNotFound— "Page not found"/apps/setup/sys_user,ObjectView渲染sys_user/apps/setup/system/organizations/apps/setup/system/record/organizations,RecordDetailView收到objectName: "system"/recordId: "organizations"/apps/setup/sys_organization/apps/setup/system/rolesRouteNotFound— "Page not found"/apps/setup/sys_position/apps/setup/system/positions…/system/record/positions,RecordDetailView收到objectName: "system"/recordId: "positions"/apps/setup/sys_position/apps/setup/system/permissions…/system/record/permissions,RecordDetailView收到objectName: "system"/recordId: "permissions"与 issue 正文的两处修正,均以实测为准:
system的记录页」,这只在有应用分支成立。AppContent的无 activeApp 路由表里既没有:objectName/:maybeRecordId也没有:objectName/record/:recordId,所以ShorthandRecordRedirect压根不参与 —— 零应用下五条全部落RouteNotFound。这条很关键,因为两个 sidebar 的sys-*簇只在 activeApp 为假时渲染(AppSidebar.tsx自己的注释),也就是说 sidebar 那三条入口平时走的正是这个分支。looksLikeRecordId的过宽判定只作记录、不改动(派发单要求)。本 PR 一行都没碰它;它造成的长度分叉现象在测试里以 MEASUREMENT 形态钉住(system/teams这类短词仍落 404),供后续单据引用。处置分支:(b) 路由侧重定向,不动导航文件
派发单给了三个分支,实测把它定死在 (b):
apps/console/src/pages/system/下确有SystemObjectViewPage.tsx+systemObjects.ts,但它们自 cccdf84 起全仓零引用,且其中的对象名(sys_org、sys_permission)在框架里根本不存在 —— 接回去只会渲染出空的 ObjectView。已另立 console:SystemObjectViewPage.tsx+systemObjects.ts自 2026-04 起全仓零引用,且其内嵌对象定义用的是已废弃/不存在的对象名 #3672(观察类)记录。{object_name}route」。等价物就是 Setup 应用导航里的type:'object'条目,resolveHref把它解析成{basePath}/{objectName}。SystemHubPage.tsx/AppSidebar.tsx/UnifiedSidebar.tsx正被 导航仍有 4 处生产端在生成已废弃的 component/metadata 别名(SystemHub 两张卡片 + 两个 sidebar),各多绕一跳 #3660 修改),故只交路由侧能做的部分:声明轻量重定向。这与它们上方system/objects/system/metadata两组重定向是同一形态(翻译 URL、不复活页面),导航仍有 4 处生产端在生成已废弃的 component/metadata 别名(SystemHub 两张卡片 + 两个 sidebar),各多绕一跳 #3660 正文亦已裁定「别名路由本身仍应保留 —— 书签与外链需要它」。目标对象名逐条取自框架源码,不是猜的:
sys_usersetup-nav.contributions.ts的nav_userssys_organizationnav_organizations(列表那条)。另一条nav_organization带recordId: '{current_org_id}',需要运行期会话值,静态重定向解析不了,故取列表sys_positionsys_role改名为sys_position;sidebar 的 "Roles" 与 Hub 的 "Positions" 是同一个面的新旧两种叫法。全仓无sys_role对象sys_positionnav_positions为什么 permissions 留着不动
框架把本 console 叫作 "Permissions" 的东西拆成了两个 Setup 条目,证据两边都硬:
sys_capability(导航标签 "Capabilities")—— 其对象 docblock 明写「Namedsys_capability(notsys_permissionas the ADR loosely floats)」,而sys_permission正是被删掉的那个页面、以及SystemHubPage计数查询今天仍在用的名字。血缘指向它。sys_permission_set(导航标签 "Permission Sets")—— 权限文档称其为「the only capability container」,是带管理员 CRUD 的授予容器,和卡片描述「Manage permission rules and assignments」以及它在 Positions 旁边的位置对得上。功能指向它。而sys_capability是managedBy: 'config'+protection.lock: 'no-overlay'的平台锁定注册表,对它做管理员增删本就没有意义。任选其一都会把此后每一次点击与每一个书签静默绑到一个维护者没有选过的面上 —— 这正是「消费端宽容」最典型的藏错处。派发单的 (b) 分支写明「redirect 目标以等价物实测为准」,而实测给出的是两个都能渲染的等价物,该条无法定案,故按「停手报告」处理:这一腿保持原样,并在测试里把它未变的落点钉住,让缺口显式可见、而不是读起来像漏掉了一条。裁决落地后,改的就是那条钉子。
零应用分支:测量,不是掩盖
重定向对两个分支同时生效(本宿主把同一个 fragment 传给
extraRoutes与extraRoutesNoApp)。零应用下目标/apps/setup/sys_user不含system/metadata路径段,于是离开伪路由家族,落到「No Apps Configured」空状态。这是诚实的终点而非被 stub 掩盖的回归:metadata 里一个 app 都没有的部署,同样没有
sys_user可渲染。变的只是换了一个死胡同 —— 修前这里五条全是RouteNotFound。测试里以专门一组用例钉住这个事实,而不是把它断言掉。逆向验证(先预测,后运行)
预测:删掉那四行
path="system/…"的路由声明后,四条一跳断言与四条零应用断言应转红,落点回到修前的两类;而三条 MEASUREMENT 断言(permissions 记录页、短词 404、零应用 permissions 404)不应受影响,因为它们不依赖这四条路由。实测:
13 passed->10 failed / 3 passed,失败清单与预测逐条吻合,失败现场直接打印出两类旧落点:测试
从仓库根跑,重活走共享 flock +
--max-old-space-size=4096+--maxWorkers=2:pnpm exec vitest run --project '@object-ui/console'-> 25 files / 232 tests passedpnpm exec vitest run packages/app-shell/src/console packages/app-shell/src/layout-> 46 files / 268 tests passed(消费半径清扫:systemRedirectTarget.test.tsx:62是全仓唯一另一处提到/system/users的断言,它测的是SystemRedirect的改写产物,发生在本 PR 的路由之前,故不受影响 —— 已跑绿确认)pnpm --workspace-concurrency=2 --filter @object-ui/console type-check-> 通过(新树里先--filter '@object-ui/console^...' build建好依赖)pnpm --workspace-concurrency=2 --filter @object-ui/console lint-> 0 errors(190 warnings 全为既有no-explicit-any;AppContent.tsx唯一那条react-refresh/only-export-components来自既有的systemRoutes导出,非本次新增)node scripts/check-control-bytes.mjs-> OK;node scripts/check-changeset-no-major.mjs-> OK文件面
apps/console/src/AppContent.tsx—— 新增SystemObjectRedirect+ 四行路由声明apps/console/src/__tests__/AppContent.systemHubRoutes.test.tsx—— 新增.changeset/system-hub-routes-3655.md—— patch⛔ 未触碰:
SystemHubPage.tsx/AppSidebar.tsx/UnifiedSidebar.tsx(#3660 在途)、ShorthandRecordRedirect的判定逻辑、packages/app-shell的任何路由声明。越界发现(只报不改,均已单独立单、未认领)
sys_org/sys_permission#3670 ——SystemHubPage的计数查的是框架里不存在的sys_org/sys_permission,.catch吞掉 404,Organizations 与 Permissions 两张卡片永远显示 0,与「确实没有」无法区分。真实缺陷,未打finding,留给分诊。SystemObjectViewPage.tsx+systemObjects.ts自 2026-04 起全仓零引用,且其内嵌对象定义用的是已废弃/不存在的对象名 #3672 ——SystemObjectViewPage.tsx+systemObjects.ts自 2026-04 起全仓零引用,且内嵌对象名已与框架脱节。观察类,已打finding。🤖 Generated with Claude Code
https://claude.ai/code/session_01GTRjn8xBqp75dk7kFupVRt