Skip to content
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
This repository was archived by the owner on Nov 4, 2026. It is now read-only.

Home reads sys_inbox_message twice — the bell's poll and useHomeInbox each issue their own query #4225

Closed

Description

@yinlianghui

Found while implementing #4197 (PR #4223). Not fixed there — out of scope for that card, which covers the approvals and sys_activity feeds.

What

On /home two consumers mount in one tree and each issues its own sys_inbox_message read:

consumer query cadence
bell poll — layout/AppHeader.tsx $filter: {user_id}, $orderby: {created_at: desc}, $top: 20, joined with sys_notification_receipt ($top: 200) for read-state every 10s
hooks/useHomeInbox.ts → Home's To-do card $filter: {user_id}, $orderby: {created_at: desc}, $top: limit (default 5) once on mount

So a Home page load issues both, and the bell's copy repeats every 10 seconds.

Why it exists

Pre-existing, and a side effect of the fix sequence rather than of any one change. #4199 un-gated the bell's inbox poll so the Notifications tab would fill in off-app — correctly — but did not merge it with Home's existing read. #4197 then shared the other two feeds (approvals and sys_activity) through hooks/sharedUserFeeds.ts; the inbox read was deliberately left out because the two consumers ask genuinely different questions there, unlike the other two feeds where the queries were byte-identical.

Observation-class, not a defect

Both consumers show correct data today. Nothing is stale, nothing disagrees — the badge's unread arithmetic lives entirely on the bell's side, and Home's card only lists titles. The cost is one extra round trip per Home load plus a 10s poll that partly overlaps it. Filing it so the duplication is recorded rather than rediscovered, not because a user is currently hitting a bug.

Why it is not a trivial merge

Home's rows are a strict prefix of the bell's superset (same object, same filter, same ordering, smaller $top), so one read could serve both. But:

  • the bell additionally reads sys_notification_receipt and joins it for is_read; Home needs none of that;
  • the bell maps to a row shape carrying notification_id / receipt_id for mark-read, Home to {id, title, actionUrl, createdAt} with a title-dedupe pass;
  • $top differs (20 vs limit), so a shared store would have to hold the superset and let Home slice — which is exactly the shape sharedUserFeeds already uses for activity, where Home filters the bell's rows at its own call site.

That last point is the suggested route: extend sharedUserFeeds with an inbox feed holding the bell's 20 merged rows, have Home derive its five from them. The merge is mechanical but it touches mark-read, so it deserves its own change and its own tests rather than riding along.

Pointers

Activity

  1. os-zhuang commented on Aug 11, 2026

    @os-zhuang
    Contributor

    Findings triage (first grade; premise check @ origin/main 6314e87): HOLD — finding stands.

    Anchors verified live: two independent sys_inbox_message readers — packages/app-shell/src/hooks/useHomeInbox.ts:100 (dataSource.find) and packages/app-shell/src/layout/AppHeader.tsx:364 (the bell's poll, with its scoping docblock at :320/:345). Held: duplicate-read efficiency observation, no wrong answer produced; consolidating onto one shared subscription is the fix shape and belongs with whoever next touches the inbox surface (the bell/inbox family already has queued kin — ui#4074's hardcoded entries and the #4110/#4197 gate work in flight — so dedup at promotion time matters).

    本评论来自分诊座位 Routine(#5474 试点),不构成认领。


    Generated by Claude Code

  2. os-zhuang commented on Aug 11, 2026

    @os-zhuang
    Contributor

    Findings cadence re-check @ origin/main 6d01319: HOLD — finding stands, premise live.

    Both duplicate reads verified on main: the bell's polled sys_inbox_message read in AppHeader.tsx (documented at :209/:286), the one-shot in useHomeInbox.ts:64, and sharedUserFeeds.ts still carries no inbox feed (its only "inbox" mention is the approvals-inbox docblock line at :21; last commit on the hooks is #4223 itself). Cost profile unchanged — one extra round trip per Home load plus overlap with a 10s poll, correctness unaffected on both consumers.

    One new adjacency since filing worth the eventual implementer's attention: ui#4230 (bell panel dead again on console 09987b68) and ui#4235 (HOME header renders a second inbox polling sys_inbox_message instead of /api/v1/notifications) are both live on this same surface — any sharedUserFeeds inbox-feed merge should land after those settle which source the bell reads, or it risks unifying onto the wrong query. Restart condition: promote when the bell's source question (ui#4230/ui#4235) is resolved; the merge route the card sketches is then mechanical-with-tests.

    本评论来自分诊座位 Routine(#5474 试点),不构成认领。


    Generated by Claude Code

  3. self-assigned this
    on Aug 11, 2026
  4. yinlianghui commented on Aug 11, 2026

    @yinlianghui
    ContributorAuthor

    PROMOTE + CLAIM — session session_017Qqyix2QcnpUC9XeYVDzx3(objectui whole-repo PM seat)。Branch: claude/issue-4225-shared-inbox-feed。

    升级依据,两条都按本卡分诊自己写下的机械条件触发:

    1. 重启条件已满足(09:16Z 分诊原文:"promote when the bell's source question (ui#4230/ui#4235) is resolved"):REGRESSION: the console header bell panel is dead again — "No notifications" under both Unread and All while /api/v1/notifications returns 10 rows (#4110 / #4156 back on console 09987b68) #4230 已裁定(表读为 ADR-0030 sanctioned;旧 pin 缺陷是 isApp 门,fix(app-shell): the bell polls the inbox on every console surface, not only inside an app (#4110) #4199 已修)、The console HOME header renders a second, different inbox polling the wrong source — sys_inbox_message instead of /api/v1/notifications, no badge, "You're all caught up" with 9 unread #4235 已交付 branch (a)(保源修条件,PR fix(app-shell): Home's action centre needs an ANSWER before it says "all caught up" (#4235) #4315;成员读权限由 objectstack#7586 当日授予)。统一查询的形状已知:sys_inbox_message + sys_notification_receipt 连接,'mine' 视图语义。
    2. observation 前提被 Home's action centre counts ALREADY-READ messages as needing attention — useHomeInbox never joins sys_notification_receipt #4316 证伪:"两个消费者都正确"不再成立——useHomeInbox 不连 receipts,已读消息仍算"需要你关注"(假阳性,铃铛的镜像)。本卡从效率观察升格为承载 Home's action centre counts ALREADY-READ messages as needing attention — useHomeInbox never joins sys_notification_receipt #4316 修复的执行卡。

    派发范围:sharedUserFeeds.ts 扩展 receipts-joined inbox feed;bell 的 poll 与 useHomeInbox 都从共享 feed 派生(消灭双读 + 10s poll 重叠);Fixes #4316(read-state 到达 home);rider:isMissingResource ×3 副本合并回单点。守护:PR #4284 的铃铛 Unread/All 绊线套件与 #4315 的 unansweredInbox 套件必须原样绿——两侧消费者的行为契约已被钉死,这正是"合并不许重破任一消费者"警告的执法形态。


    Generated by Claude Code

  5. yinlianghui commented on Aug 11, 2026

    @yinlianghui
    ContributorAuthor

    ACCEPT + 代决(裁 A) — PM review of record (session session_017Qqyix2QcnpUC9XeYVDzx3)。

    PR #4327 验收要点:

    Flipping ready + auto-merge;#4327 落地后本卡关闭(PR 为 Part of)。


    Generated by Claude Code

  6. yinlianghui commented on Aug 11, 2026

    @yinlianghui
    ContributorAuthor

    CLOSED — 共享 inbox feed 已落地 (session session_017Qqyix2QcnpUC9XeYVDzx3)。

    PR #4327 合入 main(bed18a5c2):sharedUserFeeds 增加 receipts 连接的 inbox feed,bell 与 Home 双消费者同源派生(bell 的 129 行私有轮询 effect 删除),同时修复 #4316(已读消息不再计入"需要关注")。本卡当年的 observation 定级("两个消费者都正确")已被 #4316 证伪,按分诊自记的重启条件(铃铛源问题解决即升级)升级执行。随行:store 补齐 bell 独有的三个韧性属性(隐藏页节流/可见即刷/失败退避)与四词状态方言,全 feed 受益;isMissingResource 三副本收敛。

    余波:#4329(Home 徽标计截断列表 vs bell 计全量——现在是 two-line fix)留 finding 池待分诊。


    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

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions