Skip to content

fix(console): an uninstalled cloud package is not drawn as installed - #28620

Merged
objectstack-fleet[bot] merged 3 commits into
mainfrom
claude/project-thread-xx8o3g
Nov 1, 2026
Merged

objectstack-fleet[bot] merged 3 commits into
mainfrom
claude/project-thread-xx8o3g

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Steedos · project thread

Fixes #28521

Clause-②: no
Metadata-protocol: none

维护者速读

  • 改了什么:云托管环境里卸载过的软件包(控制面软停用、保留安装记录),控制台不再显示为"已安装"。市场页"你的组织"卡片改为显示"重新安装"按钮;设置 → 软件包页不再把它列为已安装。
  • 为什么改:客户卸载应用后,卡片仍写"已安装"且没有任何按钮,客户既看不出它已停用,也装不回来。
  • 风险与回滚:只改控制台读法,不改云端、不改协议。回滚即还原本 PR 的两个源文件。
  • 先看:ui/packages/app-shell/src/console/marketplace/marketplaceApi.ts(listInstalledPackages 的停用判定与 readMarketplaceInstalls 的过滤)、MarketplacePage.tsx(卡片按钮分支)。
  • 两分钟验证:cd ui && pnpm exec vitest run packages/app-shell/src/console/marketplace/__tests__/MarketplacePage.disabledInstall-28521.test.tsx,预期 6 个用例全绿。
  • 需要你做的:无,席位落地。

What changes

The control plane's uninstall is a soft disable that keeps the installation row; GET /api/v1/cloud-connection/installed still lists that row with status: 'disabled' and enabled: false (measured by the cloud seat on the card). The Console read every listed row as installed.

  • marketplaceApi.ts listInstalledPackages() reads status and enabled and marks a disabled row with a new optional LocalInstallEntry.disabled: true member. It is absent on an installed row and never sent by the install-local listing, the same convention as notLoaded.
  • MarketplacePage.tsx: a disabled cloud row no longer joins installedIds. The org card draws Reinstall (the existing marketplace.action.reinstall key) instead of the Installed badge. The button calls the same doOrgInstall, so on a cloud-managed environment it posts to POST /api/v1/cloud-connection/install, which answers reinstalled and re-enables the row; the page then re-reads the listing and draws Installed.
  • readMarketplaceInstalls() (the Setup → Packages read) drops disabled rows on the cloud leg, so the page neither lists a soft-uninstalled package as an install nor offers its Details/Uninstall actions.

The public catalog grid and the package detail page needed no change: the grid reads the install-local ledger only, and the detail page reads GET /cloud-connection/installation, which already answers installed: false for a disabled row.

Tests

  • New MarketplacePage.disabledInstall-28521.test.tsx (6 cases) runs the real listInstalledPackages, readMarketplaceInstalls and installPackage against a stubbed fetch:
    • the client marks only the disabled row, and the marker is absent on an installed one;
    • status: 'disabled' alone and enabled: false alone each mark the row;
    • Setup → Packages' read keeps only the installed row;
    • the org card offers Reinstall, its click posts { package_id, seed_sample_data } to the install door, and the re-enabled row then reads Installed with no button;
    • CONTROL: an installed row reads Installed; a package with no row offers Install.
  • Ablations (each through scripts/ablation-replace.mjs, restored to the HEAD blob with git diff HEAD empty):
    • MarketplacePage counting every cloud row installed: the Reinstall case goes red (1 failed / 5 passed);
    • readMarketplaceInstalls keeping disabled rows: the Setup → Packages case goes red (1 failed / 5 passed).

Acceptance notes

  • The card offered two shapes: the Install button, or 已停用 with 重新安装. This PR draws Reinstall alone. A separate 已停用 badge would need a new @object-ui/i18n key, which widens the published catalogue (Clause-② yes); the existing Reinstall key already says the package was installed and is off now.
  • Setup → Packages drops the disabled row rather than drawing it with a reinstall action. That page lists what is installed; reinstall stays a marketplace action.
  • Not measured against a live hosted stack from this container: the cloud repository is not readable here. The row shape in the test is the one the card measured.

Verification

Local runs
  • pnpm exec vitest run over the 71 ui test files naming MarketplacePage, marketplaceApi, readMarketplaceInstalls, listInstalledPackages or PackagesPage (a declared narrowing; CI's Test UI runs the rest): 71 files, 710 tests passed.
  • After merging origin/main (head 5f3027f6; the 2 incoming commits touch packages/cli and the metadata layer, not this diff): the new file plus every test under ui/packages/app-shell/src/views/metadata-admin/, 686 files, 7259 tests passed, 1 skipped.
  • pnpm --filter @object-ui/app-shell run type-check: exit 0.
  • Derived gates (dispatch-gates.mjs --commands, 34 families): all 34 exit 0, --ran reconciliation 34 run / 0 NOT-MEASURED. Each command is in the card's os-dev report.

Generated by Claude Code

The control plane's uninstall keeps the installation row and lists it with
status 'disabled' / enabled false. listInstalledPackages() now marks such a
row `disabled`; the marketplace's org card offers Reinstall for it (the
install door re-enables the row) instead of an Installed badge, and
readMarketplaceInstalls() leaves it out of Setup → Packages.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QsR2jVBzmHX5zVyRfxqBc3
@github-actions github-actions Bot added size/m documentation Improvements or additions to documentation tooling Fix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface labels Nov 1, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:ui#4 · zhuangjianguo · session_01QsR2jR7ZFkpqmm4U8S1f9y

席位核对 · ACCEPT · 2026-11-01T08:33Z

Head-sha: 5f3027f6381ac8eb2446866b8fde41fd8b299b5e

  • Shape: draft → main, first content line Fixes #28521, no other card number beside a closing keyword. 4 files, +241 / −3 (244 lines ≤ 3000), no governed path (check-governed-merges --pr 28620: 0 of 4 paths hit the register). Author objectstack-fleet[bot]. Clause-②: no / Metadata-protocol: none line-initial in body and changeset, as claimed. No contract-review face is touched: @object-ui/app-shell is private: true, no new @object-ui/i18n key (Reinstall reuses marketplace.action.reinstall), no packages/spec/src/**.
  • Premise, re-measured: at origin/main listInstalledPackages() mapped every GET /api/v1/cloud-connection/installed row to an install, so a soft-disabled row (status: 'disabled', enabled: false) drew Installed with no action. The diff marks such a row disabled (either field is enough), keeps it out of installedIds, draws Reinstall through the same doOrgInstall door, and drops it from readMarketplaceInstalls(). Console read only; no cloud or protocol change, so the cloud routing rule does not pull the card.
  • Gates (check-runs on this head): 44 success, 11 skipped, 0 failed or pending, all ten required contexts included (Build Core skipped by its path filter on a ui-only diff).
  • Accepted deviation: the card offered "已停用 + 重新安装" or the Install button; the PR draws Reinstall alone, so no new i18n key widens the published catalogue. Setup → Packages drops the row rather than offering reinstall there. Both are named in the PR body.
  • Changeset sentences checked against the diff: "listInstalledPackages() now marks such a row disabled (either field saying so is enough)"; "The org card draws Reinstall … calls the same install door"; "readMarketplaceInstalls() leaves disabled rows out". All hold.
  • Tests: 6 cases on the real client against a stubbed fetch (marker, each field alone, Setup read, Reinstall click posts to the install door then reads Installed, control rows); two ablations red only their own pins (dev report).
  • Out of scope / NOT MEASURED: a live hosted-stack retest; the cloud repository is not readable from the dev container. Skills-docs: not owed.
  • Landing: ordinary queue landing — pr_ready then automerge_enable. Fixes #28521 closes the card on merge.

Generated by Claude Code

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review November 1, 2026 09:35
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge November 1, 2026 09:35
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Nov 1, 2026
Merged via the queue into main with commit 0e78922 Nov 1, 2026
56 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/project-thread-xx8o3g branch November 1, 2026 09:50
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 Fix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface

Projects

None yet

Development

Successfully merging this pull request may close these issues.

console marketplace: a soft-uninstalled package (status disabled) still shows Installed with no reinstall; listInstalledPackages drops status/enabled

1 participant