Дата: 2026-06-20
Статус: DRAFT — план вынесения конференций в отдельный микросервисsmarty-conference
smarty-sip сейчас объединяет две несвязанные зоны ответственности:
| Зона | Коллекции | Очередь RabbitMQ |
|---|---|---|
| SIP-телефония (внешние провайдеры) | sip_calls, sip_accounts, sip_employees, normalized_phones |
calls-sip |
| WebRTC-конференции (peer-to-peer + scheduled) | sip_conferences, sip_conference_participants |
calls-webrtc |
Слияние создаёт: один монолитный deploy при разных нагрузках, один PARTICIPANTS_LIMIT для p2p-звонков и многопользовательских митингов, невозможность независимого масштабирования медиа-плоскости.
Разделить smarty-sip на два независимых сервиса без изменения клиентского протокола:
smarty-sip (остаётся): SIP-телефония, webhook'и провайдеров, SIP-сигналинг.smarty-conference (новый): WebRTC-сигналинг, scheduled meetings, управление комнатами, метрики.Медиа-плоскость (ICE/STUN/TURN) уже вынесена — coturn работает отдельно. Разделять медиа-трафик в коде не нужно: он идёт peer-to-peer через TURN, минуя бэкенд.
smarty-sipsip-service.js + events/sip/ — события от SIP-провайдеровroutes/sipcall.js, routes/hooks.js — API звонков и webhook'иSipCall, SipAccount, SipEmployee, NormalizedPhoneslib/integration/ — адаптеры провайдеров (Zadarma, Mango, Flexisip, …)smarty-conference| Артефакт | Целевой путь |
|---|---|
smarty-sip/webrtc-service.js |
smarty-conference/webrtc-service.js |
smarty-sip/events/webrtc/ |
smarty-conference/events/webrtc/ |
smarty-sip/events/webrtc/callMissed.js |
smarty-conference/events/callMissed.js |
smarty-sip/events/webrtc/callFinished.js |
smarty-conference/events/callFinished.js |
smarty-sip/events/webrtc/callAutoHangup.js |
smarty-conference/events/callAutoHangup.js |
smarty-sip/models/webrtc_conference.js |
smarty-conference/models/conference.js |
smarty-sip/models/webrtc_participant.js |
smarty-conference/models/participant.js |
smarty-sip/routes/meetings.js |
smarty-conference/routes/meetings.js |
smarty-sip/lib/conferenceMetrics.js |
smarty-conference/lib/metrics.js |
smarty-sip/lib/callEventWrapper.js |
smarty-conference/lib/callEventWrapper.js |
Очередь calls-webrtc остаётся, но потребителем становится smarty-conference.
Очередь sipcalls остаётся в smarty-sip (обработка online/offline — общая).
Значения берутся из переменных окружения с fallback:
| Константа | Env | Default | Где используется |
|---|---|---|---|
PARTICIPANTS_LIMIT |
— | 50 | p2p WebRTC звонки (webrtc_conference.js) |
ROOMS_LIMIT |
CONFERENCE_ROOMS_LIMIT |
10 | scheduled meetings, проверяется в instance-pre-validate |
MAX_BITRATE_KBPS |
CONFERENCE_MAX_BITRATE_KBPS |
1500 | хранится в документе конференции, передаётся клиенту |
CREDENTIALS_TIMEOUT |
— | 28800 с | TTL TURN-credentials (8 ч) |
DIAL_DELAY |
— | 60 000 мс | таймер дозвона |
HANGUP_DELAY |
— | 30 000 мс | таймер переподключения |
Три функции на MongoDB aggregation — без внешних зависимостей:
| Функция | Назначение |
|---|---|
getConferenceSummary(_wsId) |
activeRooms, byStatus, onlineParticipants — real-time снимок |
countActiveRooms(_wsId) |
быстрая проверка ROOMS_LIMIT в pre-validate |
getFinishedSummary(_wsId, from, to) |
totalConferences, totalParticipants, totalDurationMs, avgDurationMs за период |
Эти метрики доступны через будущий /api/v1/ws/:_wsId/conference/metrics эндпоинт (в meetings.js).
meetings.js не подключён в routes/index.js — закомментирована строка const meetings = require('./meetings'). Причина: нет тестового покрытия. Подключать только после R7 (регресс-сеть). Предварительные условия: lint pass + не менее 3 integration тестов на CRUD митингов.
MEETING_TYPES не был в constants.js до этой задачи — meetings.js импортировал несуществующий экспорт и бросил бы TypeError: Cannot destructure property 'CONFERENCE' of undefined. Исправлено: MEETING_TYPES добавлен в constants.js.
name/scheduledOn не были в схеме webrtc_conference — поля из meetings.js игнорировались бы при strict: true. Исправлено: поля добавлены в схему.
removeDeadCalls побочный эффект при read — завершает «мёртвые» звонки при чтении. Должно быть в scheduled worker, не в accessChecker. Исправить при выносе в smarty-conference.
Шаг 1 — Тесты (предусловие)
Написать integration-тесты для meetings API и WebRTC flow (R7)
Шаг 2 — Выделить пакет smarty-conference
Скопировать файлы из smarty-sip (см. таблицу выше)
Обновить import-пути
Добавить отдельный package.json, ecosystem entry
Шаг 3 — Feature-flag переключение
ENV: CONFERENCE_SERVICE_MODE=standalone|embedded (default: embedded)
В embedded-режиме: smarty-sip включает webrtc-service как прежде
В standalone-режиме: smarty-conference — отдельный процесс/контейнер
Шаг 4 — Migrate очередь
Продюсером calls-webrtc остаётся smarty-sip (emitBgEvent)
Консьюмером становится smarty-conference при standalone-режиме
Шаг 5 — Подключить meetings.js
После написания тестов: раскомментировать в routes/index.js
Добавить эндпоинт /conference/metrics в meetings.js
Шаг 6 — Удалить webrtc из smarty-sip
После canary-deploy standalone-режима на prod
create, join, ice, ...) не меняются — они идут через ту же очередь./ws/:_wsId/meetings — новые эндпоинты, нет breaking changes.smarty-conference.callRecordFile*) — остаются в smarty-sip (SIP-специфика).