Skip to content

[approvals] Point the account app's Approvals nav at the inbox component; contribute a Setup inbox entry; document mounting the inbox in business apps #7234

Closed

Description

@os-zhuang

Part of #7213.
Blocked-by: #7231

(#7231 — the objectui half, registering the approvals:inbox component-registry key — carries the repo:objectui routing label. This issue is dispatchable only after #7231's PR merges. End-to-end console behavior additionally requires the next console pin bump, which is a separate standing chore — NOT a rider on this issue.)

Facts (verified on origin/main, 2026-08-10)

  • Entry C of [approvals][console] 「待我审批」有三个并存入口、三套不同 UI —— 其中 sys_approval_request 原生视图是无决策动作的开发者原始表 #7213 is exactly one metadata declaration: packages/platform-objects/src/apps/account.app.ts:100-108 (nav_account_approvals, type: 'object', sys_approval_request / my_pending). The account app declares no requiredPermissions (account.app.ts:52-56), so every authenticated user sees the raw engine-owned table.
  • Its record page shows NO decision actions because the 8 declared actions gate on record.viewer.can_act || record.viewer.can_override (packages/plugins/plugin-approvals/src/sys-approval-request.object.ts:252-407) and the viewer block is only attached on the approvals REST path (approval-service.ts:4012-4023, attachViewers()), never on the generic data API. Converting the nav entry — not patching the data API — is the v17 fix; the data-source contract is objectui#2763 A1 (deliberately out of scope here).
  • plugin-approvals contributes three raw-table Setup entries (approvals-plugin.ts:85-96) into group_approvals, gated by manage_platform_settings (setup.app.ts:80-87) — correctly positioned as an admin/diagnostic surface; they stay.
  • zh labels for these nav items live in packages/platform-objects/src/apps/translations/zh-CN.ts (:21 待我审批, :74-78).

Scope

  1. account.app.ts: change nav_account_approvals to { type: 'component', componentRef: 'approvals:inbox' } — label/icon/position unchanged; the entry point stays, the destination becomes the full Approvals Inbox. Suggestion (verify, optional): add requiresService: 'approvals' so the entry hides when plugin-approvals is not installed (requiresObject no longer applies to a component item).
  2. approvals-plugin.ts navigationContributions: add an "Approvals Inbox" type: 'component' item (componentRef approvals:inbox) at the top of group_approvals, above the three raw tables, so admins reach the full UI from Setup too; keep the raw-table entries as-is.
  3. Translations for the new/changed nav items in packages/platform-objects/src/apps/translations/* (zh 审批中心 for the Setup entry; the account entry keeps 待我审批) — respect the check:app-nav-i18n gate.
  4. Docs (content/docs/automation/approvals.mdx): update "The approver finds it in their queue" to name the Approvals Inbox as the canonical approver surface, and add a short "Mount the approvals inbox in your app" snippet ({ type: 'component', componentRef: 'approvals:inbox', label: 'Approvals' }). Touch content/docs/ui/setup-app.mdx's group_approvals row if it names the entries.
  5. Update packages/plugins/plugin-approvals/src/nav-contribution.test.ts and any pinned nav expectations; changeset (user-visible).

Acceptance criteria

  • The account app's Approvals entry renders the full inbox (component route) instead of the raw sys_approval_request grid — end users get decision actions, business vocabulary, node progress, and the drawer.
  • Setup → Approvals shows an "Approvals Inbox" entry above the raw tables.
  • The raw tables remain reachable only under Setup (admin-gated); sys_approval_request is no longer surfaced raw to end users anywhere.
  • Docs updated; check:app-nav-i18n, nav-contribution tests, and affected package suites green.

Out of scope

Console pin bump (separate chore); attaching viewer on the generic data API (objectui#2763 A1); vocabulary alignment (#7232).

Activity

  1. self-assigned this
    on Aug 10, 2026
  2. os-zhuang commented on Aug 10, 2026

    @os-zhuang
    ContributorAuthor

    Reservation (not yet dispatched): this issue is part of the pm:epic train on #7213 — see the epic registration in that issue's body.
    Session: session_01L9U1G2piXmYrhYQX96XUyv
    Planned dispatch: round 2, once the Blocked-by: #7231 upstream merges (the approvals:inbox component key must exist in objectui before this nav metadata points at it). Serial note: shares packages/plugins/plugin-approvals with #7232, which rides round 1 — this card waits for both.
    Other PM seats (including the unlock sweep that fires when #7231 closes): please do not claim or re-queue for general dispatch — the assignee + this comment are the reservation; it will be dispatched from the epic session, which also owns swapping pm:blocked → dispatch at that time.


    Generated by Claude Code

  3. added
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:blockedBlocked by another issue/PR — body carries Blocked-by: #N
    on Aug 10, 2026
  4. os-zhuang commented on Aug 10, 2026

    @os-zhuang
    ContributorAuthor

    Unblock verified + dispatching now (round 3 of the #7213 epic; supersedes the reservation comment above). Both upstreams are MERGED and the premises were re-verified on the merged ref (not assumed from the unlock): objectui#4071 landed the approvals:inbox registry key (objectui main 28c38567b); #7271 landed the vocabulary alignment (main 5d12675fc); account.app.ts:100-108 is still type: 'object' and the plugin's navigationContributions are unchanged on current origin/main.

    Claim: PM loop round 3
    Session: session_01L9U1G2piXmYrhYQX96XUyv
    Branch: claude/issue-7234-approvals-nav-component
    Worktree: objectstack-issue-7234
    Domain: domain:metadata
    File surface: packages/platform-objects/src/apps/account.app.ts, packages/platform-objects/src/apps/translations/*, packages/plugins/plugin-approvals/src/approvals-plugin.ts, packages/plugins/plugin-approvals/src/nav-contribution.test.ts, content/docs/automation/approvals.mdx, content/docs/ui/setup-app.mdx
    Container & model: M, mode:subagent, model: opus
    Serial constraints cleared: #7271 (same package, translations) is MERGED — base is current main. Same-day churn to respect: #7271 added approval-status-vocabulary.test.ts with a cross-package parity case pinning the plugin's my_pending view label to platform-objects' nav_account_approvals label (zh/ja/es) — this card keeps that nav label untouched, so the pin must stay green.


    Generated by Claude Code

  5. os-zhuang commented on Aug 10, 2026

    @os-zhuang
    ContributorAuthor

    ACCEPT — PR #7298 (review by the epic PM session, verified against GitHub, not the report):

    • Shipped: nav_account_approvals now targets { type: 'component', componentRef: 'approvals:inbox' } gated by requiresService: 'approvals' (gate mechanism verified at its implementation — BaseNavItemSchema spread + filterNav's variant-agnostic read + the existing rest-side pin — not assumed); Setup gains an Approvals Inbox entry ABOVE the three raw tables, with array order pinned as the assertion (the old set-shaped .sort() assertion couldn't see ordering, and burying the working surface under raw tables was much of [approvals][console] 「待我审批」有三个并存入口、三套不同 UI —— 其中 sys_approval_request 原生视图是无决策动作的开发者原始表 #7213's complaint); labels in all four locales; docs now name the inbox as the canonical approver surface, explain in a callout why the raw table can't be it (viewer only on the REST path), and teach mounting via the registry key — never a console path.
    • Constraints respected: nav_account_approvals label/icon untouched, so fix(plugin-approvals): unify the approval-status vocabulary across the i18n bundles #7271's cross-package parity pin stays green (run explicitly, inside the 452 green); no requiredPermissions added; no .objectui-sha rider (chore: bump the console pin to pick up objectui#4071 (approvals:inbox component ref) #7268 owns the bump); no releases/ADR paths.
    • File surface: 11 files, all inside the claim; minor changeset for both packages. CI verified per-job: 27 check runs — ESLint, TypeScript Type Check, Test Core 3/3, Dogfood 3/3, Build Core/Docs, Check Changeset, Temporal Conformance all success; Console Pin Gate skipped correctly (no pin change).
    • Reverse verification both directions in the predicted shape (5/7 red on revert with the 2 structurally-green cases explained; check:app-nav-i18n red naming exactly the dropped id — proving the contributed entry is merged and judged, not merely declared).

    This closes the last implementation card of the #7213 epic. Remaining after merge: console pin bump (#7268, queued) for end-to-end browser behavior; epic close-out on #7213.


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

pm:dispatchedDispatched to a dev agent by /pm-dispatch

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions