Repository navigation
feat(app-shell): each read-only base card on the Studio landing says how many items are customized and switched off - #28634
Merged
Conversation
…tomized, m switched off" Each read-only base's card reads GET /packages/:id/customizations once and draws the served counts: customized = overrides + extensions, switched off as served. A pair draws no line and is never sent; loading shows no number; a failed read says so, with the server's sentence as its title. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QsR2jRL4qcnwHDD4M1e4wx
… served answers Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QsR2jRL4qcnwHDD4M1e4wx
…tests; add the changeset The landing now reads each read-only base's customizations. Four landing tests that are not about it would send that read to a real socket, so they stub the reader with a pending promise. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QsR2jRL4qcnwHDD4M1e4wx
Contributor
Author
|
domain:ui#4 · zhuangjianguo · session_01QsR2jR7ZFkpqmm4U8S1f9y Contract reviewServed-tier: ① Derived judgments
② Semver level
③ Boundary flags
Implemented-by: VERDICT: PASS Generated by Claude Code |
Contributor
Author
|
domain:ui#4 · zhuangjianguo · session_01QsR2jR7ZFkpqmm4U8S1f9y 席位核对 · ACCEPT · 2026-11-01T11:09ZHead-sha:
Generated by Claude Code |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Requested by Steedos · project thread
Fixes #28566
Clause-②: yes (widening)
Metadata-protocol: none
维护者速读
GET /api/v1/packages/:id/customizations,每张卡读一次;n = 服务器给的覆盖数 + 扩展数,m = 服务器给的停用数。有定制包(BASE.custom)时「已定制」链到它的 Studio,「已停用」链到基础包的自动化页。ui/packages/app-shell/src/views/studio-design/packageCustomizations-io.ts(读取与按 spec 校验)、BuilderLanding.tsx的renderCustomizationLine、BuilderLanding.customizationCounts-28566.test.tsx。pnpm --dir ui exec vitest run packages/app-shell/src/views/studio-design/BuilderLanding.customizationCounts-28566.test.tsx,预期 1 个文件、6 个测试全绿。What changes
packages-io.packageCustomizations-io.tsexportsfetchPackageCustomizationCounts(baseId). It sendsGET /api/v1/packages/:id/customizationsand judges the dispatcher envelope'sdatabyGetPackageCustomizationsResponseSchemafrom@objectstack/spec/api. It returnscustomized= servedcounts.overrides+ servedcounts.extensions, andswitchedOff= servedcounts.switchedOff. It counts nothing itself. A failed read rejects with the server's sentence throughreadEnvelopeFailureText, the rule every package reader in that folder uses, elseHTTP STATUS. An answer the schema refuses rejects too, so no number is ever read out of an off-contract body. A pair id (isCustomizationPackage) is refused before any request, because the route refuses it by shape.BuilderLandingreads once per read-only base card drawn, after the package list answers. The effect is keyed on the joined target ids, a primitive (ui/AGENTS.md chore: version packages #10). The page does not wait for these reads. The line has three states:title;When the package list holds
BASE.custom(fromcustomizationPackageId), "n customized" links to/studio/BASE.custom/data. Otherwise it is plain text. "m switched off" links to/studio/BASE/automations, the pillar where the switch lives.engine.studio.landing.customizations.*keys go into@object-ui/i18n's studio namespace, inenandzh. The zh line reads 「已定制 n 项,已停用 m 项」, as the card asks. The other languages fall back toen, as the whole namespace does by design. Placeholders arecustomized,switchedOffandpair, single-bracetFormattokens. There is nocounttoken, so the i18next count-family gate does not apply.Tests
BuilderLanding.customizationCounts-28566.test.tsxruns the real landing and the real reader under a real router. Only the package list andfetchare stubbed, with answers shaped by the route's schema inside the dispatcher envelope. The six cases are the card's five plus one:/studio/hotcrm.custom/dataand the switched-off link to/studio/hotcrm/automations. One request is sent, for the base only.counts) shows the failed state with no digit. This is the extra case.Four existing landing tests (
accessibleNames-12510,orgScope-11553,recentPackages-11863,setupExit-12513) draw a read-only card. The new read reached a real socket from them, and the ui network-escape guard refused it. They now mock the reader with a pending promise, the way they already mockpackages-io. No assertion changed.Acceptance notes
mainyet. The seat reports thatGET /api/v1/packages/:id/customizationsis in the route ledger but answers nothing at runtime. This PR builds against the declared schema with stubbed answers, as the card's Tests ask. Until main red: Dogfood Regression Gate — GET /packages/:id/customizations is ledgered but not mounted (#28595), so the route 404s at runtime #28622 lands, a live landing shows the failed state ("Couldn’t read customizations"), never a number. The seat holds landing until then. No server code is touched here.fetchthe way its neighbours inpackages-io.tsdo, so the landing uses one transport with one failure-text rule.@objectstack/client'spackages.customizations(id)exists. Moving every package reader in this folder onto the client would be a change of its own.Verification
New test file · 6/6
pnpm --dir ui exec vitest run --maxWorkers=2 packages/app-shell/src/views/studio-design/BuilderLanding.customizationCounts-28566.test.tsxunderos-verify-lock: Test Files 1 passed (1), Tests 6 passed (6).Ablations · two red, one green explained
All three ran through
scripts/ablation-replace.mjsagainst the committed fix. The tree was restored after each run, andgit diff HEADwas empty.customized: counts.overrides(the extensions term dropped): 1 failed, the "4 customized, 2 switched off" case.Every test naming the landing or the reader · 22 files
git grep -l "BuilderLanding\|packageCustomizations-io"over ui test files (22 files): Test Files 22 passed (22), Tests 120 passed (120). Before the four stubs: 4 failed, all with the network-escape refusal. The tests that reach the landing through routes (registerStudioComponents.builderLazy-11798,StudioRoute.landingI18n,AppContent.studioRootLanding-12113,UnifiedSidebar.studioNoHome-12113): 4/4 files, 16/16 tests. This is a declared narrowing. CI's Test UI runs the rest of app-shell.Type check and i18n
pnpm --filter @object-ui/app-shell run type-check: exit 0, afterturbo run build --filter='@object-ui/app-shell^...'(64 tasks).pnpm --dir ui exec vitest run packages/i18n/: Test Files 94 passed (94), Tests 1438 passed, 13 skipped. This includes the studio namespace parity test.Derived gates · 34 of 34 exit 0 at 7b29406
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackderived 34 commands against merge base0e78922ee. All 34 ran and exited 0. That count includescheck-sdui-manifest.mjsand its--self-test,check:type-check-debtunder the lock,check:nul-bytes,check:cross-package-test-inputs,check:test-source-aliasandpnpm --dir ui exec vitest run scripts/(Test Files 169 passed, 2 skipped; Tests 4900 passed).dispatch-gates --ranreconciled 34 derived, 34 run, 0 NOT-MEASURED, 0 UNRUN.pnpm --dir ui run check:new-line-citationsfound 0 new citations. The head then took one merge ofmain(d77dc07a, twoui/e2e/livefiles, no overlap with this diff).Generated by Claude Code