G-SERVICE Docs
Архитектура ISP (OSS/BSS)

Notification Service

SMS, Email, Push, Telegram — шаблоны, приоритеты, дедупликация, multi-channel delivery.

Notification Service

Bounded Context: Notification & Messaging
Владелец данных: Template, DeliveryLog
Технологии: NestJS (Bun 1.3+), Drizzle ORM, PostgreSQL, ConnectRPC, RabbitMQ, BullMQ, Redis

Ответственность

Notification Service — единая точка отправки уведомлений клиентам и операторам по всем каналам. Аналог встроенных модулей уведомлений в Splynx и Hydra Billing, но вынесен в отдельный сервис для масштабирования и переиспользования.

  • Multi-Channel: SMS (SMPP/HTTP), Email (SMTP/SendGrid), Push (FCM/APNs), Telegram Bot, Webhook. Выбор канала — по предпочтениям клиента или приоритету события.
  • Templates: Шаблонизация сообщений (Handlebars / Nunjucks), локализация (i18next). Шаблоны управляются через CRM-интерфейс без деплоя.
  • Prioritization: Критичные (мгновенно) → обычные (< 5 мин) → batch (1 раз в час). Dunning-уведомления всегда HIGH.
  • Deduplication: Защита от спама — одинаковое уведомление одному клиенту не отправляется дважды за configurable window (по умолчанию 1 час).
  • Delivery Tracking: Статус доставки (sent/delivered/failed/read), retry при ошибке провайдера, fallback на альтернативный канал.
  • Compliance: Уважение opt-out предпочтений клиента (GDPR/ФЗ-152), тихие часы (не отправлять SMS с 22:00 до 08:00).

Типичные триггеры уведомлений (ISP)

СобытиеКаналПриоритетШаблон
Баланс < 0 (dunning soft)SMS + EmailHIGHdunning_soft_warning
Блокировка (dunning hard)SMSHIGHdunning_hard_block
Оплата полученаSMS + PushNORMALpayment_received
Подключение завершеноEmail + SMSNORMALwelcome_connected
Смена тарифаEmailLOWtariff_changed
Выезд монтажника запланированSMSHIGHfsm_scheduled
Счёт сформированEmailLOWinvoice_issued
Массовая аварияSMS + Push + TelegramCRITICALmass_outage

Архитектура

Loading diagram...

ConnectRPC API

service NotificationService {
  rpc Send(NotificationRequest) returns (NotificationResponse);
  rpc ListTemplates(ListTemplatesRequest) returns (ListTemplatesResponse);
  rpc GetDeliveryStatus(GetDeliveryStatusRequest) returns (GetDeliveryStatusResponse);
}
МетодRBACОписание
Sendisp-operator+Ручная отправка (для CRM)
ListTemplatesisp-viewer+Список доступных шаблонов
GetDeliveryStatusisp-viewer+Статус конкретной доставки

Входящие команды (RabbitMQ)

Exchange: notification.commands (Direct)

Routing KeyQueueОписание
send.smsnotification.q.smsОтправка SMS
send.emailnotification.q.emailОтправка Email
send.pushnotification.q.pushОтправка Push
send.telegramnotification.q.telegramОтправка в Telegram

Также потребляет доменные события для автоматических уведомлений:

ExchangeRouting KeyQueueШаблон
customer.eventscustomer.creatednotification.q.customer-createdwelcome_sms
billing.eventspayment.receivednotification.q.payment-receivedpayment_confirmation
billing.eventsbalance.negativenotification.q.balance-negativelow_balance_warning
billing.eventsdunning.stage_changednotification.q.dunningservice_restricted / service_blocked
inventory.eventsresource.exhaustednotification.q.resource-alertops_capacity_alert (→ операторам)

Шаблоны

// src/notification/templates/payment-confirmation.ts
export const paymentConfirmation: NotificationTemplate = {
  id: 'payment_confirmation',
  channel: 'sms',
  body: 'Оплата {{amount}} {{currency}} зачислена на л/с {{accountNumber}}. Баланс: {{balance}}',
};

Шаблоны хранятся в PostgreSQL, кэшируются в памяти. Поддерживают переменные через map<string, string> variables в SendNotificationCommand.

Приоритеты и очереди

PrioritySLAПримерыBullMQ Queue
CRITICAL< 10 секCoA failure, mass outagenotification_critical
HIGH< 1 минDunning block, payment receivednotification_high
NORMAL< 5 минWelcome, tariff changenotification_normal
LOW< 1 час (batch)Промо, newsletternotification_batch

Дедупликация

Защита от повторной отправки одного и того же сообщения:

CREATE TABLE delivery_log (
    id              BIGSERIAL PRIMARY KEY,
    customer_id     UUID NOT NULL,
    template_id     TEXT NOT NULL,
    channel         TEXT NOT NULL,
    dedup_key       TEXT NOT NULL,  -- hash(customer_id + template_id + period)
    status          TEXT NOT NULL,  -- pending / sent / delivered / failed
    provider_id     TEXT,           -- ID от SMS-шлюза
    created_at      TIMESTAMPTZ NOT NULL DEFAULT now(),
    delivered_at    TIMESTAMPTZ,
    UNIQUE (dedup_key)
);

Правило: один template_id для одного customer_id не чаще 1 раза в dedup_window (по умолчанию 1 час).

Background Jobs (BullMQ)

JobРасписаниеОписание
notification.batch_sendКаждый часОтправка LOW-priority уведомлений пакетом
notification.retry_failedКаждые 5 минRetry неудачных доставок (max 3 attempts)
notification.cleanupЕжедневноУдаление старых delivery_log (> 90 дней)

Ссылки:

On this page