Skip to content

fix(app-shell): point the remaining four Settings senders at /apps/setup/system (#3611) - #3637

Merged
yinlianghui merged 1 commit into
mainfrom
claude/issue-3611-remaining-setup-links
Aug 7, 2026
Merged

fix(app-shell): point the remaining four Settings senders at /apps/setup/system (#3611)#3637
yinlianghui merged 1 commit into
mainfrom
claude/issue-3611-remaining-setup-links

Conversation

@yinlianghui

Copy link
Copy Markdown
Collaborator

Fixes #3611

背景

#3590 / PR #3608 已修掉其文件面内的三个调用点。本单是它明确声明的剩余部分:同一根因、同一取值,但落在 #3590 的文件面之外。

根因:AppContent 只在 isSystemRoute(pathname.includes('/system'))成立时挂载系统枢纽。裸 /apps/setup 因此匹配不到除 isSetupRoute 外的任何伪路由,落回 !activeApp && … 守卫 —— 在零应用部署下,它就是「No Apps Configured」空态自己的 URL。凡是拼这个裸 URL 的入口,在那里都原地打转。

PM 裁决:「System Settings」语义恒等于系统枢纽,四处统一 /apps/setup/system(该 URL 在有/无 activeApp 两个分支下都可解析:分别经 extraRoutesextraRoutesNoApp)。常量替换,无行为分叉。

四处前后对照(3 活 1 眠)

# 文件:行 入口 before after 分类
1 layout/AppSidebar.tsx:461 无应用侧栏头 system-sidebar-header navigate('/apps/setup') navigate('/apps/setup/system')
2 layout/AppSidebar.tsx:695 用户菜单 user.settings「Settings」 navigate('/apps/setup') navigate('/apps/setup/system')
3 console/ConsoleShell.tsx:384 SystemRedirect/system 旧书签 suffix ? '/apps/setup/system' + suffix : '/apps/setup' … : '/apps/setup/system'
4 console/home/QuickActions.tsx:51 id: 'system-settings'「System Settings」卡片 href: '/apps/setup' href: '/apps/setup/system'

三个「活」缺陷

零应用部署下今天真实可达。其中 system-sidebar-header 最尖锐:它activeApp 为假时渲染 —— 也就是说,除了「其目标恰好失效」的那个状态,它根本无法被触达。

SystemRedirect 值得单独一句:它本来就有一半是对的 —— 带后缀的旧书签(/system/users)一直被正确改写成 /apps/setup/system/users,只有 /system 丢掉了那个 system 段。本 PR 让裸分支与它旁边的带后缀分支自洽,不加任何新逻辑

一个「眠」代码

QuickActions 全仓零 JSX 调用点(仅由 console/home/index.ts 导出,无人渲染),今天没有用户能碰到它,因此这一处没有用户可见的行为变化。仍在本次一并改掉:成本为零,而代价是 —— 只要有人把它挂回 HomePage,这条死链就会跟着一起回来。对应测试直接渲染该组件(休眠代码的诚实作用域),并把「零调用点」这一前提本身写成断言:有人挂回时它会变红,提示重读该文件。

测试

新增三个测试文件:

  • layout/__tests__/appSidebarSettingsTargets.test.tsx —— 站点 1、2
  • console/__tests__/systemRedirectTarget.test.tsx —— 站点 3
  • console/home/__tests__/QuickActions.settingsTarget.test.tsx —— 站点 4

SystemRedirect 的测试按真实消费者(apps/console/src/App.tsxexamples/console-starter/src/App.tsx)的写法声明路由 path="/system/*" —— splat 同样匹配裸 /system(空 splat),这正是那条缺陷分支的可达路径。

命令与结果(仓根,canonical invocation):

pnpm exec vitest run --maxWorkers=2 packages/app-shell/src/layout packages/app-shell/src/console
  Test Files  44 passed (44)
       Tests  225 passed (225)

pnpm --workspace-concurrency=2 --filter @object-ui/app-shell type-check   → EXIT=0
pnpm check:control-bytes   → OK (scanned 3656 tracked text file(s))
pnpm changeset:check       → OK (fixed group ✓,no major ✓)

逆向验证(先预测方向,后运行)

保留三个新测试文件、把三个源文件回退到 origin/main,逐条预测方向后再跑:

断言 预测 实测
AppSidebar 侧栏头 → 枢纽
AppSidebar 用户菜单 → 枢纽
AppSidebar 回归:sys-settings href(#3590 已修,本 PR 未动) 绿 绿
SystemRedirect 裸 /system → 枢纽
SystemRedirect 回归:带后缀 / 深后缀(本来就对的那一半) 绿 ×2 绿 ×2
SystemRedirect 裸 + query/hash
QuickActions 休眠前提(零调用点) 绿 绿
QuickActions「System Settings」卡片 → 枢纽
QuickActions 回归:兄弟卡片 绿 绿

逐条方向全部命中:标红的 5 条正是失败的 5 条,标绿的 5 条全部通过(Tests 5 failed | 5 passed (10))。失败文本即预期形状:

AssertionError: expected '/apps/setup' to be '/apps/setup/system'
AssertionError: expected '/apps/setup?tab=general#audit' to be '/apps/setup/system?tab=general#audit'

一处如实记录:我在汇总时把表头总数写成了「4 红 / 6 绿」,逐行预测实为 5 红 / 5 绿 —— 是我自己的加总笔误,逐条方向本身没有错。按「模板是工具而非事实」如实记下,不粉饰。

与在途单的隔离

变更集

.changeset/remaining-setup-links-3611.md(@object-ui/app-shell: patch)—— 用户可见:零应用部署下侧栏头、用户菜单与旧 /system 书签的 Settings 入口不再原地打转。


🤖 Generated with Claude Code

https://claude.ai/code/session_01GTRjn8xBqp75dk7kFupVRt


Generated by Claude Code

…tup/system (#3611)

objectui#3590 / PR #3608 fixed the three call sites inside its declared file
surface. These four were outside it and kept the bare `/apps/setup` — which,
because `AppContent` mounts the system hub only under `isSystemRoute`, is the
"No Apps Configured" empty state's own URL on a zero-app deployment. Every one
of them looped in place there.

Three are live defects:

- `AppSidebar`'s no-active-app sidebar header (`system-sidebar-header`), which
  renders ONLY when there is no active app — unreachable except in exactly the
  state where its target was broken.
- `AppSidebar`'s user-menu "Settings" entry.
- `SystemRedirect`'s bare `/system` legacy bookmark. The forwarder was already
  half right (every suffixed bookmark was rewritten to `/apps/setup/system…`
  correctly); the bare branch now agrees with the suffixed branch beside it.
  No new logic.

The fourth, `QuickActions`' "System Settings" card, is dormant — the component
has zero JSX call sites repo-wide, so no user reaches it today. Corrected in
the same pass so the dead link cannot return with the component if it is ever
remounted.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GTRjn8xBqp75dk7kFupVRt
@vercel

vercel Bot commented Aug 7, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
objectui Ignored Ignored Aug 7, 2026 4:42pm

Request Review

@github-actions github-actions Bot added the tests label Aug 7, 2026
@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Main entry (gzip) 28.1 KB 350 KB
Entry file index-CuqUPlqJ.js
Status PASS

📦 Bundle Size Report

Package Size Gzipped
app-shell (index.js) 8.66KB 3.13KB
app-shell (runtime-config.js) 7.42KB 2.32KB
app-shell (types.js) 0.01KB 0.04KB
app-shell (urlParams.js) 7.57KB 2.97KB
auth (AuthContext.js) 0.31KB 0.24KB
auth (AuthGuard.js) 1.17KB 0.53KB
auth (AuthProvider.js) 22.10KB 4.37KB
auth (AuthShell.js) 3.49KB 1.40KB
auth (ForgotPasswordForm.js) 12.21KB 3.45KB
auth (LoginForm.js) 18.13KB 5.39KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.64KB 2.21KB
auth (SocialSignInButtons.js) 9.60KB 3.89KB
auth (UserMenu.js) 3.40KB 1.22KB
auth (auth-gate-events.js) 1.29KB 0.66KB
auth (authStyles.js) 5.04KB 1.72KB
auth (createAuthClient.js) 35.76KB 9.11KB
auth (createAuthenticatedFetch.js) 4.37KB 1.69KB
auth (index.js) 2.35KB 1.07KB
auth (org-roles.js) 6.66KB 2.78KB
auth (phone-identifier.js) 1.11KB 0.66KB
auth (types.js) 0.59KB 0.35KB
auth (useAuth.js) 4.91KB 0.87KB
auth (useIsWorkspaceAdmin.js) 1.61KB 0.85KB
collaboration (CommentThread.js) 26.07KB 7.56KB
collaboration (LiveCursors.js) 3.17KB 1.27KB
collaboration (PresenceAvatars.js) 6.49KB 2.64KB
collaboration (PresenceProvider.js) 2.79KB 1.13KB
collaboration (index.js) 1.65KB 0.73KB
collaboration (useCollaborationTranslation.js) 6.05KB 2.52KB
collaboration (useCommentSearch.js) 1.98KB 0.88KB
collaboration (useConflictResolution.js) 7.75KB 1.86KB
collaboration (useMentionNotifications.js) 1.81KB 0.68KB
collaboration (usePresence.js) 6.33KB 1.84KB
collaboration (useRealtimeSubscription.js) 7.91KB 2.01KB
components (index.js) 480.72KB 105.64KB
core (index.js) 2.96KB 1.13KB
create-plugin (index.js) 9.28KB 2.98KB
data-objectstack (index.js) 137.51KB 35.11KB
fields (index.js) 230.87KB 56.83KB
i18n (LocalizationContext.js) 1.76KB 0.96KB
i18n (currency.js) 1.22KB 0.64KB
i18n (i18n.js) 4.32KB 1.77KB
i18n (index.js) 2.65KB 1.06KB
i18n (pickLocalized.js) 1.70KB 0.83KB
i18n (provider.js) 9.48KB 3.27KB
i18n (useObjectLabel.js) 26.14KB 6.07KB
i18n (useSafeTranslation.js) 4.52KB 1.96KB
layout (index.js) 38.53KB 10.71KB
mobile (MobileProvider.js) 0.92KB 0.49KB
mobile (ResponsiveContainer.js) 0.94KB 0.38KB
mobile (breakpoints.js) 1.51KB 0.70KB
mobile (createOfflineDataSource.js) 5.61KB 1.74KB
mobile (index.js) 1.50KB 0.62KB
mobile (offlineQueue.js) 3.91KB 1.35KB
mobile (pwa.js) 0.97KB 0.49KB
mobile (serviceWorker.js) 1.48KB 0.62KB
mobile (serviceWorkerSource.js) 3.41KB 1.48KB
mobile (useBreakpoint.js) 1.54KB 0.65KB
mobile (useGesture.js) 6.96KB 1.98KB
mobile (useOfflineSync.js) 1.99KB 0.72KB
mobile (usePullToRefresh.js) 2.53KB 0.85KB
mobile (useResponsive.js) 0.71KB 0.42KB
mobile (useResponsiveConfig.js) 1.36KB 0.63KB
mobile (useSpecGesture.js) 4.32KB 1.64KB
mobile (useTouchTarget.js) 1.01KB 0.54KB
permissions (MePermissionsProvider.js) 8.75KB 3.06KB
permissions (PermissionContext.js) 0.31KB 0.25KB
permissions (PermissionGuard.js) 0.89KB 0.45KB
permissions (PermissionProvider.js) 3.67KB 1.12KB
permissions (evaluator.js) 4.41KB 1.44KB
permissions (index.js) 0.91KB 0.41KB
permissions (store.js) 0.91KB 0.42KB
permissions (useFieldPermissions.js) 1.28KB 0.52KB
permissions (usePermissions.js) 1.55KB 0.71KB
plugin-ai (index.js) 15.71KB 3.79KB
plugin-calendar (index.js) 44.98KB 12.37KB
plugin-charts (index.js) 61.04KB 17.31KB
plugin-chatbot (index.js) 180.09KB 42.72KB
plugin-dashboard (index.js) 115.50KB 29.96KB
plugin-designer (index.js) 210.51KB 42.51KB
plugin-detail (index.js) 232.79KB 57.42KB
plugin-editor (index.js) 2.46KB 1.10KB
plugin-form (index.js) 112.10KB 27.10KB
plugin-gantt (index.js) 162.55KB 39.57KB
plugin-grid (index.js) 186.61KB 49.34KB
plugin-kanban (index.js) 48.30KB 13.28KB
plugin-list (index.js) 105.12KB 25.48KB
plugin-map (index.js) 16.81KB 5.24KB
plugin-markdown (index.js) 13.72KB 4.69KB
plugin-report (index.js) 40.58KB 10.58KB
plugin-timeline (index.js) 25.76KB 7.33KB
plugin-tree (index.js) 8.50KB 2.88KB
plugin-view (index.js) 84.03KB 20.55KB
providers (DataSourceProvider.js) 0.75KB 0.39KB
providers (MetadataProvider.js) 1.37KB 0.59KB
providers (ThemeProvider.js) 1.90KB 0.85KB
providers (UploadProvider.js) 11.71KB 3.53KB
providers (index.js) 0.44KB 0.22KB
providers (types.js) 0.01KB 0.04KB
react-runtime (index.js) 5.67KB 2.37KB
react (LazyPluginLoader.js) 3.77KB 1.33KB
react (SchemaRenderer.js) 19.28KB 6.38KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 1.02KB 0.55KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (codegen.js) 4.09KB 1.74KB
sdui-parser (index.js) 4.47KB 2.03KB
sdui-parser (parse.js) 10.04KB 2.82KB
sdui-parser (types.js) 0.29KB 0.24KB
sdui-parser (validate.js) 4.69KB 1.48KB
types (ai.js) 0.20KB 0.17KB
types (api-types.js) 0.20KB 0.18KB
types (app.js) 2.87KB 0.99KB
types (base.js) 0.20KB 0.18KB
types (blocks.js) 0.20KB 0.18KB
types (complex.js) 0.20KB 0.18KB
types (crud.js) 0.20KB 0.18KB
types (data-display.js) 0.20KB 0.18KB
types (data-protocol.js) 0.20KB 0.19KB
types (data.js) 0.20KB 0.18KB
types (designer.js) 1.87KB 0.85KB
types (disclosure.js) 0.20KB 0.18KB
types (error-code.js) 1.54KB 0.88KB
types (feedback.js) 0.20KB 0.18KB
types (field-types.js) 0.20KB 0.18KB
types (form.js) 0.20KB 0.18KB
types (http-retry.js) 4.32KB 2.02KB
types (index.js) 2.71KB 1.34KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 2.59KB 1.31KB
types (navigation.js) 0.20KB 0.18KB
types (objectql.js) 0.20KB 0.18KB
types (overlay.js) 0.20KB 0.18KB
types (permissions.js) 0.20KB 0.18KB
types (plugin-scope.js) 0.20KB 0.18KB
types (record-components.js) 0.20KB 0.19KB
types (record-semantics.js) 1.28KB 0.67KB
types (registry.js) 0.20KB 0.18KB
types (reports.js) 0.20KB 0.18KB
types (spec-report.js) 5.05KB 1.93KB
types (system-fields.js) 3.33KB 1.54KB
types (theme.js) 0.20KB 0.18KB
types (ui-action.js) 3.40KB 1.71KB
types (views.js) 0.20KB 0.18KB
types (widget.js) 0.20KB 0.18KB

Size Limits

  • ✅ Core packages should be < 50KB gzipped
  • ✅ Component packages should be < 100KB gzipped
  • ⚠️ Plugin packages should be < 150KB gzipped

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

console: #3590 文件面之外仍有 4 个「Settings」调用点指着裸 /apps/setup——零应用下同样落回空态

2 participants