Telegram (ask questions / claim the issue here first): https://t.me/+DOylgFv1jyJlNzM0
Labels: bug, frontend, critical
The notification SSE stream writes to a query key no component reads, so live notifications don't show up until the 60s poll catches them.
useNotificationStream pushes events with queryClient.setQueryData(queryKeys.notifications.all()) — the exact key [notifications]. But the consumers read something else: NotificationDropdown uses useNotifications() = queryKeys.notifications.list({}) = [notifications, {}], and the inbox page uses useNotifications({limit,type,unread}). setQueryData needs an exact key match (unlike invalidateQueries, which matches by prefix), so the write lands in a cache entry nobody subscribes to. The whole point of the SSE push is instant updates, and right now the bell and inbox only refresh on the 60s refetchInterval.
What the fix has to hold to
- Stream writes have to land in the exact entry the dropdown and inbox read from — align the write key to the read key, or move all readers onto one canonical key.
- Keep the init-merge path and the unread-count math working after the key change.
- Don't break the prefix-based
invalidateQueries used elsewhere.
Done when
Where to start
Reconcile the query key across frontend/src/app/hooks/useNotificationStream.ts, frontend/src/app/hooks/useApi.ts, frontend/src/app/components/global_ui/NotificationDropdown.tsx, and frontend/src/app/[locale]/notifications/page.tsx. Add a test that a streamed notification renders. Backend SSE behavior and action_url deep-linking are out of scope. 1-2 days.
Labels:
bug,frontend,criticalThe notification SSE stream writes to a query key no component reads, so live notifications don't show up until the 60s poll catches them.
useNotificationStreampushes events withqueryClient.setQueryData(queryKeys.notifications.all())— the exact key[notifications]. But the consumers read something else:NotificationDropdownusesuseNotifications()=queryKeys.notifications.list({})=[notifications, {}], and the inbox page usesuseNotifications({limit,type,unread}).setQueryDataneeds an exact key match (unlikeinvalidateQueries, which matches by prefix), so the write lands in a cache entry nobody subscribes to. The whole point of the SSE push is instant updates, and right now the bell and inbox only refresh on the 60srefetchInterval.What the fix has to hold to
invalidateQueriesused elsewhere.Done when
npm test+ lint + typecheck green; CI passes.Where to start
Reconcile the query key across
frontend/src/app/hooks/useNotificationStream.ts,frontend/src/app/hooks/useApi.ts,frontend/src/app/components/global_ui/NotificationDropdown.tsx, andfrontend/src/app/[locale]/notifications/page.tsx. Add a test that a streamed notification renders. Backend SSE behavior andaction_urldeep-linking are out of scope. 1-2 days.