Уведомления и коммуникации
Версия: 1.0 Дата: 26.04.2026 Статус: Готов к обсуждению
Назначение документа
Документ определяет канал коммуникации платформы (notification and communication contour) Vitiana — многоканальный слой доставки сообщений всем участникам (конечным клиентам, агентам агентств, партнёрам, поставщикам, внутренним операторам). Включает:
- Каноничную модель уведомлений:
NotificationTemplate,NotificationDelivery,RecipientPreferences,WebhookSubscription,ConsentRecord. - Классы уведомлений: транзакционные / операционные / маркетинговые / партнёрские / системные.
- Каналы доставки: электронная почта (email), SMS, push, in-app, webhook, голосовой звонок (фаза 4).
- Абстракцию провайдеров каналов через адаптер (как в платежах — без захвата конкретным провайдером).
- Многоязычные шаблоны и локализацию.
- Гарантии доставки: at-least-once с идемпотентностью, обработка отказов получателя.
- Защиту от спама и злоупотреблений: rate-limiting per recipient, capping, окна тишины.
- Согласие и отписки: журнал согласия (consent log), раздельные потоки для транзакционных и маркетинговых уведомлений.
- Партнёрские webhook'и — детальная стыковка с партнёрской поверхностью.
- Интеграцию с платформой данных, ML-платформой, платформой экспериментов.
- Учёт потребления (доставки уведомлений как метрика тарификации).
- Фазы развёртывания.
Документ читается после:
- Каноничная доменная ось — каноничные сущности, события которых порождают уведомления.
- Программный интерфейс как продукт — партнёрская сторона webhook-доставок.
- Платёжный домен, Жизненный цикл пост-бронирования, Поиск и обнаружение — источники событий, требующих уведомлений.
- Соответствие требованиям регуляторов — правила согласия, маркетинговые ограничения, общее регулирование защиты данных.
- Каталог совместимости webhook — правила внешних async-уведомлений.
В корневых документах зафиксировано что платформа должна уведомлять и кому. Этот документ описывает как — каноничные сущности, потоки доставки, защиту, согласие, фазы.
Канал коммуникации — критическая инфраструктура взаимодействия платформы с миром. Без него платежи не подтверждаются клиенту, бронирования не отображаются партнёрам, отмены не доходят до конечных клиентов, операционные команды не получают сигналов об инцидентах.
Правило 00000 (платформа главенствует над поставщиками) применяется здесь напрямую: каноничная модель уведомлений не подгоняется под форматы или возможности конкретного провайдера каналов. Платформа задаёт каноничную модель сообщения; конкретные провайдеры (email-провайдер, SMS-провайдер, push-провайдер) подключаются как адаптеры. Любой провайдер заменяем без изменения каноничной модели.
Главное решение
Уведомления — единая многоканальная инфраструктура с каноничной моделью сообщения, абстракцией провайдеров каналов, единой семантикой согласия и единой системой учёта.
Это означает:
- Одно событие — много каналов — событие
booking.confirmedможет породить email конечному клиенту, push в мобильное приложение, webhook партнёру, in-app уведомление агенту агентства одновременно. Маршрутизация — через каноничные правила, не через дублирование кода. - Каноничная модель шаблонов — каждое сообщение определяется через
NotificationTemplateс многоязычным содержимым и параметризацией. Шаблоны версионируются. - Абстракция провайдеров — каждый канал работает через адаптер. Поддержка нескольких провайдеров одновременно (например, два провайдера email с автоматическим резервированием).
- Согласие — первоклассная сущность — каждый получатель имеет журнал согласия с разрешением по типам уведомлений. Транзакционные и маркетинговые — раздельные правила.
- Защита от злоупотреблений — rate-limiting per recipient, capping (максимум N сообщений в день), окна тишины (quiet hours), исключения по чрезвычайным ситуациям.
- Идемпотентность доставки — повторная попытка отправки одного и того же логического уведомления (через
delivery_idempotency_key) не приводит к дубликату. - Учёт потребления — каждая доставка учитывается; партнёрские webhook'и — метрика тарификации.
- Аудит — каждое решение «отправить или не отправить», «доставлено или нет» — журналируется.
Каноничная модель уведомлений
Главные сущности
NotificationTemplate — шаблон уведомления
Сущность, представляющая именованный шаблон сообщения, привязанный к семейству событий и каналу.
{
template_id: UUID,
template_key: string,
template_namespace: string,
notification_class: enum,
trigger_event_family: string,
channel: enum,
language_payloads: object,
parameters: array,
consent_class: enum,
rate_limit_class: enum,
retention_class: string,
schema_version: string,
is_active: boolean,
owners: array,
created_at: timestamp,
updated_at: timestamp
}
Поля:
template_key— уникальный ключ шаблона, напримерbooking.confirmed.client.email.template_namespace— пространство имён (booking/payment/post_booking/usage_governance/marketing/system).notification_class— класс уведомления (см. ниже):transactional/operational/marketing/partner_integration/system.trigger_event_family— семейство событий, порождающих уведомление (например,booking.confirmation).channel— канал доставки (email/sms/push/in_app/webhook/voice_call).language_payloads— объект с многоязычным содержимым (тема + тело + параметры стилизации) для каждого языка из базового набора.parameters— список параметров, подставляемых в шаблон при генерации сообщения, с типами и валидацией.consent_class— какой класс согласия требуется для отправки этого шаблона (см. секцию о согласии).rate_limit_class— класс ограничения скорости (см. секцию о защите от злоупотреблений).retention_class— срок хранения журналов доставки этого шаблона.schema_version— версия схемы шаблона, эволюционирует по тем же правилам, что асинхронные контракты.
NotificationDelivery — доставка уведомления
Сущность, представляющая конкретную попытку доставки одного шаблона одному получателю.
{
delivery_id: UUID,
template_id: UUID,
template_version: string,
recipient_type: enum,
recipient_hash: string,
recipient_address_token: string,
channel: enum,
selected_provider: string,
provider_delivery_id: string,
state: enum,
rendered_subject: string,
rendered_body_summary: string,
parameters_snapshot: object,
language: string,
delivery_idempotency_key: string,
attempts: array,
consent_record_id: UUID,
experiment_assignment: object,
tenant_id: UUID,
trigger_event_id: string,
created_at: timestamp,
delivered_at: timestamp,
failed_at: timestamp
}
Поля:
recipient_type— тип получателя (end_client/partner_user/agency_user/supplier_contact/internal_operator/partner_webhook_endpoint).recipient_hash— анонимизированный идентификатор получателя для аналитики (не сам адрес).recipient_address_token— токенизированный адрес получателя (не сам адрес — почта или телефон лежат в защищённом хранилище контактов, а здесь — ссылка). Это снижает blast-радиус компрометации.selected_provider— какой провайдер канала был выбран по политике маршрутизации.provider_delivery_id— внешний идентификатор у провайдера для трассировки.state— состояние доставки (см. ниже).rendered_subjectиrendered_body_summary— отрендеренные тема и краткая выдержка тела (полное тело в ограниченном хранении или в blob storage, не в основной БД для приватности и объёма).parameters_snapshot— снимок параметров, использованных при генерации.delivery_idempotency_key— ключ идемпотентности (для дедупликации доставок одного и того же логического уведомления).consent_record_id— ссылка на запись согласия, разрешающую эту доставку.experiment_assignment— если доставка попала в эксперимент A/B, тут отметка.trigger_event_id— событие, которое триггернуло уведомление.
RecipientPreferences — предпочтения получателя
Сущность, представляющая настройки уведомлений конкретного получателя.
{
preferences_id: UUID,
recipient_type: enum,
recipient_hash: string,
language: string,
timezone: string,
channel_preferences: object,
notification_class_preferences: object,
quiet_hours: object,
global_unsubscribe: boolean,
marketing_consent_state: enum,
updated_at: timestamp
}
Поля:
channel_preferences— какие каналы предпочитает получатель (например, для критических уведомлений — SMS + email; для маркетинговых — только email).notification_class_preferences— настройки по классам (можно отключить операционные при сохранении транзакционных).quiet_hours— окна тишины (по умолчанию22:00–08:00локального времени, но получатель может изменить или отключить).global_unsubscribe— глобальная отписка от всех маркетинговых уведомлений.marketing_consent_state— состояние согласия на маркетинг (granted/revoked/pending).
WebhookSubscription — подписка на webhook
Сущность, представляющая подписку партнёра на канал webhook (продолжение партнёрской модели из Программный интерфейс как продукт).
{
subscription_id: UUID,
tenant_id: UUID,
partner_id: UUID,
webhook_endpoint_url: string,
signature_secret_token: string,
subscribed_event_families: array,
retry_policy: object,
state: enum,
created_at: timestamp,
last_successful_delivery_at: timestamp,
consecutive_failures: integer
}
Поля:
webhook_endpoint_url— URL партнёрского обработчика, проверенный платформой при создании.signature_secret_token— секрет для подписи доставок (HMAC), хранится отдельно в защищённом хранилище.subscribed_event_families— список семейств событий, на которые партнёр подписан.retry_policy— политика повторов при отказе (количество попыток, экспоненциальный откат, максимальное окно).state— состояние (active/paused_due_to_failures/disabled_by_partner/revoked_by_platform).consecutive_failures— счётчик последовательных отказов; при превышении порога подписка автоматически приостанавливается.
ConsentRecord — запись согласия
Сущность, представляющая факт согласия получателя на конкретный класс уведомлений в конкретный момент.
{
consent_id: UUID,
recipient_type: enum,
recipient_hash: string,
consent_class: enum,
state: enum,
legal_basis: enum,
granted_at: timestamp,
revoked_at: timestamp,
source: string,
evidence_reference: string
}
Поля:
consent_class— класс (например,marketing_email,marketing_sms,transactional— для последнего согласие неявное и не требуется отдельно).legal_basis— правовое основание по общему регулированию защиты данных (consent— явное согласие;contract— договорное основание;legitimate_interest— обоснованный интерес).source— источник (signup_form/cms_admin/partner_api/bulk_import/cms_unsubscribe_link).evidence_reference— ссылка на доказательство согласия (для аудита регулятора).
Состояния доставки
queued → routing_provider → in_flight → delivered
↓
soft_failed → retried → delivered
↓
hard_failed (terminal)
delivered → bounced (post-delivery)
delivered → opened (поведенческое для email и push)
delivered → clicked (поведенческое)
delivered → unsubscribed (если получатель отписался по ссылке)
queued— поставлено в очередь на обработку.routing_provider— выбирается провайдер канала по политике маршрутизации.in_flight— отправлено провайдеру, ожидает подтверждения.delivered— провайдер подтвердил приём.soft_failed— временная ошибка (rate limit на стороне провайдера, временная недоступность). Будет повторная попытка.hard_failed— терминальная ошибка (адрес не существует, отписавшийся, чёрный список). Повторов нет.bounced— отказ доставки post-factum (например, для email — отказ MTA).opened/clicked— поведенческие события (для каналов, поддерживающих метрику открытия и кликов).
Связь с другими каноничными сущностями
NotificationTemplate.trigger_event_family— каноничные семейства из Первоначальная таксономия событий.NotificationDelivery.tenant_id— тенант, инициировавший событие.NotificationDelivery.experiment_assignment— связь с Платформа экспериментов и A/B-тестирования.WebhookSubscription— операционная сторона партнёрских подписок из Программный интерфейс как продукт.ConsentRecord— связан с правами субъекта данных в Соответствие требованиям регуляторов.RecipientPreferences— переиспользуется во всех поверхностях взаимодействия для применения политики тишины и предпочтений.
Классы уведомлений
Транзакционные (transactional)
Назначение: прямое подтверждение действия, инициированного получателем, или критическое уведомление об изменении.
Примеры:
- Подтверждение бронирования конечному клиенту.
- Подтверждение платежа.
- Уведомление об отмене бронирования.
- Сброс пароля.
- Подтверждение изменения учётных данных.
Правила:
- Согласие не требуется отдельно — отправка обусловлена явным действием получателя или договорным обязательством платформы.
- Окна тишины не применяются для критических (транзакционные могут отправляться в любое время).
- Отписка запрещена — получатель не может отказаться от транзакционных уведомлений (это обусловлено договорными обязательствами).
- Высокий приоритет в очереди доставки.
- Защита от deduplication ошибок — критичная (двойная отправка одного подтверждения — маленький инцидент, но недоставка — большой).
Операционные (operational)
Назначение: информирование о ходе работы платформы, не связанное с конкретной транзакцией получателя.
Примеры:
- Уведомление партнёра о приближении к лимиту тарифа.
- Уведомление партнёра о превышении лимита.
- Уведомление о плановых работах.
- Уведомление о смене политики платформы.
- Уведомление об операционных инцидентах (только для пострадавших тенантов).
Правила:
- Согласие не требуется отдельно (часть условий обслуживания).
- Окна тишины применяются для не-критических.
- Отписка ограниченно возможна (можно отписаться от плановых работ, но не от уведомлений о превышении лимита).
- Средний приоритет в очереди.
Маркетинговые (marketing)
Назначение: продвижение возможностей платформы, новые предложения, акции.
Примеры:
- Рассылка о новых функциях платформы.
- Промо-предложения тарифов.
- Рекомендации новых поставщиков для тенантов.
Правила:
- Согласие явное и отдельное — без
ConsentRecordсоstate: grantedотправка запрещена. - Глобальная отписка мгновенно останавливает все маркетинговые сообщения этому получателю.
- Окна тишины обязательны.
- Capping — не более N сообщений в неделю или в месяц на получателя.
- Низкий приоритет в очереди.
- Запрет на отправку получателям из юрисдикций с особыми требованиями (например, без явного opt-in согласия в Европейском Союзе).
Партнёрские интеграционные (partner integration)
Назначение: уведомления партнёрам через webhook о событиях, релевантных их интеграциям.
Примеры:
- Все события, перечисленные в Каталог совместимости webhook: booking confirmed, post-booking changes, quote lifecycle, usage governance.
Правила:
- Согласие через подписку (
WebhookSubscriptionпартнёра). - Гарантия доставки at-least-once с идемпотентностью на стороне партнёра.
- Подпись обязательна (HMAC).
- Защита от deduplication ошибок через
delivery_idempotency_key. - Учёт потребления — каждая доставка считается метрикой
webhook_deliveriesдля тарификации. - Автопауза при последовательных отказах партнёра.
Системные (system)
Назначение: внутренние уведомления операционным командам платформы.
Примеры:
- Алерты об инцидентах.
- Уведомления о деградации защитных метрик в эксперименте.
- Алерты о превышении расходов на ML.
- Уведомления о выявленных аномалиях.
Правила:
- Согласие через роли — внутренние сотрудники получают уведомления по своим ролям, не отдельно подписываются.
- Окна тишины не применяются для критических алертов.
- Через каналы оповещения операционных команд (Slack, PagerDuty, internal email) — отдельные адаптеры.
Каналы доставки
Email
Главный канал для большинства классов уведомлений к конечным клиентам, агентам и партнёрам.
Особенности:
- Богатое содержимое (HTML), вложения возможны.
- Поведенческие метрики (открытия, клики).
- Высокий процент доставки в боевом режиме.
- Защита от попадания в спам (SPF, DKIM, DMARC).
Адаптер провайдеров:
- На фазе 2 — один провайдер для базовой доставки (рассматриваются Postmark, SendGrid, AWS SES, Mailgun — выбор открытая развилка).
- На фазе 3 — несколько провайдеров с автоматическим резервированием при деградации.
SMS
Канал для критических уведомлений или для каналов, где email медленнее.
Особенности:
- Высокая стоимость на сообщение (десятки центов в зависимости от страны).
- Ограничение длины (160 символов в одном сегменте).
- Высокая скорость доставки.
Применение:
- Усиленная аутентификация клиента (3D Secure альтернатива через SMS-код).
- Подтверждение бронирования (опционально).
- Критические алерты партнёрам (наряду с email).
Адаптер провайдеров:
- Региональные провайдеры обязательны (Украина, Казахстан имеют местные правила и тарифы).
- Twilio, Vonage, MessageBird — кандидаты для основного покрытия Европейского Союза.
Push (мобильное приложение)
Применение: для конечных клиентов потребительской витрины при наличии мобильного приложения (фаза 3+).
Особенности:
- Нулевая стоимость доставки (через Apple Push Notification Service и Firebase Cloud Messaging).
- Поведенческие метрики.
- Требует согласия пользователя в приложении.
In-app
Применение: в партнёрской консоли, в интерфейсе для агентств, в потребительской витрине.
Особенности:
- Доставка через активную сессию.
- Журнал в личном кабинете для всех типов уведомлений (даже при отписке от email).
- Никаких ограничений по объёму.
Webhook
Применение: партнёрские интеграции через программный интерфейс.
Особенности:
- Машинно-читаемый формат (JSON по AsyncAPI спецификации).
- Подпись HMAC.
- Гарантии доставки at-least-once.
- Учёт каждой доставки.
Подробности — в Каталог совместимости webhook.
Голосовой звонок (фаза 4)
Применение: для критических случаев (потеря связи с партнёром при крупном инциденте), для усиленной аутентификации в случаях недоступности SMS, для корпоративной поддержки на тарифе Enterprise.
Адаптер провайдеров:
- Twilio Voice, AWS Connect, или другие.
Поток обработки уведомлений
[Источник события] публикует доменное событие
↓
Сервис уведомлений подписан на семейства событий
↓
Для каждого получателя, релевантного событию:
↓
├── Определение получателей (recipient resolver)
├── Получение RecipientPreferences
├── Получение ConsentRecord для класса уведомлений
├── Выбор шаблона (NotificationTemplate) для класса + канала + языка
├── Применение rate-limiting и capping
├── Применение окон тишины (для не-критических)
↓
├── Если разрешено — генерация рендеринг + создание NotificationDelivery
├── Если нет — пропуск с логом причины
↓
Очередь к адаптеру канала
↓
Выбор провайдера по политике маршрутизации
↓
Отправка через провайдер
↓
├── Успех — NotificationDelivery в delivered
├── Soft fail — повтор по retry policy
└── Hard fail — terminal failure
↓
Публикация события NotificationDelivery в платформу данных
↓
Учёт потребления (для партнёрских webhook)
↓
Поведенческая метрика (открыто, кликнуто) при наличии
Согласие и отписки
Главный принцип
Согласие — первоклассная сущность платформы, не побочная информация в учётной записи получателя.
Журнал согласия (consent log)
Каждое изменение согласия записывается в ConsentRecord без удаления предыдущих записей. Это даёт:
- Полный исторический контекст для аудита регулятора.
- Доказательную базу при разрешении споров.
- Возможность восстановить согласие на конкретный момент времени для разбора инцидента.
Срок хранения — 10 лет (compliance_log retention class из Платформа данных и захват событий).
Раздельные потоки
- Транзакционные — без отдельного согласия (договорная основа).
- Операционные — без отдельного согласия (часть условий обслуживания), но с возможностью ограниченной отписки.
- Маркетинговые — обязательное явное согласие (
legal_basis: consent), мгновенная отписка по ссылке в каждом сообщении.
Запрет смешения каналов согласия
Подтверждение согласия на маркетинг в одном канале (email) не означает согласия в другом (SMS). Согласие отдельное на каждый класс канала.
Запрет тёмных паттернов
- ❌ Предзаполненный чекбокс согласия — запрещён общим регулированием защиты данных.
- ❌ Скрытое согласие в условиях обслуживания — недопустимо для маркетингового класса.
- ❌ Отписка только через сложную процедуру (контактная форма) — отписка должна быть в один клик в каждом маркетинговом сообщении.
- ❌ Принуждение получателя восстановить согласие после отписки.
Право на полную отписку
Получатель может полностью отписаться от всех маркетинговых уведомлений через один клик. Это:
- Создаёт
ConsentRecordсstate: revokedдля всех маркетинговых классов. - Устанавливает
RecipientPreferences.global_unsubscribe = true. - Применяется мгновенно — все маркетинговые уведомления, ещё не отправленные, отменяются.
Право быть забытым
При запросе на удаление от субъекта данных (по общему регулированию защиты данных):
ConsentRecordпомечается какstate: revokedдля всех классов.RecipientPreferencesанонимизируется.NotificationDeliveryжурнал анонимизируется (хеш получателя заменяется на специальныйforgottenхеш с сохранением счётчиков для compliance).- Адресная книга получателя в защищённом хранилище удаляется.
Защита от спама и злоупотреблений
Многоуровневое ограничение скорости
Платформа применяет:
- На получателя — максимум N сообщений в час, день, неделю на получателя по каждому классу. Защищает получателя от перегрузки.
- На тенанта — максимум N маркетинговых сообщений в день на тенанта. Защищает от ошибок массовой рассылки.
- Глобальное — максимум N сообщений в секунду через всю платформу. Защищает инфраструктуру.
- На провайдера — учитывает лимиты провайдеров каналов. Адаптер автоматически распределяет нагрузку при приближении к лимиту.
Capping
Для маркетинговых уведомлений — верхний предел числа сообщений на получателя в неделю или в месяц, независимо от числа кампаний.
Окна тишины (quiet hours)
Для не-критических уведомлений (всех маркетинговых, операционных не-критических) — запрет отправки в локальное время получателя:
- По умолчанию —
22:00–08:00. - Получатель может изменить или отключить через
RecipientPreferences.quiet_hours. - Транзакционные уведомления игнорируют окна тишины.
- Системные критические алерты игнорируют окна тишины.
Защита от петель
Если уведомление повторно порождается обработчиком, ответившим на первое уведомление — обнаруживается петля через цепочку trigger_event_id. Платформа разрывает петлю и журналирует инцидент.
Защита от перенасыщения
При обнаружении внезапного всплеска уведомлений (в N раз больше базовой линии за последний час) — платформа автоматически приостанавливает не-критические уведомления на короткий период и эскалирует операционной команде.
Идемпотентность доставки
Ключ идемпотентности
Каждая логическая доставка имеет delivery_idempotency_key — сгенерированный из:
- Уникального идентификатора события-источника.
- Идентификатора шаблона.
- Идентификатора получателя.
- Времени окна (для повторных попыток в течение разумного окна).
Повторная попытка отправить ту же логическую доставку — обнаруживается платформой и не приводит к дубликату на стороне получателя.
Дедупликация
Платформа поддерживает индекс выполненных доставок по delivery_idempotency_key за окно дедупликации (типично 24 часа). Запрос на доставку с уже виденным ключом возвращает существующий delivery_id, не создаёт новую доставку.
Идемпотентность на стороне провайдера
Каждый адаптер провайдера передаёт ключ идемпотентности провайдеру (для тех, кто его поддерживает — Postmark, SendGrid). Это даёт двойную защиту: даже если на стороне платформы дубликат прошёл, провайдер его не отправит.
Многоязычные шаблоны и локализация
Базовый набор языков
С фазы 1 — базовый набор языков первой волны: украинский, русский, чешский, польский, английский, казахский. Каждый шаблон должен иметь содержимое на всех языках или резервный fallback на английский.
Структура language_payloads
Поле language_payloads шаблона хранит для каждого языка:
- Тему (subject) для email.
- Тело (body) с поддержкой Markdown или HTML.
- Краткую выдержку (summary) для предпросмотра.
- Параметры стилизации, специфичные для языка (например, направление текста для языков справа налево, специфические форматы дат).
Локализация дат, валют, чисел
При генерации сообщения:
- Даты форматируются по локали получателя (
ru—5 июня 2026;cs—5. června 2026;en—June 5, 2026). - Валюты — с символом и формой по локали получателя.
- Числа — с разделителями, принятыми в локали.
Подробности — в Интернационализация и локализация.
Резервный язык
Если шаблон не имеет контента на языке получателя — fallback на английский. Журналируется как language_fallback_used для последующего восполнения переводов.
Учёт потребления
Доставки уведомлений — источник метрик для тарификации:
webhook_deliveries— основная партнёрская метрика, учитывается в Учёт потребления и квоты.email_deliveries— операционная метрика для собственного канала, влияет на расходы платформы.sms_deliveries— операционная метрика, существенный коммерческий фактор.push_deliveries— операционная метрика.
Каждая доставка публикует событие в платформу данных для аналитики и тарификации.
Партнёрские webhook'и — детальная стыковка
Управление подписками
Партнёр управляет подписками через:
- Партнёрскую консоль — графический интерфейс выбора семейств событий (см. Программный интерфейс как продукт).
- Программный интерфейс — для автоматизации (создание, обновление, удаление подписок).
Проверка endpoint при создании
Перед активацией подписки платформа отправляет тестовый webhook (webhook.subscription.test) на указанный URL. Endpoint должен ответить кодом 200 в течение 30 секунд. Без подтверждения подписка не активируется.
Подпись доставки
Каждая доставка содержит заголовок с HMAC-подписью:
X-Vitiana-Signature: t=<timestamp>,v1=<hmac_sha256_hex>
Партнёр проверяет подпись через секрет, выданный при создании подписки. Подпись защищает от:
- Подделки доставок.
- Атак повторного воспроизведения (через timestamp).
Политика повторов
При отказе партнёрского endpoint:
- Экспоненциальный откат — 1 минута, 5, 15, 60, 6 часов, 24 часа.
- Максимум 7 попыток — после этого доставка помечается как
hard_failed. - Окно повторов — 72 часа максимум с момента создания доставки.
Автоматическая пауза подписки
При 20 последовательных отказов подписка автоматически приостанавливается в paused_due_to_failures. Партнёр получает уведомление по email и в консоли с инструкцией по восстановлению.
Журнал доставок в партнёрской консоли
Партнёр видит:
- Каждую доставку с её состоянием.
- Тело доставки и timestamp.
- Историю попыток.
- Возможность вручную инициировать повторную доставку (replay).
Интеграция с платформой данных
Все доставки публикуются в Платформа данных и захват событий:
fact_notification_deliveries— главная таблица фактов.dim_notification_template— измерение шаблонов.dim_notification_provider— измерение провайдеров каналов.
Метрики, доступные для аналитики:
- Уровень доставки (delivery rate) — доля успешных доставок.
- Уровень открытий (open rate) — для email и push.
- Уровень кликов (click-through rate) — для маркетинговых уведомлений.
- Уровень отписки (unsubscribe rate) — критическая метрика для маркетинга.
- Уровень жалоб на спам (spam complaint rate) — критическая для здоровья отправляющих доменов.
Интеграция с ML-платформой
Применения
- Оптимизация времени отправки (send time optimization) — модель прогнозирует, в какое локальное время получатель с наибольшей вероятностью откроет сообщение. Применяется для маркетинговых уведомлений.
- Персонализация содержимого — модель выбирает оптимальные параметры шаблона (тема, превью, призыв к действию) для каждого получателя.
- Прогнозирование оттока — модель прогнозирует получателей, склонных отписаться, для смягчения частоты.
- Детекция аномального трафика — модель обнаруживает всплески отправок, потенциально указывающие на компрометацию или ошибку.
См. каталог применений в Платформа машинного обучения.
Каноничный путь
Каждое применение ML интегрируется через единое обращение к ML-платформе:
- Получение признаков (features) для конкретного получателя.
- Вызов модели для рекомендации (время / тема / решение «отправить или нет»).
- Журналирование результата как
MlInferenceRequest.
Интеграция с платформой экспериментов
A/B-эксперименты над шаблонами
NotificationTemplate может быть версией варианта эксперимента (см. Платформа экспериментов и A/B-тестирования). Это даёт:
- Сравнение нескольких вариантов темы или тела.
- Измерение влияния на уровень открытий, кликов, конверсии.
- Стандартизированный анализ значимости.
Защита от пересечения
Эксперименты над уведомлениями попадают в отдельный слой в layered experimentation, чтобы не пересекаться с экспериментами над поверхностями.
Защита от сетевого эффекта
Уведомления конечным клиентам через партнёра — потенциальный источник сетевого эффекта (изменение одного уведомления влияет на восприятие платформы партнёром). Эксперименты над такими уведомлениями требуют рандомизации на уровне тенанта (или семейства тенантов), не индивидуума.
События платформы уведомлений
| Событие | Когда | Главные потребители |
|---|---|---|
notification.template.created | Создание шаблона | Контур документации, аудит |
notification.template.deprecated | Шаблон помечен устаревшим | Команды-владельцы зависимых процессов |
notification.delivery.queued | Доставка поставлена в очередь | Контур наблюдаемости |
notification.delivery.sent | Доставка отправлена провайдеру | Контур наблюдаемости |
notification.delivery.delivered | Подтверждение доставки от провайдера | Платформа данных |
notification.delivery.bounced | Отскок (post-delivery отказ) | Контур наблюдаемости, контур здоровья отправляющих доменов |
notification.delivery.opened | Открытие сообщения получателем | Платформа данных, маркетинговая аналитика |
notification.delivery.clicked | Клик в сообщении | Платформа данных, маркетинговая аналитика |
notification.delivery.failed | Терминальный отказ | Контур наблюдаемости, оперативная команда |
notification.consent.granted | Согласие предоставлено | Контур аудита, журнал согласия |
notification.consent.revoked | Согласие отозвано | Контур аудита, мгновенное применение к очередям |
notification.recipient.unsubscribed | Глобальная отписка | Контур аудита, мгновенное применение |
webhook.subscription.created | Создание подписки | Контур аудита |
webhook.subscription.paused_due_to_failures | Авто-пауза подписки | Контур поддержки партнёров, оперативное уведомление партнёру |
notification.spam.complaint_received | Жалоба от провайдера на спам | Срочный алерт оперативной команде |
notification.rate_limit.exceeded | Срабатывание ограничения скорости | Контур наблюдаемости |
notification.surge.detected | Аномальный всплеск | Срочный алерт |
Полная таксономия — в Первоначальная таксономия событий.
Технологический выбор по фазам
| Фаза | SMS | Push | Webhook | Voice | |
|---|---|---|---|---|---|
| Bootstrap | Один провайдер (например, Postmark или AWS SES) | Один провайдер (Twilio для теста) | Не реализован | Базовая внутренняя реализация | Не реализован |
| 2 (Production) | Основной провайдер + правила доставки (SPF, DKIM, DMARC) | Региональные провайдеры для UA, KZ + один EU | Реализация для основной мобильной платформы | Зрелая реализация с retry policy и подписями | Не реализован |
| 3 (Multi-channel) | Несколько провайдеров с резервированием | Многорегиональные провайдеры | Зрелая push-инфра с поведенческими метриками | Расширенная аналитика для партнёров | Базовая голосовая для критических случаев |
| 4 (Multi-region) | Multi-region | Локальные провайдеры в каждой стране | Multi-region | Multi-region | Multi-region |
Конкретный выбор провайдеров — открытая развилка, эскалируется при подходе к фазе 2.
Фазы развёртывания
Фаза Bootstrap (0–6 месяцев)
Что разворачивается:
- Каноничная модель (
NotificationTemplate,NotificationDelivery,RecipientPreferences,WebhookSubscription,ConsentRecord) зафиксирована в схеме хранения. - Один email-провайдер для прототипа.
- Базовые шаблоны для критических транзакционных уведомлений (подтверждение бронирования, подтверждение платежа).
- Внутренние webhook'и для прототипа партнёрской интеграции.
- Базовый журнал согласия.
- Простой rate-limiting на тенанта.
Триггер выхода:
- Готовность к боевому запуску первого тенанта.
- Появление первого партнёра, требующего webhook-интеграцию.
Фаза 2 — Production multi-channel (6–18 месяцев)
Что разворачивается:
- Полная многоканальная инфраструктура (email + SMS + in-app + webhook).
- Несколько провайдеров каналов с автоматическим резервированием.
- Полная политика согласия и отписок.
- Защита от спама и злоупотреблений (rate-limiting, capping, окна тишины).
- Партнёрская консоль управления webhook-подписками.
- Учёт потребления
webhook_deliveriesдля тарификации. - Журнал доставок в партнёрской консоли.
Триггер выхода:
- Появление мобильного приложения (для push).
- Появление маркетинговых кампаний на масштабе.
- Появление первых ML-применений в уведомлениях.
Фаза 3 — Smart notifications (18–30 месяцев)
Что разворачивается:
- Push в мобильном приложении с поведенческими метриками.
- Оптимизация времени отправки (send time optimization) через ML.
- Персонализация содержимого через ML.
- Расширенная аналитика для партнёров.
- A/B-эксперименты над шаблонами.
- Базовый голосовой канал для критических случаев.
Фаза 4 — Multi-region и расширения (30+ месяцев)
Что разворачивается:
- Multi-region инфраструктура.
- Локализованные провайдеры в каждой стране.
- Расширенный голосовой канал с интеграцией с поддержкой.
- Прогнозирование оттока через ML.
- Платформа экспериментов над уведомлениями для крупных корпоративных тенантов.
Архитектурные решения с тезисным обоснованием
Решение 1. Единая многоканальная инфраструктура, не отдельные сервисы для каждого канала
Цель: избежать дублирования логики (согласие, шаблоны, аудит) и обеспечить единую семантику.
Тезисы:
- Согласие, журнал, защита от злоупотреблений — общие для всех каналов. Дублирование разрушает целостность.
- Многоканальные кампании (одно событие порождает email + push) требуют единой координации.
- Современные платформы (SendGrid, Twilio, Adyen Communications) — все построены на единой инфраструктуре. Это база.
Решение 2. Согласие — первоклассная сущность с журналом
Цель: обеспечить compliance и доказательную базу для регулятора.
Тезисы:
- Общее регулирование защиты данных требует доказательную базу согласия. Журнал — единственный способ.
- Без журнала невозможно ответить на запрос регулятора «когда и где этот пользователь дал согласие».
- Журнал согласия — стандарт индустрии для маркетинговых платформ.
Решение 3. Каноничные шаблоны с многоязычной поддержкой
Цель: обеспечить консистентное обслуживание пользователей на всех языках первой волны и упростить добавление новых языков.
Тезисы:
- Маркетплейс программных интерфейсов с географией Восточной Европы и Казахстана требует многоязычность с нулевого дня. Это не «фича на потом».
- Шаблоны с многоязычным содержимым в одной сущности — единственный способ обеспечить парные изменения (когда меняется логика — меняется содержимое на всех языках одновременно).
- Резервный fallback на английский — необходимость для непредвиденных языков.
Решение 4. Идемпотентность доставки как архитектурный закон
Цель: исключить класс дубликатов сообщений на стороне получателя.
Тезисы:
- Дубликат сообщения — серьёзный инцидент (например, дубликат подтверждения платежа создаёт у клиента впечатление двойного списания).
- Идемпотентность через ключ — стандарт индустрии (Stripe, Twilio).
- Архитектурное решение защищает независимо от ошибок в коде.
Решение 5. Партнёрские webhook'и — отдельный класс с собственной семантикой
Цель: обеспечить корректное взаимодействие с партнёрской интеграцией с учётом особенностей машинного канала.
Тезисы:
- Webhook — машинный канал, отличающийся от человеческих по гарантиям (at-least-once вместо exactly-once), формату (JSON вместо HTML), аутентификации (HMAC вместо адреса).
- Объединение с человеческими каналами в одной семантике разрушает свойства каждого.
- Партнёрская подписка как отдельная сущность — стандарт индустрии (Stripe Webhooks, GitHub Webhooks).
Открытые развилки
Развилка 1. Конкретные провайдеры каналов
Email: Postmark vs SendGrid vs AWS SES vs Mailgun. SMS: Twilio vs Vonage vs региональные. Push: только реализация на Apple Push Notification Service и Firebase Cloud Messaging vs дополнительные провайдеры.
Эскалируется: при подготовке к фазе 2 (production launch).
Развилка 2. Глубина партнёрской консоли управления webhook-подписками
Минимальная функциональность (создание/удаление подписки + журнал доставок) vs расширенная (детальная фильтрация событий, замена эмулирования, интерактивный отладчик).
Эскалируется: при оформлении детальной партнёрской консоли в фазе 2.
Развилка 3. Платформа маркетинговых кампаний как отдельный продукт
Расширение базовой платформы маркетинговых уведомлений до полноценной платформы кампаний (сегментация, многошаговые цепочки, A/B-тестирование тем) — открытая возможность фазы 3+.
Эскалируется: при появлении партнёрских запросов или внутренних маркетинговых нужд.
Развилка 4. Голосовой канал — приоритет внедрения
В каких применениях голосовой канал приоритетен: критическая поддержка корпоративных тенантов? Альтернатива SMS для усиленной аутентификации? Зависит от бизнес-приоритетов.
Эскалируется: при подходе к фазе 4.
Развилка 5. Conversational интерфейсы (LLM-основанные)
Conversational уведомления (LLM-основанная переписка с конечным клиентом) — открытая возможность фазы 4 при наличии LLM-инфраструктуры.
Эскалируется: при создании conversational-стратегии в Платформа машинного обучения.
Связанная документация
Корневые архитектурные документы
- Каноничная доменная ось — каноничные сущности, события которых порождают уведомления.
- Поверхности взаимодействия — поверхности, на которых появляются уведомления.
- Платформа как продукт — уведомления как часть продуктового опыта.
- Архитектурный якорь и бизнес-модель — учёт уведомлений как метрика тарификации.
- Операционная ось — наблюдаемость канала коммуникации.
Связанные доменные документы
- Программный интерфейс как продукт — партнёрская сторона webhook-доставок, ограничение скорости.
- Платёжный домен — события платежей, требующие уведомлений.
- Жизненный цикл пост-бронирования — уведомления при отмене, изменении.
- Поиск и обнаружение — уведомления о состоянии поиска для партнёров.
- Платформа данных и захват событий — журнал доставок в DWH.
- Платформа машинного обучения — оптимизация времени отправки, персонализация.
- Платформа экспериментов и A/B-тестирования — A/B над шаблонами.
- Соответствие требованиям регуляторов — общее регулирование защиты данных, согласие, маркетинговые правила.
- Учёт потребления и квоты —
webhook_deliveriesкак метрика тарификации. - Тенантная идентичность и изоляция — изоляция получателей по тенанту.
Документы развития
- Каталог совместимости webhook — правила внешних async-уведомлений; прямой источник для семейств webhook-событий этого документа.
- Скелеты AsyncAPI и event envelopes — формальная спецификация webhook-событий.
- Реестр повторов, очередей мёртвых писем и replay — политики повторов для семейств.
- Первоначальная таксономия событий — таксономия событий уведомлений.
Операционная сторона
- Наблюдаемость и реагирование на инциденты — наблюдаемость канала коммуникации, алерты.
- Дорожная карта инфраструктурного масштабирования — фазы развёртывания инфраструктуры уведомлений.
Архитектурные правила
- Закон 00000 — платформа главенствует над поставщиками — каноничная модель уведомлений не зависит от провайдеров каналов.
- Современные лучшие практики верхнеуровневых платформ — Stripe Webhooks, SendGrid, Twilio как ориентиры.
- Развитие без деградации — фазы как расширение, не миграция.
- Эластичное масштабирование и упаковка по фазам — фазы развёртывания каналов.
- Тезисное обоснование архитектурных решений — формат принятия решений.