Repository navigation
fix(app-shell): the datasource delete confirm and its refusal name the objects that still use it, in the console's language - #30442
Conversation
…jects that still use it Claude-Session: https://claude.ai/code/session_01L6bhgW7fTeU6tAZXwiAJnW Co-authored-by: Claude <noreply@anthropic.com>
…urce delete; changeset Claude-Session: https://claude.ai/code/session_01L6bhgW7fTeU6tAZXwiAJnW Co-authored-by: Claude <noreply@anthropic.com>
…next commit) Claude-Session: https://claude.ai/code/session_01L6bhgW7fTeU6tAZXwiAJnW Co-authored-by: Claude <noreply@anthropic.com>
…ious commit) Claude-Session: https://claude.ai/code/session_01L6bhgW7fTeU6tAZXwiAJnW Co-authored-by: Claude <noreply@anthropic.com>
|
domain:ui#5 · os-sales · session_01L6bhgVwQZbHRRM9CaXeKif Contract reviewServed-tier: Reviewed 2026-11-05T11:41Z. Face: the ① Derived judgments
② Semver level
③ Boundary flags
Implemented-by: VERDICT: PASS |
…kes a spec-owned name Claude-Session: https://claude.ai/code/session_01L6bhgW7fTeU6tAZXwiAJnW Co-authored-by: Claude <noreply@anthropic.com>
|
domain:ui#5 · os-sales · session_01L6bhgVwQZbHRRM9CaXeKif Contract reviewServed-tier: Reviewed 2026-11-05T11:43Z. Delta review by the same reviewer of record 6657087845 (head ① Derived judgments
② Semver level
③ Boundary flags
Implemented-by: VERDICT: PASS |
|
domain:ui#5 · os-sales · session_01L6bhgVwQZbHRRM9CaXeKif 维护者速读
席位核对 — ACCEPT · domain:ui#5 · head
|
domain:ui#5 · os-sales · session_01L6bhgW7fTeU6tAZXwiAJnW
Requested by Sales · project thread
Refs #30335
Clause-②: yes (widening)
Metadata-protocol: none
维护者速读
ui/packages/app-shell/src/views/metadata-admin/datasource/DatasourceResourcePage.tsx(openDeleteConfirm、remove的 400 分支)、DatasourceResourcePage.deleteConfirm-13333.test.tsx第二个 describe、ui/packages/i18n/src/namespaces/studio/zh.ts的engine.datasource.deleteBound*。pnpm --dir ui exec vitest run packages/app-shell/src/views/metadata-admin/datasource/DatasourceResourcePage.deleteConfirm-13333.test.tsx,预期 8 个用例全绿。What changes
Card #30335, the datasource half only. The storage half (
SettingsView.tsx, console locales) stays on the card, serial behind #30329, so this PR does not close it.MetadataClient.list('object')) and keeps each object whosedatasourcenames the row, the same test the server's delete guard counts by. While any is listed, the dialog body says the datasource cannot be deleted yet and asks to delete each object or move it to another datasource first, and the objects are listed by label with the name beside it. With none, or when the read fails, the dialog is unchanged. The delete button stays enabled: the server is still the judge.api()now keeps the HTTP status and the envelope'serror.codeon the thrown error. A400fromDELETE /api/v1/datasources/:namere-reads the bound objects; when any remain, the toast isengine.datasource.deleteBoundRefused, naming the datasource, the objects (joined with the locale's separator row) and the next step. Every other failure, and a400with no bound object, keeps the server's message in the existingengine.datasource.deleteFailedframe. No server text is matched.studionamespace rows, en and zh:engine.datasource.deleteBoundBody,engine.datasource.deleteBoundRefused,engine.datasource.boundObjectSeparator(a punctuation row, since the package'slibis ES2020 and has noIntl.ListFormat)..changeset/30335-datasource-delete-names-bound-objects.md,@object-ui/app-shelland@object-ui/i18npatch.Branch: the harness-assigned
claude/project-thread-x1xjpw, notclaude/issue-30335-*; the card is #30335.Tests
DatasourceResourcePage.deleteConfirm-13333.test.tsxgains a second top-level describe (5 cases) on the existing harness; expectations are read from Studio's table, never retyped:parts_db(label with name, name alone when unlabelled) and not the one ondefault, with the bound body instead of the plain one;400refusal is reported in zh, naming the objects, and the server's English never reaches the toast;400keeps the server's message;503keeps the server's message even while objects are bound.The three existing cases run unchanged (their fake metadata client has no
list, which exercises the failed-read path).Acceptance notes
testhandler's${name}: ${message}) is untouched: it does not fall out of this change.packages/**is the server lane): the refusal is a plainErroranswered400 DATASOURCE_ADMIN_ERRORwith a count and no object names ordetails, so a client that does not read object metadata cannot name them. Reported to the seat to file.Verification
Gates and tests ran on
de1864eb; the head adds an evidence commit and its removal, the tree is byte-identical (git diff de1864eb HEADis empty). Basefdd06415.Live rig and screenshots (zh-CN, 1440 wide)
examples/app-showcaseobjectstack dev --seed-adminon a private port, the console viaviteinui/apps/consolewithDEV_PROXY_TARGET, Chromium, browser locale zh-CN. A runtime sqlite datasourceparts_db(label 零件库) with two objects saved throughPUT /api/v1/meta/object/:namenaming it (零件parts_part, 供应商parts_supplier).DELETE /api/v1/datasources/parts_dbansweredHTTP 400with{"success":false,"error":{"code":"DATASOURCE_ADMIN_ERROR","message":"Cannot remove datasource 'parts_db': 2 object(s) are still bound to it."}}, andGET /api/v1/meta/objectserved both objects withdatasource: parts_db.Before (page restored to the base for the shot): confirm
连接 parts_db 将被移除。此操作不可撤销。; toast删除 parts_db 失败:Cannot remove datasource 'parts_db': 2 object(s) are still bound to it.After: confirm
以下对象仍在使用 parts_db,暂时无法删除。请先删除这些对象,或把它们改到其他数据源:with零件 (parts_part),供应商 (parts_supplier); toast未删除 parts_db:零件 (parts_part)、供应商 (parts_supplier) 仍在使用它。请先删除这些对象或把它们改到其他数据源,再删除 parts_db。Tests, ablation, typecheck, lint
pnpm --dir ui exec vitest run packages/app-shell/src/views/metadata-admin/datasource/ packages/i18n/src/__tests__/studio-namespace.test.ts: Test Files 8 passed (8), Tests 61 passed (61), lock VERDICT command-exit 0.scripts/ablation-replace.mjs, anchor x1 to x0): the refusal's re-read replaced by an empty list: 1 failed / 7 passed (the zh refusal case). Restored, blob equals HEAD.confirmBoundforced empty: 3 failed / 5 passed (the confirm list case and the two cases that wait on it). Restored, blob equals HEAD.pnpm --filter @object-ui/i18n --filter @object-ui/app-shell type-check(bothtsc --noEmitandtsc -p tsconfig.test.json): lock VERDICT command-exit 0.pnpm check:new-line-citations(ui): 0 new citations, exit 0.Derived gates (35/35 exit 0)
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackderived 35 families atde1864eb; every one ran and exited 0.--ranreconciliation: 35 derived, 35 run, 0 NOT-MEASURED (a derived zero, every line carries an exit code).pnpm --dir ui exec vitest run scripts/: 170 files passed, 2 skipped; 4985 tests passed, 2 skipped. CI runs the rest.Generated by Claude Code
🤖 Generated with Claude Code
https://claude.ai/code/session_01L6bhgW7fTeU6tAZXwiAJnW