Product engineering
Build notifications that arrive at the right moment
A teammate mentions you in a comment while you are looking at a project board. The useful moment for that notification is now, while you can open the conversation and respond. Building that experience takes more than adding a toast: the inbox, unread count and saved activity all need to agree.
Start with the inbox
Decide what the notification represents before choosing how to deliver it. A mention should point to a comment. An export notification should point to a finished file. Give each notification a stable ID, a recipient, a creation time and a destination the user can open. Store whether it has been read so that the same inbox makes sense across visits and devices.
The saved record is what lets someone return tomorrow and still find the update. The realtime event makes that record visible to someone who is connected right now. In pubb, events go to currently connected subscribers; your application stores the notification history and serves it when the inbox opens.
Publish after the change is saved
For a mention, first check that the author can access the project, save the comment, and create the notification for the recipient. After those writes succeed, publish a notification.created event to a channel such as private-user-42. Include the notification ID and the fields the recipient needs, or use the event to trigger a fresh inbox request.
Saving before publishing prevents a client from opening a notification whose record does not exist yet. It still leaves a failure window: the write may succeed and the publication may fail. For workflows that need reliable publication retries, an application-side transactional outbox records pending events alongside the data change in one database transaction. A worker can then publish them and retry failures. This is an application architecture choice, not a built-in inbox feature of pubb.
Send the update to its recipient
A personal inbox belongs on an authorized private channel. Your server should verify that the signed-in user is allowed to subscribe to the requested recipient channel before obtaining a subscription signature. A channel name containing a user ID does not provide access control by itself.
Keep the payload focused on that audience. A notification for one teammate does not need every participant’s email address or the full project record. In the client, merge notifications by their stable ID so repeated processing does not create a second inbox row. Refresh the unread count from saved state when needed rather than assuming every incoming event should increment it.
Make returning feel as good as arriving
When someone opens the app or reconnects after an interruption, fetch their saved notifications and unread count. Marking a notification as read should update the saved record; you can also publish that change to the user’s other connected screens. Keep transient toasts separate from the inbox so dismissing a popup does not accidentally delete useful history.
Reaching someone while the web app is not loaded is a separate delivery path. The browser Push API supports that through a service worker, subject to browser support and permission requirements. Choose that path when the product needs background notifications; use pubb for live updates inside connected experiences. Start with one complete flow—a mention, an inbox item and its destination—and make it work across both an active session and a return visit.