Skip to content

refactor(types,rest,metadata,analytics): Postgres "x" of relation "y" 短语收归 @objectstack/types 一处 - #7021

Merged
os-project-manager merged 3 commits into
mainfrom
claude/issue-6615-relation-subobject-phrase
Aug 9, 2026
Merged

refactor(types,rest,metadata,analytics): Postgres "x" of relation "y" 短语收归 @objectstack/types 一处#7021
os-project-manager merged 3 commits into
mainfrom
claude/issue-6615-relation-subobject-phrase

Conversation

@os-project-manager

@os-project-manager os-project-manager commented Aug 9, 2026

Copy link
Copy Markdown
Collaborator

Fixes #6615

普查结果(先测量,再动手)

卡片说三处,实测也是三处生产站点,另有第四份拷贝在测试里(同一条短语,按 scope 规则一并收编):

# 站点 形状 用途
A packages/rest/src/rest-server.ts mapDataError#5352 严格,带捕获组 提取列名 ⇒ 42703 答 400 INVALID_FIELD 而非 404
B packages/services/service-analytics/src/analytics-service.ts MISSING_COLUMN_OF_RELATION#6035 与 A 逐字节相同 扣除,让缺列保持硬失败
C packages/metadata/src/utils/schema-sync-errors.ts MISSING_TABLE.excludes#6347 刻意更宽 排除,在缺表判定前先出局
D service-analytics/src/__tests__/missing-column-phrase-hard-failure.test.ts:200 又一份 A 的拷贝 守护 fixture「别和 REST 面漂移」

它们一致吗? A 与 B 逐字节相同;C 刻意不同,且站点注释已写明理由。所以不是「三处不一致、要挑一个最好抽的」——而是两种宽度都对,取决于每处哪个方向的误差安全:A/B 提取,过宽会把真缺表变成硬失败、回退 #5033 的宽容,漏匹配只是消息含糊;C 排除,过宽只是把良性判定变响亮,漏匹配会让 event_seq 从 1 重启撞进有行的历史表。故按分诊要求做成两个独立导出,未合并。

D 是最值得记的一处:它为「两张面孔别对不上」而写,却把断言打在其中一面的私有复述上——它本身就是它要防的漂移。现改为直接问共享解析器,并顺带断言取出的列名。

卡片正文的两处更正(实测,均已按更正后的事实实施)

卡片正文有两处与 origin/main 不符,都在动手前测出,本 PR 按实测结果而非卡片结论实施:

  1. packages/metadata 不依赖 @objectstack/types」——错。 packages/metadatapackages/restdependencies都已有 @objectstack/types;真正没有这条边的是 packages/services/service-analytics(其 deps 仅 @objectstack/core + @objectstack/spec)。卡片把「需要检查依赖方向」的警告挂错了包,因此下面「新依赖边」一节讨论的是 service-analytics,而不是卡片点名的 metadata。
  2. 援引 isMissingTableErrorloadMetaFromDb 用 /no such table/i 正则判「良性首启」,其余 sys_metadata 读失败吞成 console.warn + loaded:0 —— isMissingTableError 的手抄第二份 #5841)作为「选家先例」——错。 它并不在 @objectstack/types,而在 packages/metadata/src/utils/schema-sync-errors.ts,经 @objectstack/metadata/errors 再导出。唯一约束冲突没有单一判别谓词:仓内四套各自为政的方言词表,REST 的 409 映射漏掉 MySQL(Duplicate entry 落成 500 INTERNAL_ERROR) #6250 的 docblock 引用它指的是「命名一个共享判定」这个动作先例,不是落户位置先例。types 里真正的同类先例是 unique-violation.ts唯一约束冲突没有单一判别谓词:仓内四套各自为政的方言词表,REST 的 409 映射漏掉 MySQL(Duplicate entry 落成 500 INTERNAL_ERROR) #6250,驱动错误串解析)与 module-not-found.ts(framework#3265,「single shared owner … so the parallel loaders cannot drift apart」)——本 PR 依据的是这两个。

改动

packages/types/src/relation-sub-object.ts(新,不 import 任何东西):

  • matchMissingColumnOfRelation(message) —— 严格提取器,返回列名
  • isRelationSubObjectPhrase(message) —— 宽检测器,无捕获组(故意,使其无法被误用来提取)

两条模式与原站点逐字节相同,行为逐字保持。

反向验证(预测先写盘,三轮)

⚠️ 先说清楚:「把一个消费者改回开码形式、看测试变红」单独做不出红,因为抽取在构造上就是保行为的(A/B 与严格式逐字节相同,C 与宽式逐字节相同)。照那样报一个红是伪造。可得的真红是差分——破坏共享定义,看谁跟着动。

轮次 操作 预测 实测
1 只废掉严格提取器 types 红 / rest 红 / analytics 红 / metadata 绿(对照) ✅ 全中:6 红、2 红(正是 → 400 INVALID_FIELD 那条)、4 红、588 全绿
2 保持破坏,把 B 改回开码正则 B 行为测试转绿,只剩那条直接 import 的守护测试红 ✅ 4 红 → 1 红,幸存者正是该守护测试
3 只废掉宽检测器 metadata 红 / rest+analytics 绿(镜像对照) ✅ 3 红 / 1126 全绿 + 1415 全绿

轮 1 的 metadata 全绿与轮 3 的镜像,共同钉住两种宽度仍是两条——合并成一条正是卡片记录在案的风险。轮 1 红 + 轮 2 同一包转绿,才是「B 确实在读这个家」的证明;任一轮单独都不是。

超串洞本身在 relation-sub-object.test.ts 里被显式钉住:column "label" of relation "sys_team" does not exist 逐字包含合法的 relation "sys_team" does not exist,且后者能被两处都在用的 postgres 锚点匹配——所以这不是能靠收紧正则绕开的擦边。

一条新依赖边 —— 经 PM 裁定 A 保留

依赖边经 PM 裁定 A 保留,理由见 #6615 评论。 该裁定为架构判断(包依赖走向,非产品或访问面决策),未上抛维护者。

@objectstack/metadata@objectstack/rest 本来就依赖 @objectstack/types只有 @objectstack/service-analytics 需要新增这条边。#6250 立下的「每个消费者都已依赖它,所以采纳从不加边」的条件在这里不成立,故当初显式上报而非默认通过:

回滚成本:1 行 package.json + 1 行 import。

验证

  • @objectstack/types 9 files / 230 tests、@objectstack/metadata 28 / 588、@objectstack/service-analytics 71 / 1440、@objectstack/rest 73 / 1142 —— 合并 origin/main(落后 36 commits)后重装重建复测,全绿。
  • 四包 build 全过(这三个消费者无 typecheck 脚本,类型检查走 tsup dts)。
  • pnpm lint 绿;check:error-code-casing / check:route-envelope / check:engine-double-contract / check:spec-parsed-alias / check:published-files / check:type-check-coverage / check:nul-bytes / check:empty-changeset 全 PASS。
  • check:api-surface 经核查仅覆盖 @objectstack/spec 自身 subpath 基线(无基线提及 @objectstack/types),本 PR 未触碰 packages/spec,故不涉及。
  • 控制字节自查(NUL 之外)clean。

Changeset

@objectstack/types minor(新增导出、纯追加),三个消费者 patch(内部实现,行为逐字不变)。


Generated by Claude Code

@vercel

vercel Bot commented Aug 9, 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 9, 2026 9:23am

Request Review

@github-actions

github-actions Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 4 package(s): @objectstack/metadata, @objectstack/rest, @objectstack/service-analytics, @objectstack/types.

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

  • content/docs/ai/connect-mcp.mdx (via @objectstack/rest)
  • content/docs/api/data-api.mdx (via @objectstack/service-analytics)
  • content/docs/api/error-handling-server.mdx (via @objectstack/rest)
  • content/docs/api/index.mdx (via @objectstack/rest, @objectstack/service-analytics)
  • content/docs/concepts/metadata-lifecycle.mdx (via @objectstack/metadata)
  • content/docs/kernel/cluster.mdx (via packages/metadata)
  • content/docs/kernel/services-checklist.mdx (via @objectstack/metadata, @objectstack/service-analytics)
  • content/docs/permissions/authentication.mdx (via @objectstack/rest)
  • content/docs/permissions/sharing-rules.mdx (via @objectstack/service-analytics)
  • content/docs/permissions/system-context.mdx (via packages/rest)
  • content/docs/plugins/index.mdx (via @objectstack/rest)
  • content/docs/plugins/packages.mdx (via @objectstack/metadata, @objectstack/rest, @objectstack/service-analytics, @objectstack/types)
  • content/docs/protocol/kernel/http-protocol.mdx (via @objectstack/metadata, @objectstack/rest)
  • content/docs/protocol/kernel/i18n-standard.mdx (via packages/rest)
  • content/docs/protocol/kernel/metadata-service.mdx (via @objectstack/metadata)
  • content/docs/releases/implementation-status.mdx (via @objectstack/rest, @objectstack/service-analytics)
  • content/docs/releases/v12.mdx (via @objectstack/metadata, @objectstack/rest)
  • content/docs/releases/v17.mdx (via @objectstack/rest, @objectstack/service-analytics)
  • content/docs/releases/v9.mdx (via @objectstack/metadata, @objectstack/service-analytics)

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.

@github-actions github-actions Bot added size/m documentation Improvements or additions to documentation dependencies Pull requests that update a dependency file tests tooling labels Aug 9, 2026
@os-project-manager
os-project-manager marked this pull request as ready for review August 9, 2026 09:53
@os-project-manager
os-project-manager added this pull request to the merge queue Aug 9, 2026
Merged via the queue into main with commit 91cefb8 Aug 9, 2026
28 checks passed
@os-project-manager
os-project-manager deleted the claude/issue-6615-relation-subobject-phrase branch August 9, 2026 10:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file documentation Improvements or additions to documentation size/m tests tooling

Projects

None yet

2 participants