Notifications Module
Overview
The Notifications Module handles all outbound communications from the IWM Platform to users. It manages multiple delivery channels (email, SMS, push, in-app), user preferences, template rendering, delivery tracking, and retry logic. The module consumes domain events from other modules and translates them into appropriate notifications.
Responsibilities
- Multi-channel notification delivery (email, SMS, push, in-app)
- User notification preferences management
- Dynamic template rendering
- Delivery tracking and retry logic
- Event-driven notification triggering
- Rate limiting and throttling
- Notification history and audit
Architecture Overview
Notification Channels
Email (SendGrid)
Primary channel for transactional and marketing communications.
| Configuration | Value |
|---|---|
| Provider | SendGrid |
| From Address | Configurable per notification type |
| Rate Limit | 100 emails/second |
| Retry Attempts | 3 |
| Retry Delay | Exponential backoff |
Supported Features:
- HTML and plain text templates
- Dynamic content personalization
- Attachments (PDFs, images)
- Click and open tracking
- Unsubscribe links
SMS (Twilio)
For time-sensitive notifications and 2FA.
| Configuration | Value |
|---|---|
| Provider | Twilio |
| Sender ID | Configurable |
| Rate Limit | 10 SMS/second |
| Retry Attempts | 2 |
| Max Length | 160 characters (or concatenated) |
Supported Features:
- Domestic and international delivery
- Delivery receipts
- 2FA codes
- Short URLs for links
Push Notifications (Firebase FCM)
Mobile and web push notifications.
| Configuration | Value |
|---|---|
| Provider | Firebase Cloud Messaging |
| Platforms | iOS, Android, Web |
| TTL | 4 weeks |
| Priority | High/Normal |
Supported Features:
- Rich notifications (images, actions)
- Topic-based broadcasting
- Device token management
- Silent notifications
In-App Notifications
Real-time notifications within the platform.
| Configuration | Value |
|---|---|
| Delivery | WebSocket |
| Storage | Database |
| Retention | 90 days |
Supported Features:
- Real-time delivery
- Read/unread status
- Action buttons
- Notification center UI
Event Triggers
What Events Trigger Which Notifications
Event-to-Notification Mapping
| Event | Notification Type | Channels | Priority |
|---|---|---|---|
| UserRegistered | welcome_email | Normal | |
| UserVerified | account_activated | Email, In-App | Normal |
| PasswordResetRequested | password_reset | High | |
| TwoFactorEnabled | security_alert | Email, SMS | High |
| LoginFromNewDevice | security_alert | Email, Push | High |
| KycApproved | kyc_approved | Email, In-App | Normal |
| KycRejected | kyc_rejected | Email, In-App | Normal |
| PartnerRegistered | partner_welcome | Normal | |
| NewReferral | new_referral | Email, Push, In-App | Normal |
| CommissionCalculated | commission_pending | In-App | Low |
| CommissionPaid | commission_paid | Email, In-App | Normal |
| PayoutRequested | payout_requested | Normal | |
| PayoutCompleted | payout_completed | Email, SMS, In-App | High |
| PayoutRejected | payout_rejected | Email, In-App | High |
| RankChanged | rank_change | Email, Push, In-App | Normal |
| OrderCreated | order_confirmation | High | |
| OrderConfirmed | order_confirmed | Email, In-App | Normal |
| OrderShipped | order_shipped | Email, SMS, Push | High |
| OrderDelivered | order_delivered | Email, Push | Normal |
| PaymentFailed | payment_failed | Email, SMS | High |
| RefundCompleted | refund_completed | Email, In-App | Normal |
| ParticipationActivated | investment_activated | Email, In-App | High |
| ReturnsDistributed | returns_credited | Email, In-App | Normal |
| InvestmentMatured | investment_matured | Email, Push, In-App | High |
| CartAbandoned | cart_abandoned | Low |
User Preferences
Preference Structure
Users can configure preferences per notification type and channel:
{
"user_id": "uuid",
"preferences": {
"order_confirmation": {
"email": true,
"sms": false,
"push": true,
"in_app": true
},
"commission_paid": {
"email": true,
"sms": false,
"push": true,
"in_app": true
},
"marketing": {
"email": false,
"sms": false,
"push": false,
"in_app": false
}
},
"global_settings": {
"quiet_hours": {
"enabled": true,
"start": "22:00",
"end": "08:00",
"timezone": "Europe/Moscow"
},
"language": "ru",
"email_frequency": "immediate"
}
}Preference Categories
| Category | Notifications | Can Disable |
|---|---|---|
| Security | 2FA, password reset, security alerts | No |
| Transactional | Orders, payments, investments | No (but can choose channels) |
| Account | KYC, profile updates | No (but can choose channels) |
| MLM | Commissions, payouts, ranks | Yes |
| Marketing | Promotions, newsletters | Yes |
Preference Management Flow
Template System
Template Structure
Templates are defined with variables for dynamic content:
templates/
├── email/
│ ├── welcome_email/
│ │ ├── subject.txt
│ │ ├── body.html
│ │ └── body.txt
│ ├── order_confirmation/
│ │ ├── subject.txt
│ │ ├── body.html
│ │ └── body.txt
│ └── ...
├── sms/
│ ├── 2fa_code.txt
│ ├── order_shipped.txt
│ └── ...
├── push/
│ ├── new_referral.json
│ ├── commission_paid.json
│ └── ...
└── in_app/
├── commission_pending.json
└── ...Template Variables
Common variables available in all templates:
| Variable | Description |
|---|---|
user.firstName | User's first name |
user.lastName | User's last name |
user.email | User's email |
platform.name | Platform name |
platform.supportEmail | Support email |
platform.baseUrl | Platform URL |
Note: Template variables use double curly braces syntax in templates.
Example Templates
Email Template (order_confirmation/body.html):
<!DOCTYPE html>
<html>
<head>
<title>Order Confirmation</title>
</head>
<body>
<h1>Thank you for your order, {{user.firstName}}!</h1>
<p>Your order <strong>#{{order.number}}</strong> has been received.</p>
<h2>Order Details</h2>
<table>
{{#each order.items}}
<tr>
<td>{{this.name}}</td>
<td>x{{this.quantity}}</td>
<td>{{this.price}} {{../order.currency}}</td>
</tr>
{{/each}}
</table>
<p><strong>Total: {{order.total}} {{order.currency}}</strong></p>
<p>
<a href="{{platform.baseUrl}}/orders/{{order.id}}">
View Order
</a>
</p>
</body>
</html>SMS Template (order_shipped.txt):
Your order #{{order.number}} has been shipped!
Tracking: {{shipment.trackingNumber}}
Track: {{shipment.trackingUrl}}Push Template (commission_paid.json):
{
"title": "Commission Received!",
"body": "You earned {{commission.amount}} {{commission.currency}} from {{commission.source}}",
"icon": "commission_icon",
"action_url": "/mlm/commissions/{{commission.id}}",
"data": {
"type": "commission_paid",
"commission_id": "{{commission.id}}"
}
}Template Rendering Flow
Delivery Tracking
Delivery Status Flow
Notification Log Entry
| Field | Type | Description |
|---|---|---|
| id | UUID | Log entry ID |
| user_id | UUID | Target user |
| notification_type | VARCHAR | Type identifier |
| channel | ENUM | EMAIL, SMS, PUSH, IN_APP |
| status | ENUM | Delivery status |
| provider_reference | VARCHAR | External message ID |
| sent_at | TIMESTAMP | Send timestamp |
| delivered_at | TIMESTAMP | Delivery confirmation |
| failed_at | TIMESTAMP | Failure timestamp |
| failure_reason | TEXT | Error details |
| retry_count | INT | Retry attempts |
| payload | JSONB | Rendered content |
Retry Logic
Retry Schedule:
| Attempt | Delay |
|---|---|
| 1st retry | 1 minute |
| 2nd retry | 5 minutes |
| 3rd retry | 15 minutes |
| After 3rd | Marked as failed |
Notification Types by Module
Authentication Notifications
| Type | Description | Channels |
|---|---|---|
| welcome_email | New user registration | |
| email_verification | Email verification link | |
| password_reset | Password reset link | |
| password_changed | Password change confirmation | |
| 2fa_code | Two-factor code | SMS, Email |
| 2fa_enabled | 2FA activation confirmation | |
| 2fa_disabled | 2FA deactivation alert | |
| login_new_device | Login from new device | Email, Push |
| account_locked | Account locked alert | |
| account_unlocked | Account unlocked |
KYC Notifications
| Type | Description | Channels |
|---|---|---|
| kyc_submitted | KYC submission confirmation | Email, In-App |
| kyc_under_review | KYC being reviewed | Email, In-App |
| kyc_approved | KYC approved | Email, In-App |
| kyc_rejected | KYC rejected with reason | Email, In-App |
| kyc_needs_info | Additional info requested | Email, In-App |
| kyc_expiring | KYC expiration warning |
Order Notifications
| Type | Description | Channels |
|---|---|---|
| order_confirmation | Order placed | |
| order_confirmed | Payment confirmed | Email, In-App |
| order_processing | Order being prepared | In-App |
| order_shipped | Order shipped with tracking | Email, SMS, Push |
| order_out_for_delivery | Out for delivery | Push |
| order_delivered | Order delivered | Email, Push |
| order_cancelled | Order cancelled | Email, In-App |
| payment_failed | Payment failed | Email, SMS |
| payment_retry | Payment retry reminder | |
| refund_initiated | Refund started | Email, In-App |
| refund_completed | Refund processed | Email, In-App |
MLM Commission Notifications
| Type | Description | Channels |
|---|---|---|
| commission_pending | Commission calculated | In-App |
| commission_approved | Commission approved | Email, In-App |
| commission_paid | Commission credited | Email, Push, In-App |
| commission_reversed | Commission reversed | Email, In-App |
| weekly_earnings | Weekly earnings summary | |
| monthly_earnings | Monthly earnings report |
MLM Payout Notifications
| Type | Description | Channels |
|---|---|---|
| payout_requested | Payout request submitted | |
| payout_approved | Payout approved | Email, In-App |
| payout_processing | Payout being processed | In-App |
| payout_completed | Payout sent | Email, SMS, In-App |
| payout_rejected | Payout rejected | Email, In-App |
MLM Rank Notifications
| Type | Description | Channels |
|---|---|---|
| rank_promotion | Rank promoted | Email, Push, In-App |
| rank_demotion_warning | Demotion warning | Email, In-App |
| rank_demoted | Rank demoted | Email, In-App |
| rank_qualification_progress | Progress update | In-App |
MLM Referral Notifications
| Type | Description | Channels |
|---|---|---|
| new_referral | New referral signup | Email, Push, In-App |
| referral_activated | Referral made first purchase | Push, In-App |
| team_member_achievement | Team member milestone | In-App |
Investment Notifications
| Type | Description | Channels |
|---|---|---|
| investment_submitted | Participation submitted | |
| investment_approved | Investment approved | Email, In-App |
| investment_activated | Investment active | Email, Push, In-App |
| investment_rejected | Investment rejected | Email, In-App |
| returns_distributed | Returns credited | Email, In-App |
| investment_matured | Investment matured | Email, Push, In-App |
| withdrawal_requested | Withdrawal submitted | |
| withdrawal_completed | Withdrawal processed | Email, SMS, In-App |
| portfolio_update | Monthly portfolio summary |
Rate Limiting and Throttling
Rate Limits by Channel
| Channel | User Limit | Global Limit |
|---|---|---|
| 20/hour | 100/second | |
| SMS | 5/hour | 10/second |
| Push | 50/hour | 1000/second |
| In-App | Unlimited | N/A |
Quiet Hours
Users can configure quiet hours:
- Notifications queued during quiet hours
- Delivered when quiet hours end
- Security notifications bypass quiet hours
Notification Batching
Low-priority notifications can be batched:
- Commission pending notifications
- In-app activity updates
- Marketing communications
Business Rules and Invariants
Delivery Rules
- Security notifications cannot be disabled
- User must have verified channel to receive notifications
- Failed deliveries retry up to 3 times
- Quiet hours respected except for security alerts
- Rate limits enforced per user and globally
Preference Rules
- New users get all notifications enabled by default
- Marketing defaults to disabled (opt-in)
- At least one channel must be enabled for transactional
- Preferences stored per notification type
Template Rules
- All templates must have fallback locale
- Variables must be sanitized before rendering
- URLs must be absolute and use HTTPS
- Sensitive data not logged in delivery logs
Integration Points
Consumes from Other Modules
| Event | Source | Notification Type |
|---|---|---|
| UserRegistered | Core | welcome_email |
| UserVerified | Core | account_activated |
| PasswordResetRequested | Core | password_reset |
| TwoFactorEnabled | Core | 2fa_enabled |
| KycStatusChanged | Core | kyc_* |
| OrderCreated | Commerce | order_confirmation |
| OrderShipped | Commerce | order_shipped |
| PaymentReceived | Commerce | order_confirmed |
| PaymentFailed | Commerce | payment_failed |
| CommissionPaid | MLM | commission_paid |
| PayoutCompleted | MLM | payout_completed |
| RankChanged | MLM | rank_* |
| NewReferral | MLM | new_referral |
| ParticipationActivated | Investment | investment_activated |
| ReturnsDistributed | Investment | returns_distributed |
| InvestmentMatured | Investment | investment_matured |
Provides to Other Modules
| Interface | Purpose |
|---|---|
| INotificationService | Send ad-hoc notifications |
| IPreferenceService | Check/update user preferences |