Skip to content

Notifications Module

Overview

This module handles platform notification delivery and device-token management for SMS, email, push, and in-app notification retrieval.

Base route: - /api/v1/notify

USSD has been split into its own module documentation: - USSD Services Module

Primary sources scanned: - app/api/v1/endpoints/notify.py - app/services/notify.py - app/db/seed/template_seed.json - app/db/seed/auth/template_seed.json

Canonical references: - API Route Live Reference - API Route Documentation TODO

Verified Endpoints

Route Method Permission Service Function
/message/fetch POST fetch_messages fetch_all_messages
/message/retry POST retry_messages retry_message
/notification/fetch POST fetch_notification fetch_all_notifications
/notification/read POST read_notification mark_notification_read
/device/register POST register_push_device Device token register flow
/device/list POST list_push_devices Device token list flow
/device/get POST get_push_device Device token get flow
/device/activate POST activate_push_device Device token activate flow
/device/deactivate POST deactivate_push_device Device token deactivate flow
/device/delete POST delete_push_device Device token delete flow
/device/delete-all POST delete_all_push_devices Device token bulk delete flow

Notification Channels

Supported channels and routing model: - sms: queued Message records, provider selected from Item/ItemKind provider entries - email: queued Message records with plain text body plus optional html_body in udf - push: token fan-out to active DeviceToken rows; one Message row per token - in-app: LiveNotification records and socket broadcast path

Channel behavior in queue_template_notification: - resolves MessageChannel by name - resolves Template by channel_id + template name + language_id - renders placeholders against template message - applies channel-specific payload formatting before queueing

Device Token Lifecycle

Device endpoints cover full token management: 1. register - Upserts token ownership and reactivates existing tokens.

  1. list and get
  2. Lists active or full token set by current user.
  3. Fetches single token details scoped to current user.

  4. activate and deactivate

  5. Soft toggles token state via is_active.

  6. delete and delete-all

  7. Removes one or all tokens for current user.

Runtime safeguards in service layer: - push sends only to active tokens - failed push token responses are deactivated via _deactivate_failed_tokens

OTP Services

OTP capabilities in notify service: - generate_custom_otp: numeric OTP generation by length - create_and_store_otp: stores hashed OTP with expiry and purpose - create_transaction_otp: transaction OTP issuance and template queue - verify_otp: attempt control, expiry check, hash verification, single-use mark - generate_access_policy_otp_and_send: policy-driven OTP delivery across sms or email

OTP security properties: - OTP values are hashed at persistence - expiry is enforced before verification - attempt count is enforced with max attempts - successful verification marks OTP consumed

Templating Engine

Central function: - queue_template_notification

Template selection keys: - channel_id - name - language_id

Rendering behavior: 1. Primary path: Template.format_message with placeholders 2. Fallback path: Template.format_transaction_message for transaction-shaped payloads

Placeholder behavior: - Missing placeholders can trigger PlaceholderNotFoundError and fallback handling - Dynamic values are passed through placeholders dict - Common placeholders include name, otp, amount, currency, account fields, receipt token

Email rendering behavior: - plain text template message stored in Message.body - rich html generated and stored in Message.udf.html_body - security template variants and transaction template context are supported

Push rendering behavior: - push_data payload includes template name + placeholders - title defaults to template subject or template name - optional image_url supported via placeholders

Language Resolution

Language is explicit in template resolution: - queue_template_notification(..., language="en") defaults to en - template query requires exact language_id match

If template does not exist for the requested language and channel: - service raises not found error for template and channel combination

Current seed data demonstrates multilingual templates: - en - fr - pt

Template JSON Structure

Primary seed files: - app/db/seed/template_seed.json - app/db/seed/auth/template_seed.json

Template item structure:

{
  "channel_id": "sms",
  "language_id": "en",
  "name": "send2FA",
  "subject": "Your 2FA Code",
  "message": "Hello {name}, your 2FA code is {otp}. Use it to complete your login. Do not share this code.{sms_retriever_hash_block}"
}

Key fields: - channel_id: sms | email | push - language_id: locale key used by template lookup - name: template key used by business flows - subject: notification subject/title - message: placeholder-based content body

Common template groups present in seed files: - authentication templates (sendInitialPin, sendInitialPassword, sendOTP, send2FA, resetPasswordInitiate) - transaction templates (INTERNAL_TRANSFER, DEPOSIT, WITHDRAWAL, EXTERNAL_TRANSFER) - account lifecycle templates (accountOpening, walletCreated)

Message and Notification Data Model Behavior

Queue models: - Message: outbound queue unit with status_id, template_id, sender, receiver, body, service, provider, priority, udf - LiveNotification: in-app notification stream with read tracking - DeviceToken: push target registry per user and device - OTP: OTP persistence with purpose, attempts, expiry, is_used

Read and retry flows: - fetch_all_messages: paginated message retrieval with filters and sensitive-data obfuscation - retry_message: retries failed/finished message jobs and updates Celery job tracking - fetch_all_notifications: paginated in-app notification retrieval - mark_notification_read: bulk mark read + read counters

Operational Notes

  • Notification queueing is template-driven and provider-aware.
  • Push notifications depend on active device tokens in DeviceToken.
  • Priority messages may be dispatched immediately after queue creation.
  • Template language/channel mismatches fail fast during queueing.
  • Push fallback and stale-token deactivation are implemented in service logic.