Skip to content

fix(studio): after Restore package original the rail's customized mark and "only customizations" count refresh without a reload - #30381

Merged
objectstack-fleet[bot] merged 5 commits into
mainfrom
claude/project-thread-5khb19
Nov 5, 2026
Merged

objectstack-fleet[bot] merged 5 commits into
mainfrom
claude/project-thread-5khb19

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Bill · project thread
domain:ui#2 · os-bill · session_01Utp6Cb5R6JDdfyvtj3dPR2

Fixes #30238

Clause-②: no
Metadata-protocol: none

维护者速读

  • 改了什么:Studio 读取「本基础包有哪些定制」(GET /api/v1/packages/:id/customizations)的时机,从「只在发布后」改为「每次元数据刷新脉冲」;恢复原版本来就会发这个脉冲,所以恢复后侧栏的定制标记和「仅看定制(n)」立即更新,不用刷新页面。
  • 为什么改:管理员在 Studio 里对已安装应用的仪表盘、报表、视图、列表视图或页面按「恢复原版」后,内容回到出厂版,但侧栏还标着已定制、「仅看定制(1)」还在,看不出恢复是否生效,可能重复恢复或误以为定制仍在。
  • 风险与回滚:只改 StudioDesignSurface.tsx 中一处读取的触发键(含注释 +13/-3 行),外加一个新测试文件和 changeset;不动 spec、服务端或元数据。发布照样只读一次(发布本来就同时发脉冲);AI 助手发布后也会重读。回滚即 revert 本 PR。
  • 先看:ui/packages/app-shell/src/views/studio-design/StudioDesignSurface.tsx 约 836–849 行(customizationsRefresh 那一段)→ 新测试 StudioDesignSurface.restoreMarks-30238.test.tsx。
  • 两分钟验证:pnpm --dir ui exec vitest run packages/app-shell/src/views/studio-design/StudioDesignSurface.restoreMarks-30238.test.tsx,预期 2/2 通过(在 main 源码上两条都失败:恢复后定制读取没有再请求)。
  • 需要你做的:无,席位落地。

What changes

StudioDesignSurface reads the base's customizations once and hands them to every pillar as customization.marks: every pillar rail's marks and "only customizations" count come from that read. It was keyed on publishNonce, so it was read again only after a publish. "Restore package original" (restoreOriginal in the Interfaces pillar, the flow restore in Automations, and the bundle item editor's restore) deletes the pair's draft and row, then calls emitMetadataRefresh(), but never moves publishNonce. So the shipped item read back while the rail kept its mark and its count until a reload.

  • The read is now keyed on useMetadataRefreshNonce(), the assistant bus pulse that the restores already emit. Both publish paths (setPublishNonce at the two publish sites) emit the same pulse in the same handler, so a publish still reads once. Keying on both would read twice per publish. A copilot publish from the right dock, which the old key missed, now refreshes the marks too.
  • No restore path changes, and no new fetch path. The hook (usePackageCustomizations) is unchanged.

The card's mechanism held as written: restoreOriginal moves servedNonce, the leaf or list-view or nav reload nonces, and emits the pulse, but no key the customization read listened to. I confirmed it on a second type: a dashboard opened from the navigation, besides the page the card measured.

Tests

  • New ui/packages/app-shell/src/views/studio-design/StudioDesignSurface.restoreMarks-30238.test.tsx: the REAL StudioDesignSurface and metadata client over a fetch stub that serves a read-only base with its pair listed, the pair's rows served over the base's items, the customization read (one override per pair row) and the reset door (DELETE, which deletes the pair's row).
    • A dashboard opened from the navigation: before the restore the rail marks it customized and "only customizations" reads 1. After the restore the read is asked again, the mark is gone, and so is the filter.
    • A page listed under its type, with a second customized dashboard as the CONTROL: after the page's restore the read is asked again, the page's mark is gone, the count reads 1, and the dashboard keeps its mark.
  • Red first, on the commit before the fix (test only, 3e7cd7f5): Tests 2 failed (2), both expected 1 to be greater than 1 (the customization read count did not move after the restore). Green after the fix: Tests 2 passed (2). The red-first run on the parent commit is the ablation leg: the fix is the only source change.
  • Every app-shell test file that renders the whole StudioDesignSurface (60 files): Test Files 60 passed (60), Tests 372 passed (372). The other test files that import the module render single pillars with a host-built customization, which this change does not touch.
  • pnpm exec turbo run type-check --filter=@object-ui/app-shell --concurrency=2: Tasks: 68 successful, 68 total.
  • eslint on the two changed ui files: 0 errors. StudioDesignSurface.tsx has 36 warnings, the same count as on main. The new test file has none.

Acceptance notes

  • The card's Expected also names the All metadata tile count. The All metadata area's pages (DirectoryPage, ResourceListPage) make their own customization read when each one mounts. The area mounts on its tab, and its list and item pages are separate routes, so after a restore made anywhere else they open on a fresh read. This PR does not change them.
  • The card lists the app's navigation with the types that share the path. The navigation's rail mark reads the served override (useServedOverride, keyed on servedNonce, which restoreOriginal moves), not the customization read, so it already cleared after a restore. The count's navigation term is that same mark. The stale part was the off-navigation items (page, dashboard, report, view) and the nav entries' marks, which this PR fixes.

Verification

Derived gates (dispatch-gates --commands, final tree `bde46d2b`)
  • node scripts/check-adr-0087-registration.mjs --base origin/main :: exit 0
  • node scripts/check-adr-0087-registration.mjs --self-test :: exit 0
  • node scripts/check-changeset-no-major.mjs --base origin/main :: exit 0
  • node scripts/check-closing-keyword-parity.mjs :: exit 0
  • node scripts/check-closing-keyword-parity.mjs --self-test :: exit 0
  • node scripts/check-comment-mask-corpus.mjs :: exit 0
  • node scripts/check-empty-changeset.mjs --base origin/main :: exit 0
  • node scripts/check-empty-changeset.mjs --self-test :: exit 0
  • node scripts/check-sdui-manifest.mjs :: exit 0
  • node scripts/check-sdui-manifest.mjs --self-test :: exit 0
  • node scripts/pm/release-rehearsal-clone.mjs --self-test :: exit 0
  • node scripts/release-pending-publish.mjs --self-test :: exit 0
  • pnpm --dir ui exec vitest run scripts/ :: exit 0
  • pnpm --filter @objectstack/spec run check:duration-unit-keys :: exit 0
  • pnpm check:changeset-gate-self-tests :: exit 0
  • pnpm check:closed-ceremony-text :: exit 0
  • pnpm check:cross-package-test-inputs :: exit 0
  • pnpm check:dispatcher-error-vocabulary :: exit 0
  • pnpm check:driver-memory-census :: exit 0
  • pnpm check:engine-double-contract :: exit 0
  • pnpm check:gitlink-declared :: exit 0
  • pnpm check:nul-bytes :: exit 0
  • pnpm check:published-files :: exit 0
  • pnpm check:query-options-erasure :: exit 0
  • pnpm check:refd-timer-probe :: exit 0
  • pnpm check:registry-log-declared :: exit 0
  • pnpm check:rest-log-spy-declared :: exit 0
  • pnpm check:skill-identifier-liveness :: exit 0
  • pnpm check:test-source-alias :: exit 0
  • pnpm check:tier-file-adoption :: exit 0
  • pnpm check:type-check-coverage :: exit 0
  • pnpm check:type-check-debt :: exit 0
  • pnpm check:undeclared-dep-imports :: exit 0
  • pnpm check:watch-hint-literal :: exit 0
  • pnpm check:where-matcher :: exit 0

node scripts/pm/dispatch-gates.mjs --ran: 35 derived, 35 run, 0 NOT-MEASURED, 0 UNRUN. check:type-check-debt ran under the verify lock (VERDICT command-exit 0). check:sdui-manifest (standing ui gate) is in the list.


Generated by Claude Code

@github-actions github-actions Bot added size/m documentation Improvements or additions to documentation tooling labels Nov 5, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:ui#2 · os-bill · session_01Utp6Cb5R6JDdfyvtj3dPR2

Waits-on: main-red #30367

Lint UI on bde46d2b fails in @objectstack/spec check:liveness (the query/searchFields row cites engine.ts, which no longer names the key after #30341). This PR touches only ui/packages/app-shell/src/views/studio-design and a changeset, so the red is main's, not this diff's: the p0 anchor is #30367 and its fix is PR #30368. Once #30368 merges, this branch merges origin/main and CI re-runs; the seat ACCEPTs on that head.

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:ui#2 · os-bill · session_01Utp6Cb5R6JDdfyvtj3dPR2

维护者速读

  • 改了什么: 在 Studio 里对已安装应用的某一项按「恢复原版」后,侧栏的定制标记和「仅看定制(n)」立刻更新,不用再刷新页面。做法是把定制读取的触发键从 publishNonce 换成元数据刷新脉冲:恢复和发布都会发这个脉冲。
  • 为什么改: 原来恢复后侧栏仍标着已定制,管理员看不出恢复有没有生效(Studio: after 恢复原版 the rail keeps the customized mark and 仅看定制 (1) until a reload #30238)。
  • 风险与回滚: 只改 StudioDesignSurface.tsx 里一处读取的依赖键,另加一个测试和一份 changeset。spec、服务端、元数据都不动。发布仍然只读一次。回滚就是撤销本 PR。
  • 先看: StudioDesignSurface.tsx 约 836–849 行的 customizationsRefresh。
  • 两分钟验证: pnpm --dir ui exec vitest run packages/app-shell/src/views/studio-design/StudioDesignSurface.restoreMarks-30238.test.tsx,应 2/2 通过。
  • 需要您做的: 无。本 PR 不在受管面,共 282 行,由席位经合并队列落地。
  • 席位意见: ACCEPT。

席位核对 — ACCEPT · domain:ui#2 · head 23d61c95e6a23fa7b65b592eb6038528752db46a

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review November 5, 2026 11:30
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Nov 5, 2026
Merged via the queue into main with commit 644883e Nov 5, 2026
56 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/project-thread-5khb19 branch November 5, 2026 11:43
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 size/m tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Studio: after 恢复原版 the rail keeps the customized mark and 仅看定制 (1) until a reload

1 participant