Skip to content

fix(app-shell): nav page picker offers a draft page only when its draft body can be a nav target - #26968

Merged
objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/project-thread-cfwyv7
Oct 28, 2026
Merged

objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/project-thread-cfwyv7

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Warren · project thread
Fixes #26743

Clause-②: no
Metadata-protocol: none

维护者速读

  • 改了什么:Studio Interfaces 导航项的「页面」选择器不再列出草稿态的记录页;草稿页按其草稿正文的 type 判定,与已发布页同一规则(绑定对象的草稿动作同理)。
  • 为什么改:_drafts 行只带元数据类型 page,不带页面自身的 type,原代码对草稿行一律放行,选中草稿记录页、随应用发布后导航项打不开。
  • 风险与回滚:只改 Studio 选择器的候选列表;每个仅草稿的页面/动作多一次草稿读取;读不到正文时仍列出(与无 type 的已发布行一致)。回滚即 revert 本 PR。
  • 先看:StudioDesignSurface.tsx 的 isDraftNavTarget 与 usePackageNavTargets 中草稿循环;再看新测试 StudioDesignSurface.navPageDrafts-26743.test.tsx。
  • 两分钟验证:pnpm --dir ui exec vitest run packages/app-shell/src/views/studio-design/StudioDesignSurface.navPageDrafts-26743.test.tsx,预期 6 个测试全过。
  • 需要你做的:无,席位落地。

What changes

  • usePackageNavTargets (Interfaces nav item inspector's target picker): a draft-only row of a type whose isNavTargetRow verdict reads a body key (page: the body's type; action: objectName) is now judged on its draft body, read with client.getDraft and unwrapped by extractDraftBody, the one draft-envelope reader. A draft record page is no longer offered; a draft static page still is.
  • A body that cannot be read (no draft served, a failed read) keeps the row, as a published row with no type is kept: only a confirmed non-target is dropped. Other target types (dashboard, report, doc) read no body.
  • In-place fix named here: the same draft loop also offered a draft action bound to an object, which the nav cannot run (it runs global actions only). Same defect class, same line, same gate families; covered by one test.

Why

The _drafts header (ListDraftsResponseSchema) carries the metadata type name and the draft's label, never the body's own type, so the old loop could not filter and added every draft-only row. Fixed client-side with the existing draft read; no spec or server change.

Tests

New StudioDesignSurface.navPageDrafts-26743.test.tsx (6 tests): a draft record page is not offered; a draft static page is offered; a published record page is still not offered; CONTROL an unreadable draft body is still offered; a draft object-bound action is not offered, a draft global action is; only body-keyed types read drafts, published rows are never re-read.

Ablation (commit ca23ec4)

node scripts/ablation-replace.mjs replaced the anchor if (verdicts[i]) byName.set(row.name, row); with an always-true condition: anchor 1 -> 0, blob 8a30d22bfe30 -> e63569e6a119. Result: a draft record page is not offered and a draft action bound to an object is not offered, a draft global action is failed (2 failed, 4 passed). Restored: blob == HEAD (8a30d22bfe30), git diff HEAD empty. No dist leg: the test imports the component by relative path.

Verification

All local readings at head ca23ec41 (base aa00362f).

Local gates
  • node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack: 24 derived families, all run, every one exit 0; --ran reconciliation: 24 derived, 24 run, 0 NOT-MEASURED, 0 UNRUN.
  • node scripts/check-sdui-manifest.mjs exit 0 (and --self-test exit 0).
  • pnpm --filter @object-ui/app-shell run type-check exit 0.
  • pnpm --dir ui exec vitest run packages/app-shell/src/views/studio-design/ packages/app-shell/src/views/metadata-admin/inspectors/: Test Files 429 passed, Tests 4289 passed, 1 skipped.
  • pnpm --dir ui run check:new-line-citations: 0 new citations, exit 0.
  • node scripts/check-nul-bytes.mjs exit 0.

Changeset: none. @object-ui/app-shell is private: true, so nothing publishes; skip-changeset is declared with this PR.

Acceptance notes

  • Each draft-only page or action costs one ?state=draft read when the picker opens; getDraft asks the shared _drafts ledger read first, so no extra ledger request is sent.

Human Minimum

  • 1. Schemas start as Zod; packages/spec holds no runtime logic.
  • 2. Every name I added uses the casing for its kind.
  • 3. No formatter ran; pnpm lint passes (CI).
  • 4. One issue, one branch off an up-to-date main, one pull request.
  • 5. A change that publishes carries a changeset (nothing publishes here), and both declaration lines are filled in.
  • 6. packages/spec not touched.
  • 7. No hand edits to content/docs/references/, packages/*/CHANGELOG.md or content/docs/releases/.
  • 8. Title, body and comments are in English.
  • The Before Submitting list in CONTRIBUTING.md is done.

🤖 Generated with Claude Code


Generated by Claude Code

…ft body

A `_drafts` header names the metadata type, never the page body's own
`type`, so the Interfaces nav page picker offered a draft record page and
picking it gave a dead entry once the app was published. A draft-only row
of a type whose verdict reads the body (page, action) is now judged on its
draft body, as a published row is; an unreadable body keeps the row.

Claude-Session: https://claude.ai/code/session_01JQwxbYChiSg5184uQo2r5x
Co-authored-by: Claude <noreply@anthropic.com>
@objectstack-fleet objectstack-fleet Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Oct 27, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

席位核对

ACCEPT · seat domain:ui#5 · session_01JQwxbXGpVJHZTXXerMoY4C · head ca23ec41 · 2026-10-27T23:49Z

席位意见:导航项「页面」选择器对仅草稿的页面读取草稿正文再判定,草稿记录页不再列出;读不到正文时保留,与无 type 的已发布行同一规则。顺手修了同一循环里绑定对象的草稿动作,范围内、同类缺陷。

  1. Shape: Fixes #26743; 2 files, +241/−4: StudioDesignSurface.tsx +42/−4 (isNavTargetRow docblock, new NAV_TARGET_BODY_KEYED and isDraftNavTarget, the draft loop in usePackageNavTargets), one new test file (199 lines). All inside the claimed region (≈L2987–3060); StudioNavItemInspector untouched. skip-changeset: @object-ui/app-shell is private: true and no published package changes.
  2. Premise measured: the seat read the source diff on the head. Draft-only rows are collected, each body-keyed type (page, action) is read once through client.getDraft + extractDraftBody, and the published-row verdict isNavTargetRow is reused; a failed or empty read keeps the row; dashboard / report / doc read nothing. No spec or server change, as the order required. Dev: 6/6 new tests incl. the unreadable-body control; ablation of the verdict filter turned 2 red, restored.
  3. Gates / check-runs: PR check-runs on ca23ec41: 43 success, 14 skipped, 0 failure; Lint & Repo Gates and TypeScript Type Check success, Type Check UI and Lint UI success. The skips are path-filtered Core / docs / dogfood jobs and Check Changeset (label). Dev's local run: 24 derived, 24 run, --ran reconciled; app-shell type-check exit 0; 429 studio-design + inspector files green.
  4. Accepted deviations: the in-place fix for draft object-bound actions (same loop, same defect class, mechanical, named in the PR body with its own test). One extra draft read per draft-only page/action row when the picker opens.
  5. Out of scope: none. Skills-docs: none — Studio picker only.
  6. Landing: not Tier H (no governed path, +245 lines); ready for landing (ready + auto-merge).

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 27, 2026 23:52
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge October 27, 2026 23:52
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 27, 2026
Merged via the queue into main with commit 31a608e Oct 28, 2026
58 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/project-thread-cfwyv7 branch October 28, 2026 00:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/m skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Studio Interfaces: the page picker for a navigation entry lists draft record pages, producing a nav entry that is broken once published

2 participants