Skip to content

[console] The bell's Approvals and Activity tabs are still dead outside an app page (same isApp gate as #4110) #4197

Description

@yinlianghui

Found while fixing #4110. Filing rather than widening that PR's scope — same root cause, different tabs.

What #4110 fixed

AppHeader's inbox poller (sys_inbox_message + sys_notification_receipt) was gated on the header's isApp variant flag, so the bell's Notifications tab was permanently empty on every surface that is not /apps/:appName/*. That gate is now removed for the inbox read only.

What is still broken

The two sibling effects in the same component carry the identical gate, and the bell renders all three tabs in every variant:

  • AppHeader.tsx — pending-approvals poll: if (!isApp || !user?.id) return;
  • AppHeader.tsxfetchPresenceAndActivities: if (!dataSource || !isApp) return;

Consequences on Home / Organizations / the full-page AI screen:

  1. Approvals tab reads "No pending approvals" even when the user has some — on the very page whose own approvals card (useHomeInbox, ungated) shows the real count. Two numbers from one source, disagreeing on one screen.
  2. Activity tab reads "No recent activity" for the same reason.
  3. The bell badge is variant-dependent: it is unreadTopics + pendingApprovalsCount, so after [console] InboxPopover 通知页签恒为空:sys_inbox_message 有未读行、REST 正常返回、Home 卡片可渲染,弹层打开不发请求且过滤成空(rc.5 回归,rc.3 正常) #4110 the same user with the same data sees a different badge number on Home than inside an app, because only the first addend is now fetched off-app.

Point 3 is the one worth grading: the badge breakdown line (#4073 / objectstack#7233) exists precisely so a user can reconcile the badge against Home's cards, and off-app it currently reconciles against a zero that is an unasked question rather than an answer.

Why the gate is wrong here

isApp exists to hide genuinely app-scoped chrome — the presence avatars and the connection dot, both rendered only when isApp. Approvals and the activity feed are user- and org-scoped respectively; neither depends on which app is in the URL.

Suggested fix

Drop isApp from both effects (scope by user?.id / dataSource only), and extend packages/app-shell/src/layout/__tests__/AppHeader.inboxVariant.test.tsx — added by #4110's PR, already renders the header per variant against a fake adapter — with an approvals case and an activity case.

Note the cost, which is why this is a separate card rather than a silent add-on: on Home this makes the bell and useHomeInbox each issue their own approvals and activity reads. The inbox half already pays that after #4110; whether the duplicate is acceptable or the two consumers should share one fetch is a call worth making deliberately.


Generated by Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingpm:queue

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions