ADR-006: WebSocket для уведомлений
- Статус: Принято
- Дата: 16 апреля 2026
- Автор: CTO Agent (KALA-133)
Контекст
В AgentCore уже была WebSocket-инфраструктура для прогресса agent-tasks. Новым продуктовым флоу понадобились realtime-уведомления пользователей про approvals, упоминания и сгенерированные документы. Нужно было выбрать: расширять существующий WebSocket-плагин, добавлять server-sent events или полагаться на REST-polling.
Решение
Добавить /ws/notifications в тот же Fastify WebSocket-плагин.
Канал уведомлений:
- аутентифицируется той же JWT-моделью, что и REST;
- поддерживает query-token или first-message аутентификацию;
- подписывается на notification-события аутентифицированного
userId; - шлёт
notification.created, когда продюсер вызываетemitNotification(); - держит durable-состояние в таблице
notifications.
Рассмотренные альтернативы
Только REST-polling
Отклонено. Polling простой, но добавляет задержку в approval и document-ready флоу и раздувает количество запросов с активных дашбордов.
Отдельный SSE-эндпоинт
Пока отклонено. SSE хорош для server-to-client событий, но в приложении уже есть проверенный WebSocket с аутентификацией. Добавлять ещё один транспорт — это дублировать auth- и lifecycle-логику.
Расширить /ws/agent-tasks
Отклонено. Прогресс agent task привязан к namespace/task scope. Уведомления — к user inbox scope. Разные пути позволяют не смешивать семантику подписок.
Последствия
Плюсы
- Переиспользует существующий WebSocket-плагин и JWT verify-путь.
- Доставка уведомлений привязана к текущей identity пользователя.
- REST inbox остаётся source of truth после переподключения.
- Тесты могут проверять сокет через те же WebSocket-хелперы.
Минусы
- Текущий EventEmitter-бродкаст — in-process.
- Multi-replica production потребует Redis pub/sub или другую shared event bus.
- Клиентам всё равно нужна REST-синхронизация для пропущенных во время disconnect событий.
Заметки по реализации
src/lib/notifications.tsвладеетemitNotification()иsubscribeUserNotifications().src/plugins/websocket.tsрегистрирует/ws/notifications.- Продюсеры сначала создают запись в БД, потом emit-ят событие.
- Сокет закрывается с кодом
4001при auth-таймауте или невалидном токене.