Skip to content

refactor(types)!: rename the 15 symbols that only collided with a spec name (#4115 A 组) - #3068

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

refactor(types)!: rename the 15 symbols that only collided with a spec name (#4115 A 组)#3068
os-zhuang merged 1 commit into
mainfrom
claude/spec-debt-groupa-renames

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

按维护者指示:A 组直接改名,不做别名过渡

这 15 个是分诊里的 COINCIDENCE 判决 —— 本地概念与 @objectstack/spec 的某个导出同名但建模的是别的东西。名字本身就是缺陷:#4115 的核心论点正是「agent 读到熟悉的名字,默认它是 spec 的语义,然后在此之上继续写」(#2901 就是这样被填成反向前提的)。

改名清单

旧名 新名 spec 那个同名符号其实是什么
FilterCondition FilterBuilderCondition 递归的 ObjectQL 过滤 AST(本地是 FilterBuilder 的一行)
FilterOperator FilterBuilderOperator WebSocket 订阅的操作符枚举
FilterConditionSchema FilterBuilderConditionSchema 同上
EventHandler UIEventHandler 内核事件总线的订阅注册(本地是 SDUI 事件绑定)
CacheStrategy FetchCacheStrategy 缓存淘汰策略(本地是 service-worker 取数顺序)
MutationEvent DataSourceMutationEvent 一个字符串枚举(本地是对象 payload)
ExpressionSchema ExpressionNodeSchema L1 CEL 表达式信封
GroupByNode GroupByClauseNode 单个分组目标(本地是整条 GROUP BY 子句)
SpanSchema TextSpanSchema OpenTelemetry 追踪 span(本地是 HTML <span>)
BatchOperationResult BatchOperationSummary 单条记录的结果(本地是整批汇总)
ReportSchedule ReportScheduleConfig 持久化的服务端行
ReportSchema ReportComponentSchema 报表元数据文档
ThemeSchema ThemeComponentSchema 主题定义(本地是主题切换器组件)
ValidationRule(field-types) FieldConstraints 具名的服务端校验规则
ValidationRule(form) FieldValidationRules 同上

改名过程中暴露的两个问题

1. objectui 自己有两个互相冲突的 ValidationRule field-types.ts 是扁平约束包(minLength?: number),form.ts 是 RHF 风格的包装形(minLength?: {value, message})—— 键名全同、值形状不兼容。barrel 只导出了后者(前者被刻意从导出块里省掉,正是为了躲开这个碰撞),所以深引 field-types 的消费者会静默拿到另一个类型。现在两者有了各自的名字。

2. zod/reports.zod.tsReportComponentSchema 已被判别联合占用。zod/theme.zod.ts 早已在用「节点 = *ComponentSchema、联合 = *UnionSchema」的约定 —— 所以把那个联合改成 ReportUnionSchema,顺带让两个文件的约定一致(一个三选一的判别联合叫 "ComponentSchema" 本来也不准确)。同样按无别名指示,zod/theme.zod.ts 里那个 @deprecatedThemeSchema 别名直接删除而非保留。

安全性:用 tsc 当裁判,不做盲目全局替换

FilterCondition/ValidationRule/ThemeSchema/ReportSchema/SpanSchema 这些名字两边都有,盲替会把消费 spec 的引用也改错。做法是:先改声明与 barrel,再让编译器把所有断裂点列出来逐个判定。人工排除的真危险点包括 app-shell/…/clientValidation.ts(从 @objectstack/spec/ui 导入 ReportSchema/ThemeSchema)、app-shell/…/report-schema.ts、以及 spec-report.ts:51(ReportSchema as SpecReportSchema_ 的导入别名)—— 这些一处未动。

tsc 确实抓到了 3 处漏改(data-protocol.tsFilterOperator 导入、registry.tsSpanSchema 导入、以及上面那个联合重名),都已修正。

验证

  • 台账 144 → 129,用 --ledger 重生成并逐条 diff:removed 恰为这 15 个、added 为空,没有误抹其他包的债务;
  • 变异测试:把 FilterBuilderCondition 改回 FilterCondition → 守卫按名+按文件报红;
  • 全仓 type-check 78/78;
  • 全量测试 8696 断言绿(752 文件)。

BREAKING CHANGE

@object-ui/types 的 15 个导出改名且无别名。仓内所有消费者已在本 PR 内更新(components / core / data-objectstack / mobile / plugin-report)。仓外消费者需要跟着改。

🤖 Generated with Claude Code

…ith a spec name (objectstack#4115 group A)

These are the triage's COINCIDENCE verdicts: local concepts that share a
`@objectstack/spec` export's NAME while modelling something different.
The name itself is the defect — #4115's own framing is that an agent reads
the familiar name, assumes the spec's semantics, and builds on it (that is
how #2901 was filed with a backwards premise). Renamed outright, with no
back-compat aliases:

  FilterCondition        -> FilterBuilderCondition        (spec: recursive ObjectQL filter AST)
  FilterOperator         -> FilterBuilderOperator         (spec: WebSocket subscription operators)
  FilterConditionSchema  -> FilterBuilderConditionSchema
  EventHandler           -> UIEventHandler                (spec: kernel event-bus subscription)
  CacheStrategy          -> FetchCacheStrategy            (spec: cache EVICTION policy, not fetch order)
  MutationEvent          -> DataSourceMutationEvent       (spec: a string enum, not an object)
  ExpressionSchema       -> ExpressionNodeSchema          (spec: the L1 CEL expression envelope)
  GroupByNode            -> GroupByClauseNode             (spec: a single grouping target)
  SpanSchema             -> TextSpanSchema                (spec: an OpenTelemetry tracing span)
  BatchOperationResult   -> BatchOperationSummary         (spec: ONE record's result; this is the rollup)
  ReportSchedule         -> ReportScheduleConfig          (spec: a persisted server-side row)
  ReportSchema           -> ReportComponentSchema         (spec: the report metadata document)
  ThemeSchema            -> ThemeComponentSchema          (spec: a theme DEFINITION; this is the switcher)
  ValidationRule (field-types) -> FieldConstraints        (spec: a named server-side rule)
  ValidationRule (form)        -> FieldValidationRules

Two follow-on decisions the renames forced:

- objectui had TWO conflicting local `ValidationRule`s — a flat constraint
  bag in field-types.ts and an RHF-style wrapped one in form.ts, sharing
  every key name with incompatible value shapes. The barrel exported only
  the second (the first was omitted specifically to dodge the collision),
  so a consumer deep-importing field-types silently got a different type.
  They now have distinct names.
- `zod/reports.zod.ts` already used `ReportComponentSchema` for the
  discriminated UNION, so it becomes `ReportUnionSchema` — matching the
  convention `zod/theme.zod.ts` already follows (node = *ComponentSchema,
  union = *UnionSchema). The deprecated `ThemeSchema` alias is deleted
  rather than kept, per the same no-alias directive.

Ledger 144 -> 129, regenerated with `--ledger` and diffed entry by entry:
the removals are exactly these 15 names, no other package's debt dropped.
Mutation-tested: re-declaring `FilterCondition` under the spec's name
fails the guard by name and file.

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

BREAKING CHANGE: 15 type/schema exports of `@object-ui/types` are renamed
with no aliases. Consumers importing the old names must update; every
in-repo consumer is updated in this commit.

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 3:34pm

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-BuSBy84N.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) 463.63KB 101.25KB
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) 183.94KB 48.25KB
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

@os-zhuang
os-zhuang merged commit 1035ff5 into main Jul 30, 2026
16 checks passed
@os-zhuang
os-zhuang deleted the claude/spec-debt-groupa-renames branch July 30, 2026 15:41
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