Архитектура
Клиенты, события и границы ответственности
Клиент → API → данные
В настольном приложении QML обращается к C++-сервисам. ApiClient выполняет REST-запросы, WebSocketClient поддерживает Phoenix Channels, модели списков хранят состояние представления. В мобильном клиенте эту роль выполняют React Native-экраны, сервисы TypeScript и общий серверный контракт.
Phoenix разделён на контексты аккаунтов, команд, чатов, устройств, звонков и шифрования. Контроллеры проверяют аутентификацию и доступ; PostgreSQL хранит сущности и членство. WebSocket-событие сообщает об изменении, а не заменяет серверную проверку прав.
Доставка зашифрованного медиа
Устройство шифрует данные и загружает вложение. Сообщение содержит ссылку-идентификатор и сведения, необходимые разрешённому клиенту для расшифровки. Загрузка байтов и наличие подходящей версии ключа — две разные зависимости: доступная ссылка сама по себе не гарантирует воспроизведение.
Сайт и медиакомнаты
Публичный сайт использует тот же Phoenix-сервер, сохраняя маршруты входа, приглашений и загрузок. LiveView обновляет нужные части HTML по соединению. Для звонка API проверяет членство и выдаёт токен LiveKit, после чего аудио и видео идут по медиатранспорту LiveKit.
Описывает текущую реализацию. Статус мобильной версии и ограничения указаны отдельно.