К содержанию
b8q
Войти Запросить демо
ПродуктВозможностиЧат, звонки, документы, канбан, ИИТехнологииWebRTC, WebSocket, PWA, CRDTБезопасностьTLS 1.3, P2P, шифрование данныхИнтеграцииTelegram, API, вебхуки
API-документацияREST, WebSocket, Webhooks
РешенияSelf-HostedРазвёртывание на вашем сервереWhite LabelВаш бренд, ваш доменКейсыСценарии использованияКомплаенс152-ФЗ, ФСТЭК, аудит
МиграцияПереход со Slack, Teams, Telegram
ТарифыТарифы
РесурсыБлогСтатьи и руководстваОбновленияИстория версийДорожная картаПланы развития продуктаВопросы и ответыОтветы на частые вопросы
КомпанияО проектеКоманда и миссияКонтактыСвяжитесь с намиПартнёрамПартнёрская программа
Запросить демоВойти
Инженерия

Технологии b8q под капотом

b8q построен на проверенных технологиях с упором на производительность, простой деплой и предсказуемое поведение. Каждая зависимость решает конкретную задачу, модных фреймворков ради моды здесь нет.

Обзор

Архитектура системы

Четыре слоя, каждый из которых можно понять, отладить и заменить независимо от остальных.

Backend

Node.js и Express 5. REST API для CRUD-операций, WebSocket для событий в реальном времени. Один процесс, один порт.

Frontend

SPA на Vanilla JS: 32 модуля, ни одного фреймворка. Темы на CSS-переменных, работает без сборки.

Real-time

WebSocket для сообщений и событий, Yjs для CRDT-синхронизации документов. Конфликтов при совместном редактировании нет.

Database

SQLite в режиме WAL. Один файл внутри процесса, чтение без сетевой задержки. Бэкап — копия файла.

Каждый слой отдельно

Backend: Node.js + Express 5

Сервер b8q — один процесс Node.js на Express 5. Пятая версия выбрана из-за нативной поддержки async/await: ошибки в асинхронных обработчиках ловит middleware, обёртки вроде express-async-errors не нужны, и уходит целый класс багов с unhandled promise rejection.

API устроен по REST: у каждого ресурса (пользователи, чаты, сообщения, документы, файлы, доски) стандартные CRUD-эндпоинты. На том же порту работает WebSocket-сервер: при загрузке клиент получает данные через REST и подписывается на обновления по WebSocket.

Сервер запускается одной командой node server.js, без Docker и внешних сервисов, кроме необязательного TURN-сервера для звонков. Установка сводится к трём действиям: скопировать файлы, поставить зависимости через npm, запустить. Для production рекомендуем PM2 или systemd, но и без них сервер работает стабильно.

Цепочка middleware минимальна: CORS, разбор JSON, проверка JWT, rate limiter. Логи пишутся через console с отметкой времени, в production они перенаправляются в файл или syslog.

Frontend: Vanilla JS SPA

Фронтенд — SPA на чистом JavaScript, без React, Vue и Angular. Каждый из 32 модулей отвечает за свою часть интерфейса (ChatModule, CallModule, DocumentEditor, KanbanBoard, FileManager и другие), загружается как ES-модуль и регистрируется в центральном роутере.

Без фреймворка весь JavaScript приложения занимает десятки килобайт, а не мегабайты, и страница загружается мгновенно. Виртуального DOM и реактивной системы нет: с DOM работаем напрямую, через querySelector и createElement. Для 90% задач этого достаточно.

Стили построены на CSS-переменных: шесть тем переключаются сменой набора переменных на :root, а при выборе своего акцентного цвета вся схема пересчитывается автоматически. Никакого CSS-in-JS и Tailwind, только обычные CSS-файлы с понятной структурой.

Сборка не нужна: код работает в браузере напрямую через <script type="module">. Минификация через terser необязательна, отладка идёт в DevTools без source maps и webpack.

Real-time: WebSocket + Yjs

В b8q два канала реального времени. Первый — WebSocket для системных событий: новые сообщения, индикатор набора, статусы прочтения, изменения на канбан-досках, уведомления о файлах. Соединение открывается при входе и живёт всю сессию, при разрыве клиент переподключается с экспоненциальной задержкой.

Второй канал — Yjs для совместного редактирования документов. Это CRDT-библиотека (Conflict-free Replicated Data Type): каждая операция коммутативна и идемпотентна, поэтому одновременные правки сливаются без конфликтов, а правила «побеждает последний сохранивший» нет.

Yjs синхронизируется поверх WebSocket: открывая документ, клиент запрашивает текущее состояние и подписывается на обновления. Каждое нажатие клавиши уходит как операция, и результат одинаков на всех устройствах, даже если двое печатали в одном месте.

Производительность Yjs масштабируется линейно по числу операций: документ с тысячами правок открывается за десятки миллисекунд. История изменений хранится в компактном бинарном виде.

  • WebSocket для всех событий в реальном времени
  • Автоматическое переподключение с backoff
  • Yjs CRDT: совместное редактирование без конфликтов
  • Линейная масштабируемость по числу операций

WebRTC: P2P-звонки

Звонки построены на WebRTC, стандарте W3C для P2P-аудио и видео в браузере. Медиапотоки идут напрямую между участниками, а через сервер по WebSocket проходит только сигнализация (offer, answer, ICE-кандидаты). Отсюда минимальная задержка и отсутствие нагрузки на сервер.

Соединение устанавливается через ICE: сначала клиенты пробуют прямой путь через STUN, а при симметричном NAT или корпоративном файрволе трафик идёт через TURN-relay. Свои STUN- и TURN-серверы задаются в конфигурации.

Качество видео адаптивное: клиент следит за пропускной способностью через RTCPeerConnection.getStats() и переключает разрешение — 480p на слабом канале, 720p на обычном, 1080p на хорошем. Звонок при этом не прерывается.

Групповые звонки на 2–5 участников идут по mesh-топологии: каждый соединён с каждым, для пяти человек это 10 соединений. Медиасервер (SFU/MCU) не нужен, это упрощает деплой, но ограничивает масштаб. Для большинства рабочих созвонов пяти участников хватает.

  • WebRTC peer-to-peer без медиасервера
  • ICE: STUN для прохождения NAT, TURN как запасной путь
  • Адаптивный битрейт: 480p, 720p, 1080p
  • Mesh-топология для групповых звонков

База данных: SQLite + WAL

Для self-hosted мессенджера на одном сервере SQLite удобнее PostgreSQL или MySQL: нет отдельного процесса БД, сетевых вызовов и настройки пулов соединений. SQLite встроен в процесс Node.js через better-sqlite3, и запрос к базе — это вызов функции, а не сетевой roundtrip.

Ключевая настройка — WAL (Write-Ahead Logging): чтение и запись не блокируют друг друга. Сотни запросов к истории чатов выполняются параллельно и не мешают записи новых сообщений.

На типичной нагрузке мессенджера SQLite в режиме WAL выдерживает десятки тысяч операций в секунду, этого с запасом хватает команде до нескольких сотен человек. База — один файл: бэкап делается командой cp database.db database.db.backup, миграции — SQL-файлы, которые выполняются при запуске сервера.

Схема нормализована (users, chats, messages, documents, files, boards, cards), на частых полях chat_id, created_at и user_id стоят индексы. Полнотекстовый поиск по сообщениям работает на FTS5, который входит в стандартную сборку SQLite.

AI: Gemini + Rule-based fallback

AI-ассистент подключается к Google Gemini через REST API. Сервер собирает промпт с контекстом (история диалога и системная инструкция), отправляет запрос в Gemini и возвращает ответ пользователю обычным сообщением в чате.

Если Gemini недоступен (таймаут, исчерпана квота, сбой сети), включается резервный режим на правилах: заготовленные ответы на типовые запросы, помощь по интерфейсу, базовые команды и FAQ. Полноценную LLM он не заменяет, но ассистент не замолкает.

Промпт собирается на сервере, клиент отправляет только текст пользователя. Поэтому поведение модели настраивается централизованно: администратор меняет системный промпт без обновления клиента.

Если требования к данным жёсткие, AI-модуль полностью отключается в конфигурации сервера, и ни один запрос не уходит во внешний сервис. Это важно для работы с персональными данными, финансовой информацией и коммерческой тайной.

  • Google Gemini через REST API
  • Резервный режим на правилах, если LLM недоступна
  • Промпт собирается на сервере
  • Полное отключение AI для чувствительных данных

Безопасность: JWT + bcrypt + Rate Limiting

Авторизация построена на JWT (JSON Web Tokens). При входе сервер проверяет пароль, формирует токен с user_id и ролью и подписывает его секретным ключом, а клиент передаёт токен в заголовке Authorization в каждом запросе. Срок жизни токена задаётся в конфигурации.

Пароли хранятся как bcrypt-хеши. Алгоритм намеренно медленный (cost factor настраивается), соль встроена в хеш, поэтому rainbow tables бесполезны. Даже при утечке базы восстановить пароли при адекватном cost factor практически невозможно.

Rate limiting защищает вход от перебора паролей, а API от DoS. Лимиты задаются для каждого эндпоинта: на вход жёстче, на чтение сообщений мягче, при превышении сервер отвечает 429 Too Many Requests. В self-hosted пороги настраивает администратор.

WebSocket-соединение проверяется при установке: клиент передаёт JWT, сервер проверяет подпись, и неавторизованные соединения отклоняются до передачи данных. В production трафик идёт по HTTPS/WSS, TLS обеспечивает reverse proxy (nginx, Caddy).

История

Развитие проекта

Ключевые этапы b8q от первого прототипа до полноценной платформы.

  1. Q3 2024Готово

    Прототип мессенджера

    Первая версия: чат на WebSocket, авторизация по JWT, хранилище на SQLite, базовый интерфейс на Vanilla JS. Проверяли гипотезу, можно ли собрать рабочий мессенджер без фреймворков.
  2. Q4 2024Готово

    Звонки и документы

    P2P-звонки на WebRTC. Три редактора документов: Markdown, Rich Text (Quill) и таблицы (jspreadsheet). Yjs для совместного редактирования в реальном времени.
  3. Q1 2025Готово

    Канбан, облако, AI

    Канбан-доски с перетаскиванием, облачное хранилище с превью файлов, AI-ассистент на базе Gemini. Групповые звонки до 5 участников, поддержка PWA на мобильных.
  4. Q2 2025Готово

    Темы и кастомизация

    Шесть цветовых тем и настройка акцентных цветов. White-label для корпоративного брендинга. Импорт .docx, .xlsx, .csv. Голосовые сообщения.
  5. Q3 2025Готово

    Self-hosted и стабилизация

    Документация для self-hosted деплоя. «Картинка в картинке» и демонстрация экрана в звонках. Оптимизация SQLite и WebSocket. Закрытая бета.
  6. 2026

    Публичный запуск

    Открытая регистрация. Облачная версия наряду с self-hosted. Расширение API для интеграций. Планы по E2E-шифрованию и федерации между серверами.
32JS-модуля
0UI-фреймворков
1файл БД
P2Pархитектура звонков

Хотите пощупать вживую?

Архитектуру лучше всего оценивать в работе: от git clone до первого сообщения 5 минут.