Skip to content

feat(spec)!: 跨形态同名三条收敛 — ShareRecipientType / TransformType / suggestFieldType (#4539) - #4571

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-4539-cross-form-dual-source
Aug 2, 2026
Merged

feat(spec)!: 跨形态同名三条收敛 — ShareRecipientType / TransformType / suggestFieldType (#4539)#4571
os-zhuang merged 1 commit into
mainfrom
claude/issue-4539-cross-form-dual-source

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

Fixes #4539

基线里最阴险的三条:同名但不同形态(type≠const,或两个不相干的 function),选错一侧连"形状重叠、编译通过"的掩护都没有。每条都按三仓 import 级扫描(framework、/workspace/cloud、objectui 浅克隆)单独判真源 —— cloud 与 objectui 对这三个名字的引用均为零,全部消费方都在本仓。

逐条判定

1. ShareRecipientType — 改名(两个活概念共用一名)

  • 真源(保名):security/sharing.zod.ts 的 zod enum(user | team | position | unit_and_subordinates | business_unit)—— 可授权的共享规则收件人词表,被 SharingRuleSchema.sharedWith.type 直接消费,与 contracts 的 SharingRuleRecipientType(多一个保留的 queue)本来就是刻意配对。
  • contracts 侧:描述的是另一个概念 —— sys_record_share 行的 recipient_type。它自称 "mirrors spec/security" 早已失真(security 侧 groupteamguest 已删),且成员 role 与存储侧 select(user | group | position | unit_and_subordinates | guest)不符 —— role 从来不是可持久化的值。改名 RecordShareRecipientType,成员对齐存储 select(roleposition,补完 ADR-0090 D3 leftovers in plugin-sharing: sys_record_share role recipient enum + "角色及下级" translations #2724 D3 改名在 changelog 里声称完成、实际漏掉的那一半),注释改为指向它真正镜像的存储侧 gate。plugin-sharing 的 re-export 同步改名;运行时仍只强制 user(grant() 拒绝其余值),行为零变化。测试里原本被迫的 as any 铸型随之删除 —— 类型现在能如实表达。

2. TransformType — 改名(shared 侧双名零消费者)

  • 真源(保名):data/mapping.zod.ts 的导入映射 enum(none | constant | lookup | split | join | javascript | map),被 ImportMapping 的 transform 字段活消费。
  • shared 侧:TransformTypeSchema(transform 配置对象的 discriminated union,形态完全不同)+ 推断类型别名 TransformType,两个名字在三仓都是零 importer。整对改名 FieldMappingTransformSchema / FieldMappingTransform(它就是 FieldMapping.transform 的取值)。为什么不是只删别名:build-docs 生成 import type { X } 示例时机械剥 Schema 后缀,别名不在了文档照样宣传一个不存在的导出 —— 该生成器缺陷已按第十条军规单独立案 build-docs.ts 用「剥掉 Schema 后缀」推导 import type 示例,类型别名不存在时生成的文档引用无法编译 #4570(unassigned)。json-schema.manifest.jsonshared/TransformType 键随之改为 shared/FieldMappingTransform(蓄意改名,非静默下架)。不引入过渡别名:零消费者,干净断,changeset 带 FROM → TO。

3. suggestFieldType先 diff 两份实现,行为判定如下

两份实现从来不是同一函数的分叉,是两个用途不相干的函数共用一名,签名、语义、返回类型全不同:

输入 shared/suggestions.zod(. + ./shared,同一符号) data/type-compat(./data)
签名 (input: string) => string[] (rawType: string, dialect?: SqlDialect) => FieldType | undefined
用途 作者拼错 FieldType 时的 "Did you mean?"(别名表 + Levenshtein),喂 zod error map SQL 列类型 → ObjectStack 字段类型的确定性映射(ADR-0015 §4.6,外部数据源起草)
'varchar(255)' [](模糊匹配不到) 'text'
'text_area' ['textarea'] undefined(不是 SQL 类型)
'int' ['number'](数组) 'number'(标量)

不是潜伏 bug:两个调用方(error map、service-datasource)各自 import 的都是自己要的那份,运行时行为无分歧。真正的危险在编写时选错:auto-import 按名挑错一侧后,标量位置来了个数组 —— 而 [] 是 truthy,if (suggested) 这类写法编译通过、静默走错分支。处置:./data 侧改名 suggestFieldTypeForSqlType(typo-suggester 保名保 root 导出);上表的行为分歧已固化为 type-compat.test.ts 里的交叉 pin,两函数若日后被人为归并,pin 会逼着显式删除。

基线

dual-source-exports.baseline.json 恰好删除 3 行(gate 点名的即这 3 行,main 移动未产生额外 stale 行):

  • ShareRecipientType — [./contracts (type)] ≠ [./security (const)]
  • TransformType — [./data (const)] ≠ [./shared (type)]
  • suggestFieldType — [., ./shared (function)] ≠ [./data (function)]

验证

  • pnpm --filter @objectstack/spec build
  • check:generated 8/8 up to date ✅(api-surface + reference docs 经 --fix 定向再生)
  • check:dual-source-exports ✅(self-test 通过;4306 名字 / 16 入口,基线 38 → 35)
  • spec test:287 文件 / 7271 用例全过 ✅;spec typecheck
  • 全仓 pnpm build 71/71 ✅、pnpm typecheck 122/122 ✅、pnpm test 132/132 ✅

Changeset

@objectstack/spec: major@objectstack/plugin-sharing: major,三条 FROM → TO 迁移各带一行修法(升级 agent grep 得到)。

范围外发现

🤖 Generated with Claude Code

https://claude.ai/code/session_01M9uWvoEp9CoLzYjNExj9sL


Generated by Claude Code

The three baseline rows where the two declarations sharing a name did not
even share a FORM (type vs const, or two unrelated functions), so a wrong
import-path pick had no shape overlap to hide behind. Each judged against a
three-repo import-level scan (framework, cloud, objectui — the latter two
contain zero references to all three names).

- ShareRecipientType: the security zod enum (authorable sharing-RULE
  recipients) keeps the name; the contracts type is a DIFFERENT concept —
  the recipient_type a sys_record_share ROW may carry — renamed
  RecordShareRecipientType, member set aligned to the storage select it
  actually mirrors ('role', never persistable, -> 'position', completing
  the #2724 D3 rename its changelog already claimed). plugin-sharing
  re-export renamed in lockstep; only 'user' is enforced today, unchanged.

- TransformType: the data import-mapping enum keeps the name; shared's
  differently-shaped config-union pair (zero importers for either name in
  all three repos) renamed FieldMappingTransformSchema /
  FieldMappingTransform. Renamed rather than alias-deleted because
  build-docs derives `import type` examples by stripping 'Schema' (filed
  unassigned as #4570). json-schema.manifest key moved with it.

- suggestFieldType: diffed the two implementations FIRST — they were never
  forks of one function: shared/suggestions.zod is the typo-suggester
  (string -> string[] candidates, feeds the zod error map, keeps the name
  on . and ./shared); data/type-compat is the deterministic SQL-column ->
  FieldType mapper (ADR-0015), renamed suggestFieldTypeForSqlType.
  Divergence pinned in type-compat.test.ts: ('varchar(255)') -> [] vs
  'text'; ('text_area') -> ['textarea'] vs undefined; ('int') ->
  ['number'] vs 'number'. Not a live bug: each caller imports the one it
  means; the hazard was authoring-time wrong-pick, where `[]` is truthy.

All 3 dual-source-exports.baseline.json rows deleted; api-surface and
reference docs regenerated via check:generated --fix (8/8 green);
check:dual-source-exports green at 35 baseline rows.

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

vercel Bot commented Aug 2, 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)
objectstack Ignored Ignored Aug 2, 2026 7:19am

Request Review

@github-actions github-actions Bot added documentation Improvements or additions to documentation protocol:data tests tooling size/m labels Aug 2, 2026
@github-actions

github-actions Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 3 package(s): @objectstack/plugin-sharing, @objectstack/service-datasource, @objectstack/spec.

107 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/ai/agents.mdx (via @objectstack/spec)
  • content/docs/ai/skills-reference.mdx (via @objectstack/spec)
  • content/docs/ai/skills.mdx (via @objectstack/spec)
  • content/docs/api/client-sdk.mdx (via @objectstack/spec)
  • content/docs/api/environment-routing.mdx (via @objectstack/spec)
  • content/docs/api/error-catalog.mdx (via @objectstack/spec)
  • content/docs/api/error-handling-client.mdx (via @objectstack/spec)
  • content/docs/api/error-handling-server.mdx (via @objectstack/spec)
  • content/docs/api/index.mdx (via @objectstack/spec)
  • content/docs/automation/approvals.mdx (via @objectstack/spec)
  • content/docs/automation/connectors.mdx (via @objectstack/spec)
  • content/docs/automation/flows.mdx (via @objectstack/spec)
  • content/docs/automation/hook-bodies.mdx (via packages/spec)
  • content/docs/automation/hooks.mdx (via @objectstack/spec)
  • content/docs/automation/index.mdx (via @objectstack/spec)
  • content/docs/automation/webhooks.mdx (via @objectstack/spec)
  • content/docs/automation/workflows.mdx (via @objectstack/spec)
  • content/docs/concepts/architecture.mdx (via @objectstack/spec)
  • content/docs/concepts/design-principles.mdx (via packages/spec)
  • content/docs/concepts/index.mdx (via @objectstack/spec)
  • content/docs/concepts/metadata-driven.mdx (via @objectstack/spec)
  • content/docs/concepts/metadata-lifecycle.mdx (via packages/spec)
  • content/docs/concepts/north-star.mdx (via packages/spec)
  • content/docs/data-modeling/analytics.mdx (via @objectstack/spec)
  • content/docs/data-modeling/drivers.mdx (via @objectstack/spec)
  • content/docs/data-modeling/external-datasources.mdx (via @objectstack/spec)
  • content/docs/data-modeling/field-types.mdx (via @objectstack/spec)
  • content/docs/data-modeling/fields.mdx (via @objectstack/spec)
  • content/docs/data-modeling/formulas.mdx (via @objectstack/spec)
  • content/docs/data-modeling/index.mdx (via @objectstack/spec)
  • content/docs/data-modeling/objects.mdx (via @objectstack/spec)
  • content/docs/data-modeling/queries.mdx (via @objectstack/spec)
  • content/docs/data-modeling/schema-design.mdx (via @objectstack/spec)
  • content/docs/data-modeling/seed-data.mdx (via @objectstack/spec)
  • content/docs/data-modeling/validation-rules.mdx (via @objectstack/spec)
  • content/docs/data-modeling/validation.mdx (via @objectstack/spec)
  • content/docs/deployment/cli.mdx (via @objectstack/spec)
  • content/docs/deployment/troubleshooting.mdx (via @objectstack/spec)
  • content/docs/deployment/validating-metadata.mdx (via @objectstack/spec)
  • content/docs/getting-started/build-with-claude-code.mdx (via @objectstack/spec)
  • content/docs/getting-started/common-patterns.mdx (via @objectstack/spec)
  • content/docs/getting-started/examples.mdx (via @objectstack/spec)
  • content/docs/getting-started/quick-reference.mdx (via @objectstack/spec)
  • content/docs/getting-started/quick-start.mdx (via @objectstack/spec)
  • content/docs/getting-started/your-first-project.mdx (via @objectstack/spec)
  • content/docs/kernel/cluster.mdx (via @objectstack/spec)
  • content/docs/kernel/contracts/auth-service.mdx (via packages/spec)
  • content/docs/kernel/contracts/cache-service.mdx (via packages/spec)
  • content/docs/kernel/contracts/data-engine.mdx (via @objectstack/spec)
  • content/docs/kernel/contracts/index.mdx (via @objectstack/spec)
  • content/docs/kernel/contracts/metadata-service.mdx (via packages/spec)
  • content/docs/kernel/contracts/storage-service.mdx (via packages/spec)
  • content/docs/kernel/index.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/email-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/index.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/queue-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/sharing-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/sms-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/storage-service.mdx (via packages/spec)
  • content/docs/kernel/services-checklist.mdx (via @objectstack/plugin-sharing, @objectstack/spec)
  • content/docs/kernel/services.mdx (via @objectstack/spec)
  • content/docs/permissions/authorization.mdx (via packages/plugins/plugin-sharing, @objectstack/spec)
  • content/docs/permissions/permission-sets.mdx (via @objectstack/spec)
  • content/docs/permissions/permissions-matrix.mdx (via packages/plugins/plugin-sharing, @objectstack/spec)
  • content/docs/permissions/positions.mdx (via @objectstack/spec)
  • content/docs/permissions/rls.mdx (via @objectstack/spec)
  • content/docs/permissions/sharing-rules.mdx (via @objectstack/spec)
  • content/docs/plugins/adding-a-metadata-type.mdx (via @objectstack/spec)
  • content/docs/plugins/development.mdx (via @objectstack/spec)
  • content/docs/plugins/index.mdx (via @objectstack/spec)
  • content/docs/plugins/packages.mdx (via @objectstack/plugin-sharing, @objectstack/spec)
  • content/docs/protocol/backward-compatibility.mdx (via @objectstack/spec)
  • content/docs/protocol/diagram.mdx (via packages/spec)
  • content/docs/protocol/kernel/config-resolution.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/i18n-standard.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/index.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/lifecycle.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/plugin-spec.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/runtime-capabilities.mdx (via @objectstack/spec)
  • content/docs/protocol/knowledge.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/index.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/query-syntax.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/schema.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/security.mdx (via packages/plugins/plugin-sharing, packages/spec)
  • content/docs/protocol/objectql/state-machine.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/actions.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/concept.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/index.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/layout-dsl.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/record-alert.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/widget-contract.mdx (via @objectstack/spec)
  • content/docs/releases/implementation-status.mdx (via @objectstack/plugin-sharing, @objectstack/spec)
  • content/docs/releases/index.mdx (via @objectstack/spec)
  • content/docs/releases/v12.mdx (via @objectstack/spec)
  • content/docs/releases/v13.mdx (via @objectstack/spec)
  • content/docs/releases/v16.mdx (via @objectstack/spec)
  • content/docs/releases/v17.mdx (via @objectstack/spec)
  • content/docs/releases/v9.mdx (via @objectstack/spec)
  • content/docs/ui/actions.mdx (via @objectstack/spec)
  • content/docs/ui/create-vs-edit-form.mdx (via @objectstack/spec)
  • content/docs/ui/dashboards.mdx (via @objectstack/spec)
  • content/docs/ui/forms.mdx (via @objectstack/spec)
  • content/docs/ui/index.mdx (via @objectstack/spec)
  • content/docs/ui/public-data-collection.mdx (via @objectstack/spec)
  • content/docs/ui/setup-app.mdx (via @objectstack/spec)
  • content/docs/ui/translations.mdx (via @objectstack/spec)
  • content/docs/ui/views.mdx (via @objectstack/spec)

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

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

Labels

documentation Improvements or additions to documentation protocol:data size/m tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[#4535·B] 跨形态同名三条:ShareRecipientType(type≠const)、TransformType(const≠type)、suggestFieldType(双实现 function)

2 participants