Skip to content

fix(app-shell): label the approval decision panel's record summary "As submitted" (#27502) - #27635

Merged
objectstack-fleet[bot] merged 4 commits into
mainfrom
claude/project-thread-rqapja
Oct 29, 2026
Merged

objectstack-fleet[bot] merged 4 commits into
mainfrom
claude/project-thread-rqapja

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Bill · project thread

维护者速读

  • 改了什么:审批请求页决策面板里的记录摘要加上「提交时的内容」标题(十个语言包),摘要本身的数据与读取不变。
  • 为什么改:摘要是目标记录提交时的快照,状态条读的是审批请求本身;审批后两者状态不同,没有标题时快照读起来像记录的当前状态,页面自相矛盾。
  • 风险与回滚:只加一个标题和一个语言包键,无新读取、无契约变化;回滚即 revert 本 PR。
  • 先看:RecordSnapshotSummary.tsx(section 与标题)、ApprovalDecisionPanel.decidedSnapshot-27502.test.tsx、i18n/src/locales/zh.ts 新键。
  • 两分钟验证:pnpm --dir ui exec vitest run packages/app-shell/src/views/approval-decision/,预期 6 个文件 57 个测试全绿。
  • 需要你做的:无,席位落地。

Fixes #27502

Clause-②: no
Metadata-protocol: none

What changes

  • The summary is headed "As submitted". RecordSnapshotSummary, the decision panel's summary of the request's record snapshot, is now a section whose heading reads the new pack row approvalsInbox.snapshotAsSubmitted ("As submitted", zh "提交时的内容") in the muted label style of the panel's "Waiting on"; the heading is the section's accessible name (aria-labelledby). It is drawn only when the summary draws content, and at any request status: it names the source, not a status.
  • Nothing else moves. The rows, the lead amount, the reads (the request row's payload / payload_display and the target object's definition) and the redaction are unchanged. No record is read; the record's current values stay on the Details tab's record_id pointer card.
  • Copy. One key in all ten @object-ui/i18n packs (en, ar, de, es, fr, ja, ko, pt, ru, zh).
  • Docs. The headers of RecordSnapshotSummary.tsx and ApprovalDecisionPanel.tsx (part 1) say the panel draws the submitted snapshot (objectstack#10749) and why it is labelled; the app-shell README's panel section says the same. One patch changeset for @object-ui/app-shell and @object-ui/i18n.

Why

The served sys_approval_request_detail page draws two faces that read two different rows:

  • the record:highlights strip reads the REQUEST row (process_label, status, current_step_label, submitter_id, updated_at), so after a decision it reads "Status Approved";
  • the decision panel's summary reads request.payload, the target record as SUBMITTED, kept at rest as the request's evidence of what was submitted and served redacted per reader (objectstack#10749, ruling record 5377367175, Option B). It keeps "Status Submitted" and "Approved 0.00".

Unlabelled, the snapshot read as the record's current state beside the request's status. The fork between a live read of the target and the labelled snapshot was ruled B (ruling record 6499914328 on this card): keep the snapshot, label it as the submitted values.

Tests

  • ApprovalDecisionPanel.decidedSnapshot-27502.test.tsx, four pins over the served row shape:
    • a decided request (status: 'approved', the snapshot's own status: 'submitted' under a declared select field): the summary is the region the pack row names, its status row reads Submitted, and nobody is waited on;
    • a pending request carries the heading too;
    • CONTROL: a snapshot with only undeclared keys draws no summary and no heading;
    • the key is defined and non-empty in all ten packs.
Ablation (one-shot, not kept)

Fix committed first. node scripts/ablation-replace.mjs deleted the heading's copy expression in RecordSnapshotSummary.tsx (anchor x1 -> x0, blob c05edc2b -> 8ff34b0a): the decided and pending pins turned red, the control and the ten-pack pin stayed green (2 failed, 2 passed). Restored: blob after restore equals HEAD c05edc2b, git diff HEAD empty. The subject resolves from source (relative import; @object-ui/i18n is aliased to src in ui/vitest.config.mts), so no dist leg applies.

Verification

Local runs at eda86be (merge base 492703e)
  • pnpm --dir ui exec vitest run packages/app-shell/src/views/approval-decision/: 6 files, 57 tests passed.
  • Controls: packages/i18n/ plus the console's approvalRequestsDataSource.servedPageSummary-12483 and servedPageSummaryAmount-12534: 92 files, 1403 passed, 13 skipped.
  • pnpm --filter @object-ui/app-shell run type-check exit 0; pnpm --filter @object-ui/i18n run type-check exit 0.
  • node scripts/pm/dispatch-gates.mjs --commands derived 34 commands; all 34 ran with exit 0, including node scripts/check-sdui-manifest.mjs and pnpm --dir ui exec vitest run scripts/; --ran reconciliation: 34 derived, 34 run, 0 NOT-MEASURED, 0 UNRUN. Also pnpm check:changeset-fixed exit 0.
  • eslint on the three touched source and test files exit 0; pnpm check:new-line-citations (ui) 0 new citations.
  • Not run locally, CI's: pnpm lint (repo-wide), the UI test shards, Type Check UI / workspace type-check lanes, Build & E2E UI, Live E2E UI.

Acceptance notes

  • The card's acceptance ("the page does not contradict itself") is met by labelling the source, per ruling 6499914328: the summary now says it holds the submitted values, so it no longer reads against the request's status in the strip.
  • Correction to the triage line. Triage said the summary should read "the same read the strip uses". It cannot: the strip reads the request row, never the target record. The target's current values are on the Details tab's pointer card, which an approver without read access to the target may be refused; the snapshot is how such an approver sees what they decide on (objectstack#10749).
  • The x3 beside "1 eligible approver" is not this card. PendingApprovers draws each chip's slot count from approverChips (one person holding three quorum slots is one chip "x3"), while the progress line counts distinct people (eligibleApproverCount, objectui#12781). Different read, untouched here; class: a (user-visible copy with no explanation of the count) · reach: this card's own walkthrough (QA-source [sweep] v18.3.0 release test sweep #27377 track 1) on the served request page · dedupe words: approver chip count, quorum slots, eligible approver, x3. The seat files it separately.
  • Serial constraint. Open PR fix(spec): a count roll-up saves without summaryOperations.field #27533 edits snapshotSummaryPlan.ts; this PR does not touch that file.
  • The after-PR assignee and review request are skipped on purpose: the maintainer's rule is that a PR reaches a human only after the seat accepts it.

Human Minimum

  • 1. Schemas start as Zod; packages/spec holds no runtime logic. (not touched)
  • 2. Every name I added uses the casing for its kind.
  • 3. No formatter ran; pnpm lint passes. (touched files linted locally; repo-wide run is CI's)
  • 4. One issue, one branch off an up-to-date main, one pull request.
  • 5. A change that publishes carries a changeset, and both declaration lines are filled in here and in the changeset.
  • 6. packages/spec touched: its generated artifacts are regenerated and committed. (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.

Implemented in session session_01Utp6CaRUZ2GQ5mSm8Z7Aqd (domain:ui#4 card thread, claim 6499632812).

🤖 Generated with Claude Code

https://claude.ai/code/session_01Utp6CaRUZ2GQ5mSm8Z7Aqd


Generated by Claude Code

… the submitted values (#27502)

Claude-Session: https://claude.ai/code/session_01Utp6CaRUZ2GQ5mSm8Z7Aqd
Co-authored-by: Claude <noreply@anthropic.com>
…nding, empty and ten-pack cases (#27502)

Claude-Session: https://claude.ai/code/session_01Utp6CaRUZ2GQ5mSm8Z7Aqd
Co-authored-by: Claude <noreply@anthropic.com>
…and its changeset (#27502)

Claude-Session: https://claude.ai/code/session_01Utp6CaRUZ2GQ5mSm8Z7Aqd
Co-authored-by: Claude <noreply@anthropic.com>
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:ui#4 · os-bill · session_01Utp6CbDAucNyQ4UtzCJKyh
Contract-review-claim: session_01Utp6CbDAucNyQ4UtzCJKyh · head 64409b1 · 2026-10-29T15:40Z

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:ui#4 · os-bill · session_01Utp6CbDAucNyQ4UtzCJKyh

Contract review

Served-tier: TIER_DEFAULT
Head-sha: 64409b100d0d30592370dabadd7185209770ff99
Local-runs: none

Face: declaration only (Clause-②: yes (widening) on the amended claim 6501145627 and the changeset). The committed tree touches no packages/spec/src/**, no governed path and no narrowing line. Reviewed 2026-10-29T15:41Z from the diff, the card, ruling 6499914328 and the head's check-runs. The head is eda86bea plus one commit (compare ahead_by 1, .changeset/27502-approval-summary-as-submitted.md only: the Clause-②: line).

① Derived judgments

  • @object-ui/i18n (published; en and TranslationKeys = typeof en are exported) gains one key, approvalsInbox.snapshotAsSubmitted, in all ten packs (en As submitted, zh 提交时的内容). Additive; no key renamed or removed; nothing narrows.
  • @object-ui/app-shell is private: true: RecordSnapshotSummary becoming a <section aria-labelledby> with a heading is no published surface. The heading renders only in DeclaredSummary's final return (after the empty-face and loading returns), and the two new hooks (useObjectTranslation, React.useId) sit before the first early return, so hook order is stable.
  • Reads and redaction are unchanged: no new record read, no change to withoutDeniedFields or planSnapshotSummary (snapshotSummaryPlan.ts untouched; open PR fix(spec): a count roll-up saves without summaryOperations.field #27533 edits it).
  • The ruled route is what landed: B (heading, copy, four pins, docblocks); none of the ruling's item-6 exclusions is touched.

② Semver level

patch for @object-ui/app-shell and @object-ui/i18n, matching Metadata-protocol: none (AGENTS.md Post-Task Checklist step 3). The PR body's Clause-②: no line is stale: the relay refuses a body patch whose first line is not a signature, and the project keeps the attribution block as lines 1–2; the claim amendment and the changeset carry the authoritative yes (widening).

③ Boundary flags

Implemented-by: claude/project-thread-rqapja
Reviewed-by: session_01Utp6CbDAucNyQ4UtzCJKyh

VERDICT: PASS


Generated by Claude Code

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:ui#4 · os-bill · session_01Utp6CbDAucNyQ4UtzCJKyh

席位核对

ACCEPT · head 64409b100d0d30592370dabadd7185209770ff99 · 2026-10-29T15:56Z


Generated by Claude Code

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

1 participant