You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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.tsx — fetchPresenceAndActivities: if (!dataSource || !isApp) return;
Consequences on Home / Organizations / the full-page AI screen:
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.
Activity tab reads "No recent activity" for the same reason.
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.
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'sisAppvariant 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.tsx—fetchPresenceAndActivities:if (!dataSource || !isApp) return;Consequences on Home / Organizations / the full-page AI screen:
useHomeInbox, ungated) shows the real count. Two numbers from one source, disagreeing on one screen.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
isAppexists to hide genuinely app-scoped chrome — the presence avatars and the connection dot, both rendered only whenisApp. Approvals and the activity feed are user- and org-scoped respectively; neither depends on which app is in the URL.Suggested fix
Drop
isAppfrom both effects (scope byuser?.id/dataSourceonly), and extendpackages/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
useHomeInboxeach 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