Skip to content

docs(guide): 把 building-crud-app 的两条死链改指真实存在的文档页 - #3509

Merged
yinlianghui merged 1 commit into
mainfrom
claude/issue-3507-dead-example-links
Aug 7, 2026
Merged

docs(guide): 把 building-crud-app 的两条死链改指真实存在的文档页#3509
yinlianghui merged 1 commit into
mainfrom
claude/issue-3507-dead-example-links

Conversation

@yinlianghui

Copy link
Copy Markdown
Collaborator

Fixes #3507

背景

content/docs/guide/building-crud-app.md 的 "Next Steps" 有两条指向 examples/todoexamples/crm 的 GitHub 绝对 URL。这两个目录在 12b287d8b(2026-05-02,"refactor: remove example Todo application and related files",一次删掉 80 个 examples/todo/examples/crm/ 下的文件)里已随 Todo/CRM 示例一起移除,链接自那时起就是 GitHub 404,至今约三个月无人发现 —— 因为两个门禁按设计都看不见它:

这是 #3486/#3495examples/hello-world/README.md../crm/../todo/ 两条死链的同源问题在文档站这一侧的残留:同一次示例删除,README 那侧已修,docs 这侧漏了。

改动

只动两行 link,标签按真实目标如实改写,不假装存在一个等价的示例 app(沿用 #3506Example: CRM Application 改成 Example: ObjectStack Console Starter、以及 #3495 "描述取自各自 README,未臆造" 的口径):

原目标(404) 新目标 为什么是它
328 examples/todo /docs/plugins/plugin-kanban 该 bullet 承诺的是 "Add a Kanban board view using @object-ui/plugin-kanban"。Kanban 插件文档页正是这件事的正面回答,页内还挂着两个真实可跑的 board schema(plugin-kanban/basic-kanban-boardplugin-kanban/advanced-kanban-with-badges-and-limits),比原来指向一个"待办示例 app"更直接。
330 examples/crm /docs/fields/lookup 该 bullet 承诺的是 "Build multi-object apps with relationships"。Lookup Field 文档页开篇即 "reference field for creating relationships between objects and records",且 schema 是 type: 'lookup' | 'master_detail' —— 单对象 CRUD 教程读完后想把对象 B 接到对象 A 上,要看的就是这一页。

关于 330 为什么没跟着 #3506 指向 console-starter

#3506 把另一处 Example: CRM Application 改指了 examples/console-starter,看起来"同名同解"更一致。但两处的上下文不同:#3506 那条在 objectos-integration 的 Resources 清单里,承诺仅仅是"一个示例 app";本文这条承诺的是关系(relationships)怎么建console-starter/src/App.tsx 通读下来是 routing + auth 脚手架(ConsoleShell/AuthenticatedRoute/Default* 页面),对象与关系全部来自 ObjectStack 后端,它并不演示关系建模。指过去会是第二次"标签夸大目标"。这里跟随 #3506 的是原则(如实改写标签),不是那个具体目标。

顺带的一个真实收益(不是本单的目标)

两条链接从"带 scheme、门禁一律跳过"的那一类,落进了 /docs/... 路由这一类 —— 而 /docs/... 恰恰是 check-doc-links.mjs 今天在 main 上就已经严格校验的一类。也就是说这两条链接以后再烂掉,PR 会直接红,不需要等 #3507 里 hold 住的方向 2(给"指向本仓库自身的 GitHub 绝对 URL"补离线校验)。方向 2 仍然有价值 —— 它覆盖 #3506 新引入的 8 条同形态链接 —— 本 PR 未触碰 scripts/check-doc-links.mjs,把那块完整留给 #3506 合并后的那张 gate 扩展单。

验证

正反两个方向都先预测、后执行:

  1. 目标真实存在(离线判定) —— content/docs/plugins/plugin-kanban.mdxcontent/docs/fields/lookup.mdx 均在盘上;examples/todoexamples/crmNo such file or directory
  2. node scripts/check-doc-links.mjsDocs links are valid.(exit 0)。
  3. 探针 A(预测:红) —— 把新 href 改成 /docs/plugins/plugin-kanban-nope,门禁 exit 1 并精确点名 building-crud-app.md:328。证明新链接确实被校验,而不是换了个门禁同样看不见的写法。
  4. 探针 B(预测:绿) —— 把第 328 行原样还原https://github.com/objectstack-ai/objectui/tree/main/examples/todo,门禁仍然 Docs links are valid.(exit 0)。这条 404 就在文件里,门禁绿着 —— 这正是本 issue 描述的盲区,也是探针 A 的对照组。
  5. pnpm exec vitest run scripts/Test Files 14 passed (14) / Tests 204 passed (204)。符合预测:纯文案改动,verdict 不动;唯一变的是覆盖面——the repo it guards / has no broken internal docs links 这条用例现在多校验了这两条链接(此前它们作为外链被整条跳过)。
  6. node scripts/check-control-bytes.mjs → OK(3686 个文本文件);另对改动文件单独 grep -naP 自查控制字节,无命中。

已知的先存红:type-check:scripts

pnpm run type-check:scripts 在本分支报

scripts/__tests__/check-doc-links.test.ts(7,1): error TS2578: Unused '@ts-expect-error' directive.

这是 origin/main(f995a45)自带的,不是本 PR 引入:本 PR 的 diff 只有 content/docs/guide/building-crud-app.md 一个文件(2 增 2 删),git show origin/main:scripts/__tests__/check-doc-links.test.ts 第 7 行的 @ts-expect-error 原样还在。即 #3504,热修 PR #3505 尚未落到 main。按分诊要求不在本 PR 里顺手改,#3505 合并后 update branch 即可转绿。

范围


Generated by Claude Code

`examples/todo` and `examples/crm` have never existed on `main` (examples/
holds README.md, byo-backend-console, console-starter, hello-world,
schema-catalog), so both "Next Steps" links were live GitHub 404s.

Retarget each to the page that actually answers the bullet, and retitle the
label to name that page honestly rather than dressing it up as an example app
that does not exist (precedent: #3506's "Example: CRM Application" ->
"Example: ObjectStack Console Starter").

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

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

Request Review

Copy link
Copy Markdown
Collaborator Author

更正正文里「已知的先存红」一节的口径 —— 那段写于本地跑完 type-check:scripts 之后、CI 报回之前,说法偏重了。

CI 实际结果:本 PR 一共 5 个 check,没有 Type Check 这一项

check 结论
Internal Docs Link Check success
Control Byte Scan success
Vercel Preview Comments success
dependabot skipped
label (housekeeping)

scripts 的 Type Check 作业带 path filter,本 PR 的 diff 只有 content/docs/guide/building-crud-app.md,所以它根本没触发。也就是说 #3504 的 TS2578 在本 PR 上既不红也不绿,是「不适用」。

正文那段仍然成立的部分:该错误确实存在于 origin/main(f995a45)自身,我在本地 pnpm run type-check:scripts 复现了它,且它与本 PR 无关(diff 未触碰 scripts/)。不成立的部分:「#3505 合并后 update branch 即可转绿」—— 本 PR 没有等它转绿的东西,无需为此 update branch。留档以免 reviewer 误以为本 PR 挂着一个待修的红。


Generated by Claude Code

@yinlianghui
yinlianghui marked this pull request as ready for review August 7, 2026 02:11
@yinlianghui
yinlianghui added this pull request to the merge queue Aug 7, 2026
Merged via the queue into main with commit 15abf9b Aug 7, 2026
6 checks passed
@yinlianghui
yinlianghui deleted the claude/issue-3507-dead-example-links branch August 7, 2026 02:11
akarma-synetal pushed a commit to akarma-synetal/objectui that referenced this pull request Aug 10, 2026
…bjectstack-ai#3571)

三条链接的目标在磁盘上都不存在,且这两个文件不在任何门禁的扫描面内
(check-doc-links 的 SCAN_ROOTS 是 content/docs + examples + 根 README;
lychee 扫 content/docs、docs、README.md),所以一直静默失效。

- CONTRIBUTING.md:153 `./docs/spec/architecture.md`(`docs/spec/` 目录根本不存在)
  → `./content/docs/guide/architecture.md`。未按 issue 建议指向 `docs/ARCHITECTURE.md`:
  该文件的 H1 是 "Console Streamlining - Architecture Guide",讲的是 app-shell/providers
  那次重构的迁移路径,而链接所在的 "Architecture Overview" 一节讲的是 monorepo 包结构与
  设计原则 —— `content/docs/guide/architecture.md`(标题即 "Architecture Overview",
  含 Package Structure / Core Philosophy 两节)才是这句 "for details" 真正承诺的内容。
  链接文字同时改成目标文档的真实标题,避免用旧标签包装另一个目标。
- CONTRIBUTING.md:469 `./docs/README.md` → 删除整句。仓库里没有、也从未有过
  "Documentation Guide" 这份文档;它承诺的细节就在它所处的 Documentation 一节里
  (Writing Documentation / Documentation Guidelines / Link Conventions / Validating Links),
  前一句也已自成完整陈述。按 objectstack-ai#3506/objectstack-ai#3509 的先例,如实删除而不是改指别的文档。
- ROADMAP.md:1892 扩展名错 `.mdx` → `.md`。真实文件是
  `content/docs/guide/plugin-development.md`;保持相对文件链接的写法,与同一列表里
  `./CONTRIBUTING.md`、`./QUICK_REFERENCE.md` 一致。

本 PR 只做第 1 步。issue 的第 2 步(把这两个文件与 `docs/**` 纳入 SCAN_ROOTS)
刻意留下,不碰 scripts/check-doc-links.mjs。


Claude-Session: https://claude.ai/code/session_01GTRjn8xBqp75dk7kFupVRt

Co-authored-by: Claude <noreply@anthropic.com>
akarma-synetal pushed a commit to akarma-synetal/objectui that referenced this pull request Aug 10, 2026
…t path filtering into the jobs (objectstack-ai#3523 steps 1-2) (objectstack-ai#3722)

* ci(step 1): subscribe ci/lint/control-bytes/docs-links to merge_group (objectstack-ai#3523)

Step 1 of objectui#3523, on its own commit as the issue's ruling requires:
this is a pure addition and changes nothing about which pull requests or
pushes run CI.

The merge queue is enforced on this repository by a ruleset (objectstack-ai#3243 measured a
direct push to `main` returning 405 `Changes must be made through the merge
queue`), but not one of the 22 workflows subscribed `merge_group` — repo-wide
`event=merge_group` runs stood at total_count = 0. A queue nothing subscribes
to can only carry an empty required-check set, so it rebuilt each PR on the
current `main` and let it through without validating anything. On 2026-08-07
that was cashed in: objectstack-ai#3503 / objectstack-ai#3510 / objectstack-ai#3516 merged between 02:11Z and 02:15Z
with `Type Check` at conclusion=failure, on a `main` poisoned by objectstack-ai#3498, and
objectstack-ai#3505 had to hot-fix it.

The four workflows named by the issue now carry the trigger. It is spelled
`merge_group: types: [checks_requested]`; `checks_requested` is the only
activity type GitHub defines for this event today, so this is equivalent to
objectstack's bare `merge_group:` and merely refuses to inherit a second type
added later.

Two `ci.yml` jobs additionally needed to be told the third event exists —
both changes are no-ops for `pull_request` and `push`:

- `test` moves from `if: github.event_name == 'pull_request'` to
  `!= 'push'`, so a queue build actually runs the suite instead of skipping
  every shard.
- `docs`'s `should_run` treated anything that is not `push` as a pull request
  and diffed `github.event.pull_request.*`, which is null on a queue build —
  an empty revision range, i.e. the site build silently skipped on the last
  check before `main`.

Verified rather than assumed: `concurrency` needs no merge-queue case. On
`merge_group` the group expression falls back to `github.ref`, which is the
queue's own generation — measured on objectstack, whose 3552 queue runs report
head_branch `gh-readonly-queue/main/pr-6594-251e888a…`. That can collide with
neither a PR group (a bare number) nor a push group (`refs/heads/main`).

Refs objectstack-ai#3523

* ci(step 2): move ci/lint path filtering out of the PR trigger into the jobs (objectstack-ai#3523)

Step 2 of objectui#3523, deliberately a separate commit from step 1: step 1
adds runs that did not exist, this one changes which pull requests start CI,
and mixing them would make that impossible to review apart.

`on.pull_request.paths-ignore` skips the WHOLE workflow when every changed
file matches, and GitHub has no per-job path filter. A docs-only or
changeset-only PR therefore started neither `ci.yml` nor `lint.yml` — objectstack-ai#3509
measured zero check runs from them. A check that is never *created* does not
fail a required-status-check rule, it leaves the pull request pending; inside
the merge queue it fails on the ruleset's 60-minute status-check timeout. So
none of `Lint`, `Type Check`, `Test (shard N/4)`, `Build & E2E` or
`Changeset Fixed Group Check` could be made required while the filter lived
on the trigger — which is why the queue's required set was empty to begin
with.

The filter is not deleted, it moves. `type-check`, `test`, `e2e` (ci.yml) and
`lint` (lint.yml) each open with a `Decide whether this change needs a full
run` step, and every step after it carries
`if: steps.relevant.outputs.should_run == 'true'`. The job always runs and
always reports; the paths decide only whether it does any work. That is the
shape `ci.yml`'s `docs` job has used since objectstack-ai#3450 — not a new mechanism — and
the exclusion lists are byte-for-byte the `paths-ignore` they replace, so
which PRs pay for a full run is exactly as before.

Two deliberate narrowings, both stated so they can be argued with:

- `paths-ignore` stays on the `push` trigger. Branch protection and the merge
  queue judge pull requests and queue builds, never pushes to `main`, so the
  push lane gains nothing from losing it and would cost a full CI run on
  every docs merge. It also gives the ignore list one authored home, which
  `merge-queue-reporting.test.ts` then pins the in-job copies against.
- `changeset-check` is not gated. It is a checkout and one `node` call, so
  short-circuiting it would cost more in complexity than it saves.

The gate fails OPEN: an unresolvable diff runs everything rather than
reporting green having built nothing (objectstack#4928's filter contract).
Measured both ways against a fixture repository — as shipped an unreachable
base sha yields should_run=true; rewritten with the `|| echo ""` spelling
`ci.yml`'s older `docs` gate still uses, the same input yields
should_run=false, i.e. a silent full skip. That pre-existing `docs` gate is
reported separately rather than changed here.

`scripts/__tests__/merge-queue-reporting.test.ts` pins both steps; against
the pre-change workflows 9 of its 10 assertions go red, each naming its own
regression. `lint-workflow.test.ts`'s TypeScript-exclusion tripwire now reads
the in-job list as well as the trigger, which is where that list now lives.

Refs objectstack-ai#3523

---------

Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants