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.
- list and get
- Lists active or full token set by current user.
-
Fetches single token details scoped to current user.
-
activate and deactivate
-
Soft toggles token state via is_active.
-
delete and delete-all
- 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.