Модуль Notifications
Обзор
Модуль Notifications обрабатывает все исходящие коммуникации платформы IWM с пользователями. Он управляет множеством каналов доставки (email, SMS, push, in-app), пользовательскими настройками, рендерингом шаблонов, отслеживанием доставки и логикой повторных попыток. Модуль потребляет доменные события от других модулей и преобразует их в соответствующие уведомления.
Зоны ответственности
- Многоканальная доставка уведомлений (email, SMS, push, in-app)
- Управление пользовательскими настройками уведомлений
- Динамический рендеринг шаблонов
- Отслеживание доставки и логика повторных попыток
- Триггеры уведомлений на основе событий
- Ограничение частоты и троттлинг
- История уведомлений и аудит
Обзор архитектуры
Каналы уведомлений
Email (SendGrid)
Основной канал для транзакционных и маркетинговых коммуникаций.
| Конфигурация | Значение |
|---|---|
| Провайдер | SendGrid |
| Адрес отправителя | Настраивается для каждого типа уведомления |
| Лимит частоты | 100 писем/секунду |
| Попыток повтора | 3 |
| Задержка повтора | Экспоненциальный откат |
Поддерживаемые функции:
- HTML и текстовые шаблоны
- Динамическая персонализация контента
- Вложения (PDF, изображения)
- Отслеживание кликов и открытий
- Ссылки отписки
SMS (Twilio)
Для срочных уведомлений и 2FA.
| Конфигурация | Значение |
|---|---|
| Провайдер | Twilio |
| Sender ID | Настраивается |
| Лимит частоты | 10 SMS/секунду |
| Попыток повтора | 2 |
| Макс. длина | 160 символов (или конкатенация) |
Поддерживаемые функции:
- Доставка внутри страны и международная
- Подтверждения доставки
- Коды 2FA
- Короткие URL для ссылок
Push уведомления (Firebase FCM)
Push уведомления для мобильных и веб.
| Конфигурация | Значение |
|---|---|
| Провайдер | Firebase Cloud Messaging |
| Платформы | iOS, Android, Web |
| TTL | 4 недели |
| Приоритет | High/Normal |
Поддерживаемые функции:
- Богатые уведомления (изображения, действия)
- Рассылка по темам
- Управление токенами устройств
- Тихие уведомления
In-App уведомления
Уведомления в реальном времени внутри платформы.
| Конфигурация | Значение |
|---|---|
| Доставка | WebSocket |
| Хранение | База данных |
| Срок хранения | 90 дней |
Поддерживаемые функции:
- Доставка в реальном времени
- Статус прочитано/непрочитано
- Кнопки действий
- UI центра уведомлений
Триггеры событий
Какие события вызывают какие уведомления
Соответствие событий и уведомлений
| Событие | Тип уведомления | Каналы | Приоритет |
|---|---|---|---|
| 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_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"
}
}Категории настроек
| Категория | Уведомления | Можно отключить |
|---|---|---|
| Security | 2FA, сброс пароля, предупреждения безопасности | Нет |
| Transactional | Заказы, платежи, инвестиции | Нет (но можно выбрать каналы) |
| Account | KYC, обновления профиля | Нет (но можно выбрать каналы) |
| MLM | Комиссии, выплаты, ранги | Да |
| Marketing | Акции, рассылки | Да |
Процесс управления настройками
Система шаблонов
Структура шаблонов
Шаблоны определяются с переменными для динамического контента:
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
└── ...Переменные шаблонов
Общие переменные, доступные во всех шаблонах:
| Переменная | Описание |
|---|---|
user.firstName | Имя пользователя |
user.lastName | Фамилия пользователя |
user.email | Email пользователя |
platform.name | Название платформы |
platform.supportEmail | Email поддержки |
platform.baseUrl | URL платформы |
Примечание: Переменные шаблонов используют синтаксис двойных фигурных скобок в шаблонах.
Примеры шаблонов
Email шаблон (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 шаблон (order_shipped.txt):
Your order #{{order.number}} has been shipped!
Tracking: {{shipment.trackingNumber}}
Track: {{shipment.trackingUrl}}Push шаблон (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}}"
}
}Процесс рендеринга шаблонов
Отслеживание доставки
Поток статусов доставки
Запись лога уведомлений
| Поле | Тип | Описание |
|---|---|---|
| id | UUID | ID записи лога |
| user_id | UUID | Целевой пользователь |
| notification_type | VARCHAR | Идентификатор типа |
| channel | ENUM | EMAIL, SMS, PUSH, IN_APP |
| status | ENUM | Статус доставки |
| provider_reference | VARCHAR | Внешний ID сообщения |
| sent_at | TIMESTAMP | Время отправки |
| delivered_at | TIMESTAMP | Подтверждение доставки |
| failed_at | TIMESTAMP | Время неудачи |
| failure_reason | TEXT | Детали ошибки |
| retry_count | INT | Количество попыток |
| payload | JSONB | Отрендеренный контент |
Логика повторных попыток
Расписание повторов:
| Попытка | Задержка |
|---|---|
| 1-й повтор | 1 минута |
| 2-й повтор | 5 минут |
| 3-й повтор | 15 минут |
| После 3-го | Помечается как неудачное |
Типы уведомлений по модулям
Уведомления аутентификации
| Тип | Описание | Каналы |
|---|---|---|
| welcome_email | Регистрация нового пользователя | |
| email_verification | Ссылка подтверждения email | |
| password_reset | Ссылка сброса пароля | |
| password_changed | Подтверждение смены пароля | |
| 2fa_code | Код двухфакторной аутентификации | SMS, Email |
| 2fa_enabled | Подтверждение активации 2FA | |
| 2fa_disabled | Предупреждение о деактивации 2FA | |
| login_new_device | Вход с нового устройства | Email, Push |
| account_locked | Предупреждение о блокировке аккаунта | |
| account_unlocked | Аккаунт разблокирован |
Уведомления KYC
| Тип | Описание | Каналы |
|---|---|---|
| kyc_submitted | Подтверждение подачи KYC | Email, In-App |
| kyc_under_review | KYC на проверке | Email, In-App |
| kyc_approved | KYC одобрен | Email, In-App |
| kyc_rejected | KYC отклонен с причиной | Email, In-App |
| kyc_needs_info | Запрошена дополнительная информация | Email, In-App |
| kyc_expiring | Предупреждение об истечении KYC |
Уведомления заказов
| Тип | Описание | Каналы |
|---|---|---|
| order_confirmation | Заказ размещен | |
| order_confirmed | Платеж подтвержден | Email, In-App |
| order_processing | Заказ готовится | In-App |
| order_shipped | Заказ отправлен с трекингом | Email, SMS, Push |
| order_out_for_delivery | На доставке | Push |
| order_delivered | Заказ доставлен | Email, Push |
| order_cancelled | Заказ отменен | Email, In-App |
| payment_failed | Платеж не прошел | Email, SMS |
| payment_retry | Напоминание о повторном платеже | |
| refund_initiated | Рефанд начат | Email, In-App |
| refund_completed | Рефанд обработан | Email, In-App |
Уведомления MLM комиссий
| Тип | Описание | Каналы |
|---|---|---|
| commission_pending | Комиссия рассчитана | In-App |
| commission_approved | Комиссия одобрена | Email, In-App |
| commission_paid | Комиссия зачислена | Email, Push, In-App |
| commission_reversed | Комиссия отменена | Email, In-App |
| weekly_earnings | Еженедельная сводка заработка | |
| monthly_earnings | Ежемесячный отчет о доходах |
Уведомления MLM выплат
| Тип | Описание | Каналы |
|---|---|---|
| payout_requested | Запрос на выплату подан | |
| payout_approved | Выплата одобрена | Email, In-App |
| payout_processing | Выплата обрабатывается | In-App |
| payout_completed | Выплата отправлена | Email, SMS, In-App |
| payout_rejected | Выплата отклонена | Email, In-App |
Уведомления MLM рангов
| Тип | Описание | Каналы |
|---|---|---|
| rank_promotion | Ранг повышен | Email, Push, In-App |
| rank_demotion_warning | Предупреждение о понижении | Email, In-App |
| rank_demoted | Ранг понижен | Email, In-App |
| rank_qualification_progress | Обновление прогресса | In-App |
Уведомления MLM рефералов
| Тип | Описание | Каналы |
|---|---|---|
| new_referral | Регистрация нового реферала | Email, Push, In-App |
| referral_activated | Реферал сделал первую покупку | Push, In-App |
| team_member_achievement | Достижение члена команды | In-App |
Уведомления инвестиций
| Тип | Описание | Каналы |
|---|---|---|
| investment_submitted | Участие подано | |
| investment_approved | Инвестиция одобрена | Email, In-App |
| investment_activated | Инвестиция активна | Email, Push, In-App |
| investment_rejected | Инвестиция отклонена | Email, In-App |
| returns_distributed | Доходность зачислена | Email, In-App |
| investment_matured | Инвестиция погашена | Email, Push, In-App |
| withdrawal_requested | Вывод запрошен | |
| withdrawal_completed | Вывод обработан | Email, SMS, In-App |
| portfolio_update | Ежемесячная сводка портфеля |
Ограничение частоты и троттлинг
Лимиты по каналам
| Канал | Лимит на пользователя | Глобальный лимит |
|---|---|---|
| 20/час | 100/секунду | |
| SMS | 5/час | 10/секунду |
| Push | 50/час | 1000/секунду |
| In-App | Без лимита | N/A |
Тихие часы
Пользователи могут настроить тихие часы:
- Уведомления откладываются во время тихих часов
- Доставляются по окончании тихих часов
- Уведомления безопасности игнорируют тихие часы
Группировка уведомлений
Низкоприоритетные уведомления могут группироваться:
- Уведомления об ожидающих комиссиях
- Обновления активности in-app
- Маркетинговые коммуникации
Бизнес-правила и инварианты
Правила доставки
- Уведомления безопасности нельзя отключить
- У пользователя должен быть верифицированный канал для получения уведомлений
- Неудачные доставки повторяются до 3 раз
- Тихие часы соблюдаются, кроме предупреждений безопасности
- Лимиты частоты применяются на пользователя и глобально
Правила настроек
- Новые пользователи получают все уведомления включенными по умолчанию
- Маркетинг отключен по умолчанию (opt-in)
- Хотя бы один канал должен быть включен для транзакционных
- Настройки хранятся для каждого типа уведомления
Правила шаблонов
- Все шаблоны должны иметь резервную локаль
- Переменные должны быть санитизированы перед рендерингом
- URL должны быть абсолютными и использовать HTTPS
- Чувствительные данные не логируются в записях доставки
Точки интеграции
Потребляет от других модулей
| Событие | Источник | Тип уведомления |
|---|---|---|
| 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 |
Предоставляет другим модулям
| Интерфейс | Назначение |
|---|---|
| INotificationService | Отправка произвольных уведомлений |
| IPreferenceService | Проверка/обновление настроек пользователя |