Skip to content

build-docs.ts 的 schema→页面索引按「裸名字」全局建表,同名跨 category 的 schema 会被归到错误的页面 #4696

Description

@os-zhuang

在 #4684(C9)实施过程中实证发现的一个独立缺陷。未在该 PR 内修复(范围外,按第十条军规立单),未认领。

现象

packages/spec/scripts/build-docs.ts 的 scanCategories() 用裸 schema 名做全局 key:

for (const { slug, rel } of collectZodFiles(dir)) {
  // …
  while ((match = regex.exec(content)) !== null) {
    const finalName = schemaNameFromExportKey(match[1]);
    schemaCategoryMap.set(finalName, category);   // ← key 只有名字,没有 category
    schemaZodFileMap.set(finalName, slug);        // ← 同上
  }
}

两张表都不带 category 前缀,所以同名但分属不同 category 的两个声明会互相覆盖,谁赢取决于 CATEGORIES 的遍历顺序。赢的那一侧的 slug 会被用来决定输的那一侧的页面归属。

实证

RateLimitConfig 此前在 integration/connector.zod.ts 与 shared/http.zod.ts 各有一个声明(#4684 处理的双源)。shared 后遍历,于是 schemaZodFileMap['RateLimitConfig'] = 'http' 覆盖了 'connector',结果 connector 侧那个 schema 被写进了一个根本不存在的源文件对应的页面:

  • content/docs/references/integration/http.mdx —— 目录下没有 integration/http.zod.ts;
  • 该页面只有一个 section,就是声明在 integration/connector.zod.ts 里的 RateLimitConfig;
  • content/docs/references/integration/meta.json 因此也长期列着一个 "http" 页。

#4684 把 connector 侧改名为 ConnectorRateLimitConfig 后名字不再碰撞,gen:docs 自动把它归位到 integration/connector.mdx,并删除了 integration/http.mdx、移除了 meta 里的 "http" 条目 —— 这就是覆盖关系的直接证据(改名是唯一变量)。

为什么值得单独修

  1. 它不随双源账清零而自动消失。 今天 dual-source-exports.baseline.json 还剩 16 条,其中 ConflictResolution / DataSyncConfig / FieldMapping / EnvironmentArtifact / PackageDependency / TenantPlan 等都是跨 category 同名,每一对都可能正在被错误归页(未逐一核实,建议开工时先枚举)。
  2. 它会让文档说假话。 页面里的 Source: 指针与 import { X } from '@objectstack/spec/<category>' 示例是按归页结果拼的,归错页 = 指向一个不含该声明的文件。这属于 AGENTS.md「Machine-readable surfaces must not lie」同一类。
  3. 没有任何门禁能发现它。 check:docs 比较的是 build-docs.ts 自己的输出与磁盘,生成器错了它就一起错(和 build-schemas.ts 用 replace('Schema','') 剥后缀,前缀含 Schema 的 4 个 schema 名被截断($id / 文档页名 / import 全错) #4592 里 replace('Schema','') 那个 bug 同源:两个生成器共享 lib/schema-name.ts 是为了不再漂移,但索引的 key 结构没有一起收敛)。

建议方向(待裁决,不要直接猜)

把两张表的 key 从 name 改成 `${category}/${name}`(与 build-schemas.ts 的 def key 口径一致),并在发现同 category 内重名时报错而不是覆盖。需要确认的是:跨 category 的合法 re-export(同一个声明,多个入口)在新口径下会得到多个条目,归页策略要明确 —— 是按声明所在文件归一次、其余入口只出 import 示例,还是每个 category 各出一页。这会影响 content/docs/references/** 的页面集合与 meta.json,属于文档 IA 决定。

关联:#4684(发现处)、#4535(双源主单)、#4592(同一对生成器的另一处 key 处理 bug)、#4446(dual-source 门禁)。

Activity

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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions