Это триггер состояний.
Сущности: оповещение, канал (оповещения), статус доставки, статус обработки, время повторного действия, кол-во повторов
По триггеру создаётся экземпляр сущности "оповещение" и присваивается "канал".
Далее, канальный воркер (каждый воркер для своего канала и они синхронны):
1. забирает пакет оповещений длиной N-штук и проставляет статус: sending
2. пытается отправить.
3. когда всё обработано - проставляет статус обработки, согласно обработке (success,fail,retry + sendAt:timestamp + retryCount++ - сам добавляет в очередь)
4. Когда все отправлено - переходит к выборке следующего пакета данных.
Если есть возможность проверки доставки - поле изменяется с помощью входящего события о доставке (за это отвечает протокол канала доставки).
5. После успешной обработки оповещения (статусы все success), можно или просто "убить" оповещение из очереди или поместить в архивную таблицу оповещений (если этого требует бизнес-процесс).