Uh oh!
There was an error while loading. Please reload this page.
fix(app-shell): 零应用分支补 component/metadata 别名路由与 catch-all (#3610) - #3636
Merged
Conversation
零应用部署下,系统兜底导航的 sys-datasources 指向 /apps/setup/component/metadata/resource?type=datasource,sys-objects 经 console 宿主的 MetadataRedirect 改写后落到同一条 URL。isMetadataRoute 是对 `/metadata` 的子串判断,两条 URL 因此都越过「No Apps Configured」守卫进入 AppContent 的无-activeApp 路由表 —— 而该表既没有任何 component/* 声明,也没有 有-activeApp 分支末尾那条 catch-all。无匹配的 <Routes> 渲染 null,于是全新环境 的管理员点进去只看到一块纯白屏:没有 404、没有报错、没有空态。 测量结论(与派发时的猜测相反):component/metadata/resource?type= 不是规范拼法, 而是别名。有-activeApp 分支把它声明成 LegacyMetadataRedirect(注释原文 "Legacy: old metadata routes built before the REST-style nesting landed"), 302 到规范的 metadata/:type。两种拼法不是两个页面,是一个别名指向一个页面。 因此修法是纯镜像,导航 URL 一个不改:把同样两条别名路由声明进无-activeApp 分支, 它们转向的 metadata/:type 该分支本来就有;并补上与有-app 分支对齐的 path="*" → RouteNotFound,让这一类缺陷从「白屏不可报告」变成「可读的没找到」。 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 16:48
Uh oh!
There was an error while loading. Please reload this page.
This was referenced Aug 7, 2026
Closed
Closed
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#3610
现象与成因
零应用部署下,系统兜底侧栏的两项点下去是纯白屏 —— 没有 404、没有报错、没有空态:
sys-datasources→/apps/setup/component/metadata/resource?type=datasourcesys-objects→/apps/setup/system/metadata/object,由 console 宿主的MetadataRedirect改写成上面同一条 URLAppContent.tsx:185的isMetadataRoute是对/metadata的子串判断,两条 URL 都为真,于是越过:568的「No Apps Configured」守卫,进入:616的无-activeApp 路由表。该表只声明create-app、system/marketplace*、metadata*与宿主传入的extraRoutesNoApp,没有任何component/*;而且末尾没有 catch-all(全文件path="*"只有一处,在有-activeApp 分支的:775)。无匹配的路由表渲染null= 白屏。两种拼法的关系(实测,与派发预设相反)
派发单假设
component/metadata/resource?type=才是规范拼法(理由是宿主的MetadataRedirect往它改写)。实测结论正好相反:AppContent.tsx:753-754(有-activeApp 分支)把这两条component/metadata/*声明为LegacyMetadataRedirect,上方注释原文:"Legacy: old metadata routes built before the REST-style nesting landed. Redirect to the new /metadata/:type/... shape."LegacyMetadataRedirect自己的 docblock(:927-933)写的是同一件事:把 pre-refactor 的component/metadata/resource/:name?type=:type翻译成 new REST-style 的metadata/:type/:name。所以两种拼法不是同一页面的两个入口,而是一个别名指向一个页面:
metadata/:type才是规范拼法(两个分支都把它声明为真正的MetadataResourceListPage),component/metadata/resource是旧别名 —— 在有-app 分支里它根本不渲染页面,只做 302。这个结论不改修法,只改叙述:「镜像有-app 分支的
component/metadata形态、渲染同一组件」落地下来就是把同样两条LegacyMetadataRedirect声明进无-app 分支,而它们转向的metadata/:type该分支本来就有。这也正是契约优先的选择:别名保持唯一的规范落点,不为零应用另造一个拼法。导航 URL 一个没改。改动
packages/app-shell/src/console/AppContent.tsx,只动无-activeApp 分支(+22 行,全部为新增):component/metadata/directory与component/metadata/resource/*两条别名路由,element 与有-app 分支完全一致。path="*"→RouteNotFound,与有-app 分支的:775对齐 —— 让这一类缺陷从「白屏不可报告」变成「可读的没找到」。零应用下的完整链路(测试逐条钉住):
/apps/setup/component/metadata/resource?type=datasource/apps/setup/metadata/datasource资源列表页/apps/setup/system/metadata/objectMetadataRedirect→…/component/metadata/resource?type=object→ 别名 302/apps/setup/metadata/object资源列表页/apps/setup/system/metadata…/component/metadata/directory→ 别名 302/apps/setup/metadata目录页/apps/setup/system/no-such-pagesys-objects那条绕行链穿过三张路由表、两次重定向,是最不显眼、最会静默回归的一条,按分诊裁定单独钉了一条测试。逆向验证(先预测后运行)
预测:新测试保留、
AppContent.tsx停在origin/main状态 → 五条新断言全红,方向是查无元素(白屏),而不是渲染错误。实测吻合 ——
Tests 5 failed | 1 passed (6)。失败现场的 DOM dump 里 body 只剩测试自己的pathname探针,一个业务节点都没有,这是白屏的字面证据:第 6 条预期即为绿 —— 它是边界测量,不是回归钉子,见下一节。
一处验收口径修正
验收条目里的「访问
/apps/setup/no-such-page→ 渲染 RouteNotFound」这条 URL 选错了:它不含/system、不含/metadata、也不以/create-app结尾,三个开关全不亮,所以它压根进不了这个分支 ——:568的守卫先命中,渲染的是「No Apps Configured」空态(既有行为,AppContent.noAppsCta.test.tsx已有同族钉子)。真正需要 catch-all 的,是进得了分支却匹配不上的 URL,例如/apps/setup/system/no-such-page。测试按后者写,并把前者作为边界单独钉了一条 MEASUREMENT 用例,免得这两块屏日后被混为一谈。测试
新增
packages/app-shell/src/console/__tests__/AppContent.noAppComponentRoutes.test.tsx(6 条)。宿主的MetadataRedirect是apps/console的模块私有函数、且属于另一个 vitest project,app-shell 无法 import,因此在测试里逐字转写了它的prefix正则与 target 构造,并在文件头注明出处 —— 没有它,sys-objects那一跳在 app-shell 内不可测量。有-activeApp 分支零改动,现有测试全绿。
范围
只碰
AppContent.tsx的无-app 分支、其测试与 changeset。未碰UnifiedSidebar.tsx(在途 #3609)、AppSidebar.tsx(#3611)、ConsoleShell.tsx、QuickActions.tsx、apps/console/**—— 导航侧 URL 一个未改。顺带把
AppContent.noAppsCta.test.tsx里两处「该分支没有 catch-all,因此渲染空白」的注释改写为现状(断言未动)—— 本 PR 正是让那句话过期的改动。🤖 Generated with Claude Code
https://claude.ai/code/session_01GTRjn8xBqp75dk7kFupVRt
Generated by Claude Code