← Notifications

Диспетчер

notifications · workzone

Как событие из любого модуля доходит до адресата: единый диспетчер собирает событие, разводит его по двум моделям адресации и каналам, журналирует доставку. Схема каналов, маршрутов и ленты — в модели данных; экран настроек — в Admin Panel.

1 Диспетчер источник → адресация → каналы → доставка
1 Источник модуль зовёт диспетчер в core
2 Событие строка notifications
3 Адресация broadcast / targeted
4 Веер маршрут × канал → deliveries
5 Доставка in-app сразу + push · email/webhook в очередь
Источник поднимает событие, не шлёт сам
Модули не знают про email или Slack. При сбое, пороге или governance-действии они зовут диспетчер в core — тот пишет строку notifications и дальше ведёт доставку сам. Рождение события и доставка — разные заботы, циклов между модулями нет.
  • Пишут: Harvester · Auth · Agent Engine · Knowledge Store · Admin — полный перечень в каталоге ниже.
  • Строка: тип · severity · источник · ссылка на сущность · target_user_id (при targeted).
Две модели адресации — по типу события → Колонка target_user_id
Тип события несёт свою модель адресации; диспетчер ветвится одним условием — заполнен ли target_user_id. Старые админские типы всегда пишут NULL — их путь нетронут.
Broadcast
target_user_id IS NULL
Адресаты — срез по роли (owner / admin, status=active). Платформенные сигналы организации.
sync security budget system discovery
Targeted
target_user_id = X
Единственный адресат — конкретный пользователь (владелец агента, субъект записи). Любая роль, включая member.
agent account
Веер по каналам через маршруты → Матрица → Cache & Workers
Диспетчер берёт notification_routes этого типа и на каждый включённый маршрут заводит строку notification_deliveries.
  • Маршрут enabled=true — иначе тип по этому каналу не уходит. Отдельного «выключателя типа» нет: погашены все маршруты — тип не идёт никому.
  • Канал enabled=false пропускается целиком — проверенный webhook держат про запас.
  • Замок: in_app × security и in_app × sync под locked=true — критичный тип нельзя обнулить, он всегда виден в ленте.
  • Личные каналы (in-app, email) ещё сверяются с настройками адресата.
in-appпишется сразу и шлёт сигнал в pub/sub — колокольчик обновляется мгновенно (push); до клиента сигнал доезжает по платформенному потоку живых обновлений.
email · webhookв очередь SAQ — ретраи и тротлинг, чтобы всплеск не забил доставку.
Адресаты минус личный opt-out → Личные настройки
Адресаты не хранятся списком — диспетчер вычисляет их на лету и снимает тех, кто отписался.
  • Broadcast → все users с ролью owner / admin, динамический срез status = active, не ручной перечень.
  • Targeted → один адресат, target_user_id.
  • Личный opt-out: по каждому сверяется notification_prefs (in_app_enabled, email_enabled) по типу; строки нет — дефолт каталога (у личных типов email выключен, opt-in).
  • Замков на личном уровне нет — отписаться можно от любого типа; организационный замок держит in-app security / sync лишь на уровне организации (что нельзя выключить).
  • Webhook персон не имеет — общий endpoint команды; личные настройки не влияют, targeted по нему не идёт.
Дедуп и тротлинг
Однотипные события в окне схлопываются в одно уведомление с растущим счётчиком — не N писем на каждую неудачу.
  • Ключ дедупа: конкретное событие (не категория event_type) + затронутая сущность (source_ref); для targeted — плюс адресат.
  • Раздельно: «источник отвалился» и «серия сбоев» остаются разными уведомлениями.
  • Окно и пороги в v1 фиксированные; тонкая настройка на инстанс — v2.
Payload вебхука — по пресету канала → Каналы
preset канала выбирает форму тела POST: Slack получает свой формат сообщения, generic — нейтральный JSON для любого приёмника (свой бот, n8n, Teams через Power Automate Workflow):
{ // generic preset — нейтральный JSON "event": "sync.failure_series", "severity": "critical", "title": "Источник Jira: 5 сбоев подряд", "source": "harvester", "source_ref": "source/42", "ts": "2026-05-27T14:30:00Z" }
  • Endpoint и secret (url_enc, secret_enc) — write-only: в UI и export не возвращаются.
  • «Test» шлёт это же тело с фиктивным событием.
  • Только broadcast идёт по вебхукам — targeted-события личные, каналом команды не расходятся.
2 Каталог событий что поднимает уведомление · по типам
Админ события broadcast → администраторам
Событие Источник Severity Условие
Sync
Серия сбоев прогона harvester critical несколько sync_runs.state=failed подряд по источнику
Источник отвалился harvester critical проба источника → last_probe_status ≠ ok (health error)
Прогон с потерями harvester warning succeeded при error_count > 0 (часть в DLQ)
DLQ накапливается v2 harvester warning хвост dead-letter растёт сверх порога
Security
Перебор пароля auth critical ≥ 10 неудачных входов на аккаунт / 15 мин
Смена ролей auth critical изменён users.role (owner / admin / member)
API-ключ истекает auth warning за 7 дней до expires_at
Последний Owner v2 auth warning в системе остался один Owner — риск блокировки
Budget
Порог расходов AI admin critical SUM(cost) за месяц > ai_monthly_budget
System
Провайдер недоступен admin critical проверка соединения провайдера → error (здоровье, не расход)
Сервис degraded / down v2 admin critical postgres / redis / n8n не отвечают штатно
Backup провалился knowledge_store critical плановый снимок KS завершился ошибкой
Curation Pass упал knowledge_store warning curation_runs.state=failed
Переэмбеддинг затянулся v2 knowledge_store warning прогон после смены модели дольше ожидаемого
Storage у предела v2 admin warning PG / pgvector приблизились к лимиту
Discovery
Новый контейнер v2 harvester info объект за пределами разрешённого scope источника — с действием «в scope»
Общие события targeted → пользователю
Событие Источник Severity Условие
Agent · targeted → владелец · governance
Прогон провалился agent_engine warning agent_runs.state=failed (reason error / iteration_cap / stale)
Недельный бюджет исчерпан agent_engine info agent_runs.state=skipped, reason=budget_exceeded
Агент приостановлен админом agent_engine info agents.admin_pausedtrue
Модель агента снята agent_engine warning agents.model_idNULL (модель убрана из списка)
Прогон завершён успешно v2 agent_engine info доставка выхода прогона — отложена вместе с доставкой в чат-тред
Account · targeted → пользователь
Роль изменена админом auth info audit_log смены роли (meta old→new)
Выдан временный пароль auth warning users.must_change_passwordtrue (сброс админом)