Skip to content

refactor(types)!: Page/App/Dashboard 渲染节点不再占用 spec 的文档名 (#4115 B 组) - #3074

Merged
os-zhuang merged 1 commit into
mainfrom
claude/spec-debt-groupb-renames
Jul 30, 2026
Merged

refactor(types)!: Page/App/Dashboard 渲染节点不再占用 spec 的文档名 (#4115 B 组)#3074
os-zhuang merged 1 commit into
mainfrom
claude/spec-debt-groupb-renames

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

按维护者指示:B 组沿用 A 组敲定的 *ComponentSchema 约定,不做别名过渡

B 组是什么

type 的语义冲突:spec 的 type 是页面/仪表盘的种类(record|app|utility|list|home),objectui 的 type 是组件判别式('page'),种类被挪到了 pageType。后果是 spec 写法 {type:'list'} 的页面在 objectui 这边直接校验失败,而 objectui 页面的 pageType 在 spec 那边被静默丢弃 —— 偏偏两者顶着同一个名字,读代码的人会认为它们是一回事。

旧名 新名
AppSchema AppComponentSchema
DashboardSchema DashboardComponentSchema
PageSchema PageNodeSchema ← 约定的例外,见下

Page 为什么不叫 PageComponentSchema

PageComponentSchema 本身已经是 @objectstack/spec/ui 的导出,而且它指的是页面区域内部的一个组件({type: PageComponentType, properties, …}),不是页面本身。用这个名字等于把本 issue 要消灭的缺陷原样搬到隔壁概念上 —— 下一个读到 objectui PageComponentSchema 的人会以为它就是 spec 那个区域组件。

这不是推演出来的:本 PR 第一版真的用了 PageComponentSchema,被守卫按名拦下。所以 Page 改用 PageNodeSchema(spec 未占用),App/Dashboard 两个 *ComponentSchema 则是空闲的,照常。

方法:仍然让 tsc 当裁判

这三个名字比 A 组那批高频得多(225 处、约 40 个文件),而且 spec 与本地引用混在同一文件,所以替换时跳过注释行与含 @objectstack/spec 的行,整份排除三个「名字指向 spec」的文件(app-shell/…/page-schema.tsdashboard-schema.tsclientValidation.ts)。

过程中被 tsc / 守卫抓到两个我自己的疏漏,都已修正:

  1. 多行 import 块的洞 —— 成员行本身不含 @objectstack/spec(路径在结尾行),导致 4 处 spec 导入别名被误改成 PageComponentSchema as SpecPageSchema。特征是 …ComponentSchema as Spec…,已全部还原。
  2. apps/ 目录漏扫 —— 我的扫描只覆盖了 packages/,apps/console/src/schemas/objectDetailPageSchema.ts 被漏掉,tsc 报了出来。顺带回查确认 A 组(refactor(types)!: rename the 15 symbols that only collided with a spec name (#4115 A 组) #3068)在 apps/ 下确实没有引用,那轮的 78/78 是真绿而非侥幸。

验证

  • 台账 129 → 126,--ledger 重生成并逐条 diff:removed 恰为这三个、added 为空;
  • 变异测试两个方向:把节点改回 PageSchema → 守卫按名+按文件报红;改成 PageComponentSchema(我差点提交的陷阱名)→ 同样报红;
  • 全仓 type-check 78/78;
  • 全量测试 8701 断言绿(752 文件)。

BREAKING CHANGE

@object-ui/types 及其 /zod 入口的这三个导出改名且无别名。仓内所有消费者已更新,包括 apps/consolepackages/layoutpackages/runnerpackages/componentspackages/plugin-dashboardpackages/plugin-designerpackages/app-shellpackages/core

🤖 Generated with Claude Code

… spec's document names (objectstack#4115 group B)

Group B is the `type`-semantics collision: the spec's `type` IS the page /
dashboard kind (`record|app|utility|list|home`), while objectui's `type`
is the component discriminator (`'page'`) and the kind lives on
`pageType`. So a spec-authored `{type: 'list'}` page failed objectui's
schema and an objectui page's `pageType` was silently dropped by spec's —
under names that told every reader the two were the same thing.

Renamed to the *ComponentSchema convention group A settled on (node =
*ComponentSchema, union = *UnionSchema), with no back-compat aliases:

  AppSchema        -> AppComponentSchema
  DashboardSchema  -> DashboardComponentSchema
  PageSchema       -> PageNodeSchema

Page is a deliberate exception to the convention: `PageComponentSchema`
is ALREADY a `@objectstack/spec/ui` export — and it means a component
*inside* a page region (`{type: PageComponentType, properties, …}`), not
the page itself. Taking that name would have rebuilt the exact defect
this issue exists to remove, one concept over. The guard caught it: the
first pass of this commit used `PageComponentSchema` and failed by name.

Ledger 129 -> 126, regenerated with `--ledger` and diffed entry by entry:
removals are exactly these three, no other package's debt dropped.

Mutation-tested in both directions — re-declaring the node as `PageSchema`
*and* as `PageComponentSchema` each fail the guard by name and file.

78/78 type-check; full suite 8701 assertions green.

BREAKING CHANGE: `AppSchema`, `DashboardSchema` and `PageSchema` are
renamed in `@object-ui/types` (and its `/zod` entry point) with no
aliases. Every in-repo consumer is updated here, including apps/console.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 30, 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 Jul 30, 2026 4:06pm

Request Review

@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

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

📦 Bundle Size Report

Package Size Gzipped
app-shell (index.js) 8.20KB 2.97KB
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.12KB 3.41KB
auth (LoginForm.js) 17.86KB 5.29KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.43KB 2.09KB
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) 18.38KB 4.49KB
collaboration (LiveCursors.js) 3.17KB 1.27KB
collaboration (PresenceAvatars.js) 3.65KB 1.42KB
collaboration (PresenceProvider.js) 2.79KB 1.13KB
collaboration (index.js) 1.25KB 0.53KB
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) 471.08KB 102.76KB
core (index.js) 2.16KB 0.78KB
create-plugin (index.js) 9.28KB 2.98KB
data-objectstack (index.js) 134.68KB 34.25KB
fields (index.js) 222.07KB 54.35KB
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.46KB 0.96KB
i18n (pickLocalized.js) 1.70KB 0.83KB
i18n (provider.js) 5.37KB 1.72KB
i18n (useObjectLabel.js) 25.17KB 5.80KB
i18n (useSafeTranslation.js) 3.26KB 1.44KB
layout (index.js) 38.45KB 10.67KB
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.05KB 1.53KB
mobile (useTouchTarget.js) 1.01KB 0.54KB
permissions (MePermissionsProvider.js) 8.76KB 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 (retry.js) 3.48KB 1.61KB
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.90KB 12.35KB
plugin-charts (index.js) 60.52KB 17.11KB
plugin-chatbot (index.js) 180.09KB 42.72KB
plugin-dashboard (index.js) 111.59KB 28.74KB
plugin-designer (index.js) 210.51KB 42.50KB
plugin-detail (index.js) 221.81KB 54.28KB
plugin-editor (index.js) 2.46KB 1.10KB
plugin-form (index.js) 110.71KB 26.67KB
plugin-gantt (index.js) 162.26KB 39.53KB
plugin-grid (index.js) 184.77KB 48.50KB
plugin-kanban (index.js) 47.82KB 13.18KB
plugin-list (index.js) 104.07KB 24.88KB
plugin-map (index.js) 16.80KB 5.24KB
plugin-markdown (index.js) 13.65KB 4.67KB
plugin-report (index.js) 40.32KB 10.53KB
plugin-timeline (index.js) 25.75KB 7.32KB
plugin-tree (index.js) 8.36KB 2.81KB
plugin-view (index.js) 85.95KB 21.02KB
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
sdui-parser (codegen.js) 4.09KB 1.74KB
sdui-parser (index.js) 3.47KB 1.54KB
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 (index.js) 2.07KB 0.99KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 0.20KB 0.18KB
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) 1.08KB 0.64KB
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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant