← All frames · Frame (d)

The notification bell, backed by a real inbox

The bell stops being a stub. Unread count, an inbox with per-item read/archive, “mark all read”, and a live SSE stream that prepends arrivals without a refetch.

Populated inbox — 3 unread
Notifications
Invoice INV-2043 paid
$480.00 for Northwind Labs was charged successfully.
billing2m ago
New sign-in from Lisbon
Chrome on macOS. If this wasn't you, review your sessions.
security1h ago
Timesheets installed for everyone
Ada Rivera installed Timesheets across Northwind Labs.
app3h ago
Workspace provisioning complete
Northwind Labs is ready to use.
systemYesterday

Read and unread are visually distinct without relying on color alone — the unread rows also carry the leading dot and a tinted surface.

Loading · empty · error
Notifications
Notifications
You're all caught up.
Notifications
Couldn't load notifications.

Degrades quiet: when the service is unreachable the bell shows no badge and the panel shows the error — a notification outage must never break the shell.

Badge states
3
99+

Left to right: unread, none, capped at 99+, and service unreachable. The degraded bell is indistinguishable from “no unread” on purpose — a phantom badge the user can never clear is worse than a missing one.

Live arrival over SSE
Notifications
Deployment finished
fuzefront-backend rolled out to production.
systemjust now

Arrivals prepend and bump the badge. On reconnect the client re-fetches the unread count, so an event missed during a drop self-heals rather than under-counting forever.

Service surface

MethodPathNotes
GET/api/v1/notificationsPaginated inbox; status, category, organizationId filters.
GET/api/v1/notifications/unread-countThe badge.
GET/api/v1/notifications/streamSSE, heartbeat-kept.
POST/api/v1/notifications/{id}/readAlso /read-all, /{id}/unread, /seen.
DELETE/api/v1/notifications/{id}Archive.
GET/PUT/api/v1/notifications/preferencesPer category × channel.
POST/api/v1/notifications/internal/publishService-to-service only; internal token; fans out to recipients.
Test hooks: [data-panel='notifications'] · [data-state='loading'|'empty'|'error'|'ready'] · [data-bell] · [data-badge] · [data-notification] · [data-read] · [data-action='mark-all-read'|'archive'|'retry'] · [data-arrival='live'].
Frame (d) — notifications Next: cross-cutting states →
Review · app-scopes-user-menu approve or reject each flow ↓
user-menupendingApproveReject
accountspendingApproveReject
install-scopependingApproveReject
notificationspendingApproveReject