Skip to content
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
This repository was archived by the owner on Nov 4, 2026. It is now read-only.

console: 系统导航 / System Hub 的 users / organizations / roles / positions / permissions 五个入口没有对应路由 —— 两个落 "Page not found",三个跳进不存在对象 system 的记录页 #3655

Closed

Description

@yinlianghui

越界发现,记录于 #3638(伪路由开关改按路径段判断)期间枚举 system / metadata 输入面时。按纪律只报不改,单独立单,未认领,留给 PM 分诊。

基线:origin/main @ 54dd7ec1f。静态路由表推导,未做浏览器实测 —— 见下「未验证的部分」。

现象

侧栏 sys-* 簇与 System Hub 卡片一共产出 5 个 /apps/setup/system/{名} 目标,宿主一个都没有声明路由:

入口 产出者 目标 URL
Users UnifiedSidebar.tsx:337 / AppSidebar.tsx:331 / SystemHubPage.tsx:138 /apps/setup/system/users
Organizations UnifiedSidebar.tsx:338 / AppSidebar.tsx:332 / SystemHubPage.tsx:146 /apps/setup/system/organizations
Roles UnifiedSidebar.tsx:339 / AppSidebar.tsx:333 /apps/setup/system/roles
Positions SystemHubPage.tsx:154 /apps/setup/system/positions
Permissions SystemHubPage.tsx:162 /apps/setup/system/permissions

宿主 apps/console/src/AppContent.tsx:86-114 的 systemRoutes 只声明了 system、system/apps、system/profile、system/approvals、system/ai-approvals、system/audit-log、system/settings{,/:namespace}、system/objects{,/:objectName}、system/metadata{,/:type,/:type/:itemName};packages/app-shell/src/console/AppContent.tsx:781-783 只补了 system/marketplace{,/installed,/:packageId}。上面 5 个名字都不在其中。

两种落点(取决于名字长度,这是最刺眼的地方)

未匹配的 URL 掉到 packages/app-shell/src/console/AppContent.tsx:794 的 :objectName/:maybeRecordId,由 ShorthandRecordRedirect 判定第二段像不像记录 id。looksLikeRecordId(:940)要求 segment.length >= 6(:946):

  • users(5)、roles(5) → 不像记录 id → RouteNotFound → 「Page not found」。
  • organizations(13)、positions(9)、permissions(11) → 像记录 id → 重写成 /apps/setup/system/record/{名},命中 :objectName/record/:recordId(:763)→ RecordDetailView 去加载对象名为 system 的一条记录 —— system 不是任何对象。

也就是说,同一簇导航里点 Users 得到 404、点 Organizations 得到一个「不存在对象的记录详情」,差别只来自单词长度。前者尚可辨认,后者会被读成后端/数据问题。

影响面

sys-* 簇是 AppSidebar / UnifiedSidebar 里无条件呈现的系统导航(与已修好的 sys-settings #3590、sys-datasources / sys-objects #3610 同一簇),System Hub 的四张卡片也是「System admin cards (non-metadata, always present)」(SystemHubPage.tsx:132 原注释)。不是零应用专属,有应用时同样点得到。

与 #3638 / #3610 / #3590 的关系(为什么单独立单)

未验证的部分(交分诊时请连这条一起读)

结论来自路由表 + looksLikeRecordId 的静态推导,没有跑浏览器。两处需要实测确认:

  1. 是否有别的宿主(cloud / framework 内嵌 console)通过自己的 extraRoutes 声明了这 5 条 —— 若有,则问题收敛为「参考宿主 apps/console 缺声明」。
  2. RecordDetailView 拿到不存在的对象 system 时的实际屏幕(空态?报错?白屏?),决定后三条的严重度。

可能的修法方向(留给分诊,不预判)

要么在宿主补 5 条路由指向对应的系统对象页(与 system/objects/:objectName 的重写风格一致),要么把这 5 个导航项改指已存在的目标(如 sys_user 等对象的 component/metadata/resource / 对象页),要么按 #3590 的做法逐个重定目标。属于导航契约层面的取舍,需要维护者定方向。

已就关键词(system/users、system/organizations、sys-users、SystemHubPage、ShorthandRecordRedirect、looksLikeRecordId)搜过本仓开放 issue 与 PR,无同源单。


Generated by Claude Code

Activity

  1. self-assigned this
    on Aug 7, 2026
  2. yinlianghui commented on Aug 7, 2026

    @yinlianghui
    ContributorAuthor

    认领(PM 派发)。

    • Session: session_01GTRjn8xBqp75dk7kFupVRt
    • 分支:claude/issue-3655-system-hub-routes
    • 文件面:apps/console 的路由声明面(systemRoutes fragment 所在文件,实测定位)+ 相关页面文件(仅当已存在未接线)+ 测试 + changeset。前置已落:PR fix(console): 宿主重定向直发规范 metadata 路由,不再绕已废弃的 component/metadata 别名 (#3639) #3658 已在 main(7883c02),apps/console AppContent.tsx 障碍解除。
    • 派发要求:issue 结论来自静态路由表推导 — 先做路由级实测复核(五条 URL 逐条渲染断言),再动手。
    • 处置(有界授权):先测量这五个入口本意指向什么 — (a) 已有页面组件未接线 → 声明路由;(b) 无页面但有 metadata 驱动等价物(如 user 对象列表)→ 改导航目标指真实等价物并同步测试钉;(c) 两者皆无 → 停,报告选项与测量证据,PM 复裁 — ⛔ 不发明空页面。looksLikeRecordId 的过宽误判机制只测量记录(修前后行为写进报告),不动它 — 那是另一个类。

    Generated by Claude Code

  3. yinlianghui commented on Aug 7, 2026

    @yinlianghui
    ContributorAuthor

    部分验收 ACCEPT → PR #3673(session_01GTRjn8xBqp75dk7kFupVRt,4/5 交付;PR 正文已由 PM 改为 Fixes-part-of,本单保持开放跟第五腿)。

    已核:CI 18 项 0 失败;路由级实测复核推翻了两处 issue 静态推导(零应用分支五条全 404、sys-* 簇仅零应用渲染);分支 (a) 以提交考古证伪(孤儿页面 + 不存在的对象名);四条目标逐条溯源框架源码;逆向验证 10 红 3 绿逐条吻合。

    裁决记录:

    1. roles/positions 同归 sys_position(ADR-0090 D3 改名)的判断接受 — 新旧两种叫法一个面。
    2. permissions 腿停手正确,现挂 needs-user-decision:两个等价物证据都硬(血缘指 sys_capability,功能指 sys_permission_set),任选即静默强制转换 — 「宁可显式缺口,不让别名悄悄定型」的判词收录。⛔ 维护者三选一(见 PR 正文该节):A sys_permission_set / B sys_capability / C 连同 bespoke 卡片退场(SystemHubPage 自己已标 @deprecated)。dev 推荐 A(过渡期语义押活面),终局是 C。此裁决同时定死 console: System Hub 的 Organizations / Permissions 卡片计数永远显示 0 —— 查的是框架里不存在的对象 sys_org / sys_permission #3670 的计数对象。
    3. 新发现:console: System Hub 的 Organizations / Permissions 卡片计数永远显示 0 —— 查的是框架里不存在的对象 sys_org / sys_permission #3670(两张卡片计数永远 0,查不存在的对象名,.catch 吞 404)定级 bug 入队 — ⚠️ 同文件等在途 导航仍有 4 处生产端在生成已废弃的 component/metadata 别名(SystemHub 两张卡片 + 两个 sidebar),各多绕一跳 #3660 的 PR fix(nav): 导航侧最后 4 处生产端直发规范 metadata 路由,不再绕已废弃的 component/metadata 别名 (#3660) #3668 落 main,且 permissions 计数一半等本决策;console: SystemObjectViewPage.tsx + systemObjects.ts 自 2026-04 起全仓零引用,且其内嵌对象定义用的是已废弃/不存在的对象名 #3672(孤儿页面)入池。

    Generated by Claude Code

  4. yinlianghui commented on Aug 8, 2026

    @yinlianghui
    ContributorAuthor

    PM 裁决(维护者已授权代裁,产品长期稳定视角,session_01GTRjn8xBqp75dk7kFupVRt):选 A(sys_permission_set)作为过渡别名落地;C(卡片墙退场)保留为独立产品项,不阻塞、另行由维护者定夺。

    理由:

    1. 契约不误绑:B(sys_capability)是 managedBy:'config' + no-overlay 的平台锁定注册表,把可收藏 URL 绑到一个管理员无法操作的面上,是稳定但无用的契约;A 是权限文档自述「the only capability container」、带管理员 CRUD 的授予容器,与卡片文案「Manage permission rules and assignments」同向。
    2. 可逆性:A 是一行 redirect,C 落地时它依然语义正确(书签继续通),不欠债;C 是产品面移除,不该由过渡裁决顺手带走。
    3. 此裁决同时解锁 console: System Hub 的 Organizations / Permissions 卡片计数永远显示 0 —— 查的是框架里不存在的对象 sys_org / sys_permission #3670 permissions 计数半件(改查 sys_permission_set)与 console: System Hub 计数失败后「无徽章」与「这张卡本来就没有计数」「还在加载」三态同形 —— 403 的管理员得到的是沉默,不是「你没有权限」 #3685。

    据此认领收尾腿。分支:claude/issue-3655-permissions-leg。文件面:apps/console AppContent.tsx systemRoutes(补 system/permissions → /apps/setup/sys_permission_set redirect,#3673 同形态)+ 翻转 systemHubRoutes.test.tsx 里钉住未变落点的 MEASUREMENT(其设计信号)+ SystemHubPage 计数 sys_permission → sys_permission_set + 翻转 counts 测试的恒 0 钉 + changeset。needs-user-decision 摘除。


    Generated by Claude Code

  5. yinlianghui commented on Aug 8, 2026

    @yinlianghui
    ContributorAuthor

    验收:PR #3728 ACCEPT,permissions 第五腿落地(会话 session_01GTRjn8xBqp75dk7kFupVRt,PM 循环)。

    交付内容

    • apps/console systemRoutes 增加 SystemObjectRedirect objectName="sys_permission_set"(与既有四腿同形态):/apps/:app/system/permissions 由"改写成记录页 URL、渲染对象名 system 的记录页"变为一跳直达 /apps/:app/sys_permission_set。
    • SystemHubPage 计数 sys_permission → sys_permission_set,Permissions 卡片徽章由恒 0 变为真实计数。
    • 8 项 MEASUREMENT 钉翻转(替换不并存,覆盖交接齐全,逐条见 PR 正文),含新增 system/workgroups 长词钉接手"长词→记录页"侧的唯一覆盖。

    证据:CI 18 项 0 失败;console project 247 tests 全绿(净增 2);双扰动先预测后实测逐条吻合(扰动 A:2 failed/22 passed;扰动 B:4 failed/20 passed,含扰动 B 下两条 0-permissions 用例"因同形错法保持绿"的已知盲区,已如实写进 PR 正文)。

    【论据订正补档】 裁决 A 的理由 1 曾引用论据「B(sys_capability)是 managedBy:config + no-overlay 的平台锁定注册表,A 是带管理员 CRUD 的授予容器」——dev 复核不成立:两对象同为 managedBy:'config' + protection.lock:'no-overlay'(sys-permission-set.object.ts:21,24-25 / sys-capability.object.ts:32,35-36),且两个 docblock 都写明锁的是 schema、租户/管理员可加行。裁决结论 A 不变,改由更硬的 ADR-0066 层1(定义目录)/层2(授予容器)支撑——卡片文案 "Manage permission rules and assignments" 正是层 2 职责。同一错误论据也出现在已合并的 PR #3673 / #3680 正文中,以本评论为公开订正记录,后续读者请以此为准。

    遗留(不阻塞本单)

    • 徽章文案 'permissions'(计数实为 permission set 行数)判为裁决 A 明确接受的过渡期语义,终局随 C 选项(System Hub bespoke 卡片墙退场,决策仍在维护者处)。
    • ROADMAP 中 permissions 腿的中性表述待本 PR 落 main 后按新现实更新(已挂账)。

    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions