Backend Overview
High-level backend architecture and flow for the Notification System.
Backend Overview
This document provides a high-level view of how the Notification System backend is designed: how it uses FCM (Firebase Cloud Messaging), how devices are subscribed/unsubscribed, how topics are named, which DB models are involved, and how notifications are generated and sent.
For product context and UI workflows, see:
Channels (What gets delivered where)
-
Browser / device push (FCM)
- Used for push notifications that can show even when the app is not focused.
- Delivered to topics or device tokens depending on recipient strategy.
-
In-app notifications / Inbox
- Users see notifications via the Notification Center/Inbox backed by database records.
- The frontend uses backend APIs to fetch lists and update read state.
Device registration + Subscribe / Unsubscribe
At a high level the lifecycle is:
- Token registration
- Client (web/mobile) generates an FCM token and registers it with the backend.
- Backend stores the token and its context (device, user/doctor, lab, session).
- Subscribe to topics
- Backend subscribes the token to the correct topics (org/lab/role/type scoped).
- Unsubscribe / cleanup
- On logout/session end, backend unsubscribes and/or deletes token mappings so the device stops receiving pushes.
See API Reference for the endpoints used by clients (/users/fcm-token, /notifications/subscribe, /notifications/unsubscribe).
Topic naming convention
Topics are derived from notification type and the βreference idβ extracted from session context.
For example, for Org Report Ready and Critical Report notifications, the topic is built like:
{deployment_zone}_notification_type_{notification_type_id}_org_{organization_id}This behaviour is defined in communication/notifications/models/notification_types_master.py (NotificationTypesMaster.get_topic()), where deployment_zone comes from DEPLOYMENT_ZONE (default IN) and the reference id resolves to organizationId for these types.
Core DB models (what is stored)
These are the key tables/models used by the backend:
NotificationTypesMaster(NotificationTypesMaster)- Master list of notification types and default message parameters.
LabNotificationsTypes(LabNotificationsTypes)- Lab-level configuration for each notification type (message params, enabled/disabled).
Notifications(Notification)- Each generated notification instance (payload/message + context like lab/org/report references).
- Read metadata is stored on the notification (e.g.
read_on,read_by*fields).
FcmDevices(FcmDevices)- Stored device tokens and topic subscriptions mapped to lab/doc/user and session (
token,topics,session_key,last_activity_time).
- Stored device tokens and topic subscriptions mapped to lab/doc/user and session (
For table structure and relationships, see Data Model.
Sending a notification (high level)
- A business event occurs
- Example: critical report is finalised or an organisation report becomes ready.
- Backend selects notification type + config
- Resolves the
NotificationTypesMastertype and applicableLabNotificationsTypesconfig.
- Resolves the
- Recipients + topic resolution
- Determines recipients and topic(s) using session/org context and the naming convention described above.
- Persist notification record
- Creates a row in
Notificationswith the generated message payload and references.
- Creates a row in
- Trigger delivery
- Sends via FCM using the device tokens/topics associated to the recipients.
- Read/unread tracking
- When users interact with the inbox, backend updates read state via the read API.
Key Components
- Notification base classes
- Provide a common interface (
prepare_payload,get_recipients,send) for all web notifications.
- Provide a common interface (
- Type-specific implementations
- Classes such as
OrgReportReady,CriticalReportNotification, etc., encapsulate logic for specific notification types.
- Classes such as
- Gateways
FCMPusherGateway(and optional Pusher gateways) abstract the underlying delivery mechanism.
For deeper backend architecture, see Class Diagrams.