Notifications
The bell inbox — server-backed reminders with per-user read state, plus a persona-scoped activity feed of items needing attention.
The Notifications page is where the app surfaces things that need your eye — stock-take reminders, PRs waiting on review, deliveries to send, POs to approve. It opens with the bell inbox at the top, then a persona-scoped activity feed below it.
Note: the two halves behave differently. The bell inbox is server-backed with real per-user read state — its rows persist and stay marked-read across reloads. The activity feed below is derived live from current PR / transfer / PO state, so its “Clear” only hides what’s on screen and items reappear on reload. This page focuses on the bell inbox; the feed is summarized at the end.
The bell inbox
The inbox lists persisted notifications served by GET /notifications. Each row
is one notification per recipient, so read state is independent per user —
marking a notification read clears it for you alone, not for your colleagues.
Notifications are grouped under date headers (Today, Yesterday, then dated
buckets), newest first. An unread row carries a faint highlight and a small dot
next to its title; a count of N unread sits above the list.
Each notification carries:
- title — the headline line of the notification (e.g. a stock-take reminder).
- body — an optional second line with detail. Omitted rows show the title only.
- createdAt — when the notification was raised, rendered as a relative time (“2h ago”) and used to place the row in its date bucket.
- isRead — per-user read state. Unread rows are highlighted and show the unread dot.
The inbox renders for every persona (owner, manager, staff). If the notifications endpoint is unavailable or returns nothing, the inbox quietly renders nothing and the page falls through to the activity feed below — a missing endpoint never breaks the page.
Notification types
Two types are recognised today. Each gets its own icon and accent; any other (future, server-side) type falls back to a neutral bell row so it still renders cleanly.
stock_take_due— a reminder that an outlet’s stock take is due. Shown with a calendar-clock icon.stock_take_started— a heads-up that a stock take has been opened for an outlet. Shown with a clipboard-check icon.
Both types are scoped to an outlet (an outletId on the notification) and may
carry arbitrary server-supplied metadata (for example a take id or due date).
Reading and clearing
- Tap a notification. Tapping an unread row marks it read immediately.
For a stock-take notification (
stock_take_dueorstock_take_started), tapping also deep-links straight to the stock take screen so you can act on the reminder. - Mark all read. When there are unread items, a Mark all read control sits next to the unread count. It clears the entire unread badge in one action.
Note: read state in the bell inbox is real and persistent — once marked read, a notification stays read for you across reloads and devices, because it’s stored server-side per recipient. This is unlike the activity feed’s “Clear”, which is session-local.
How it links back to the stock-take flow
The two recognised types both originate from the stock-take cadence:
stock_take_duecorresponds to an outlet reaching its schedule status ofdue(oroverdue) on its stock-take cadence — a prompt to run the count.stock_take_startedsignals that a count has been opened for the outlet.
Tapping either row navigates to /stock-take, putting the count one tap away from the reminder. See stock dashboard for how an open (blind) stock take masks on-hand figures for staff while the count runs.
The activity feed
Below the bell inbox, each persona sees a derived event stream of items needing attention. These rows are computed live from current state — there is no backend seen/dismiss endpoint — so the Clear control only hides what’s currently shown; cleared items reappear on reload and genuinely newer ones still come through.
What each persona sees:
- Staff — activity from the staff member’s own outlet: PRs submitted, approved & ordered, sent back, or cancelled, and transfers dispatched. Tapping a PR row opens that purchase request.
- Manager — org-wide items to action: submitted PRs needing review, transfers pending dispatch, and receipts that came up short (received less than ordered) routed to the variance review.
- Owner — POs awaiting the owner’s approval, and POs that were sent back. Both deep-link into approvals.
Warning: the activity feed’s Clear is session-local — it only filters out items timestamped at or before the moment you cleared, and resets on reload. It does not write any read state. Only the bell inbox above has true, persisted read state.