# Изменения Формат основан на [Keep a Changelog](https://keepachangelog.com/ru/1.1.0/), проект придерживается [семантического версионирования](https://semver.org/lang/ru/). ## [0.0.21] — 2026-08-02 Рычаги нагрузки медиа в админке: потолок качества публикации и лимит плиток. ### Добавлено - Настройка инстанса «Потолок качества публикации видео» (без ограничения / 720p / 360p / 180p) — режет битрейт исходящего видео публикующего через `publishDefaults` LiveKit, снижает нагрузку на его канал и устройство. Дефолт — без ограничения, поведение существующих инсталляций не меняется. - Настройка инстанса «Максимум плиток на экране» (25 / 16 / 9 / 4) — участники сверх лимита уходят на следующую страницу сетки вместо подписки на их видеотреки, меньше одновременных видеопотоков на канал и экран участника. Дефолт — 25 (текущий максимум сетки 5×5), без изменений. - Обе настройки доступны в новой карточке «Нагрузка» вкладки «Настройки» админки и отдаются участнику вместе с токеном входа в конференцию — ещё до подключения к комнате, чтобы применяться до публикации трека и не вызывать переподключение уже вошедших участников при смене настройки. ## [0.0.20] — 2026-08-02 Сеть LiveKit: один UDP-порт вместо диапазона на 101 порт. ### Исправлено - Весь медиа-трафик конференций шёл через userland-прокси Docker: диапазон `54000-54100/udp` заставлял поднимать по отдельному процессу `docker-proxy` на каждый порт. LiveKit переведён на `rtc.udp_port` (один порт, мультиплексирование ICE-сессий по ufrag внутри самого сервера) — проброс портов схлопнут до одного, TURN не затронут. Проверено локально синтетической нагрузкой (`lk load-test`, 2 видео + 2 аудио publisher'а, 2 subscriber'а) — 0% потерь пакетов, ICE во всех сессиях выбирает новый единственный порт. ## [0.0.19] — 2026-08-02 Правки по замечаниям к части B (комната конференции). ### Исправлено - Очередь поднятых рук открывалась боковой панелью во весь экран на мобильном — теперь компактный поповер над кнопкой (как «Вид»), размер подстраивается под число записей, после ~10 строк список скроллится. - Кнопки нижнего тулбара при сужении окна вылезали за края блока (задачи B1/B2 добавили «Рука»/«Очередь», в тулбаре стало до 11 кнопок вместо восьми) — теперь плавно уменьшаются на диапазоне 1200–600px вместо жёсткого скачка на мобильный вид. - Подпись «Мини-окно» на промежуточных ширинах переносилась на 2 строки и делала эту кнопку выше соседних — ниже 1200px показывается короткое «Мини». - Эмодзи-поповер в чате красил все свои кнопки в зелёный цвет кнопки «Отправить» (гонка специфичности CSS-селекторов) — исправлено; заодно сетка приведена к ровным 5×6 без неполной строки, добавлены 🦾 🚀 🦞 💯 🤷‍♂️. ## [0.0.18] — 2026-08-01 Ограничение частоты запросов больше не блокирует вход целой конференции. ### Исправлено - Лимит на резолв конференции и гостевой вход считался по адресу контейнера nginx, а не клиента, — то есть «10 запросов в минуту» действовали на весь сервер разом. Одиннадцатый человек, открывший ссылку в течение минуты, получал отказ и видел «Не удалось найти конференцию» для существующей и активной конференции. Теперь адрес берётся из заголовка, который nginx уже передаёт. - Счётчик считает только неудачные попытки — конференция не найдена или пароль неверен. Именно так выглядит перебор номера, от которого защищает ограничение; массовый вход по рабочей ссылке к нему отношения не имеет. На общий поток с адреса оставлен потолок в 300 запросов в минуту. ## [0.0.17] — 2026-08-01 Массовый вход в систему и в конференцию перестаёт упираться в проверку пароля. ### Исправлено - Проверка пароля больше не останавливает весь backend. Хэширование argon2 — это десятки миллисекунд счёта, и выполнялось оно синхронно внутри асинхронного обработчика: пока считался один пароль, процесс не обслуживал ничего другого. На нагрузочном тесте 31.07 с примерно семью десятками одновременных входов это дало p95 логина 7.28 секунды, p95 входа в конференцию 7.06 секунды и 33 соединения к базе, висящих в открытой транзакции при одном активном запросе. Страдали и посторонние запросы — вход в конференцию отказывал, хотя пароль там не проверялся вовсе. Теперь хэширование считается в пуле потоков. - Параметры argon2id приведены к рекомендации OWASP (t=2, m=19 МБ, p=1) вместо дефолтов библиотеки (t=3, m=64 МБ, p=4): 95 мс против 42 мс на проверку. Прежнее значение `parallelism=4` вдобавок занимало все четыре ядра сервера — те же, на которых работает медиа-сервер. - Пароли, сохранённые со старыми параметрами, продолжают работать и перевыпускаются автоматически при первом успешном входе. ## [0.0.16] — 2026-08-01 Роль организатора в комнате: поднятие руки с очередью и принудительный мьют. ### Добавлено - Роль организатора прокинута в комнату — метаданные LiveKit-токена несут подсказку `is_organizer` для UI (владелец конференции/администратор); любое серверное действие организатора перепроверяется по владельцу конференции в БД, метаданным токена для авторизации не доверяем. - Поднятие руки: кнопка «Рука» в тулбаре (у всех участников, с общим счётчиком), бейдж на плитке говорящего, видимый всем, и панель «Очередь» для организатора — участники в порядке поднятия руки, с возможностью опустить любую руку. Состояние — в Redis (не в БД): очередь существует ровно во время звонка. Участник, вышедший из конференции, автоматически исчезает из очереди; переподключение место не теряет. - Принудительный мьют: организатор может выключить микрофон или камеру любого участника — кнопки на его плитке. Участник получает уведомление, что его выключил организатор, и может включить себя обратно сразу тем же тулбаром. - Эмодзи скачущего коня 🐎 в наборе смайликов чата. ### Изменено - Транспорт чата (`WS /conferences/{id}/chat`) расширен: очередь поднятых рук и уведомления о мьюте едут по тому же аутентифицированному соединению, что и сообщения чата — без нового эндпоинта. Миграций БД нет — новое состояние (очередь поднятых рук) хранится в Redis, не в Postgres. ## [0.0.15] — 2026-07-30 Шесть доработок UI комнаты конференции. ### Добавлено - Выбор эмодзи в чате — поповер с небольшим собственным набором популярных эмодзи (без библиотеки-пикера), вставка в позицию курсора. - Кнопка микрофона в мини-окне (Document PiP) — раньше в PiP не было никакого способа замьютить себя, не разворачивая основное окно. - Закрепление участника доступно из любого режима показа («Стандарт», «Плитки», «Живые плитки») — раньше булавка рендерилась только в «Стандарте». Само закрепление автоматически переключает вид на «Стандарт» (закреплённого иначе негде показать крупно); открепление вид назад не меняет. ### Изменено - Участник заходит в конференцию с выключенными микрофоном и камерой, включает их сам уже в комнате. - В топбаре комнаты вместо технического `room_name` LiveKit (вида `hC-Dmos9KEM`) показывается название конференции; при его отсутствии — «Конференция без названия». Номер и ссылка-приглашение не задеты. ## [0.0.14] — 2026-07-28 TURN-фолбэк для участников из сетей с жёстким NAT. ### Исправлено - LiveKit теперь анонсирует клиентам внешний TURN-сервер (`rtc.turn_servers` в конфигурации, UDP и TCP на 3478). Раньше coturn поднимался и был healthy, но клиенты о нём не знали: внешний TURN в конфиге объявлен не был, встроенный выключен, а фронтенд `iceServers` не задаёт. За всё время работы в логах coturn не было ни одной аллокации — то есть relay не использовался никогда, и участники из сетей, где прямое UDP-соединение не проходит, теряли связь (`PEER_CONNECTION_DISCONNECTED`). На нагрузочном тесте 28.07 все такие разрывы пришлись на внешних участников и ни одного — на офисных. - Credentials TURN генерируются по механизму TURN REST API из общего `TURN_STATIC_AUTH_SECRET`, то есть тот же секрет, что и у coturn. ### Изменено - `deploy/render-templates.sh` подставляет `TURN_EXTERNAL_IP` и `TURN_STATIC_AUTH_SECRET` также в конфигурацию LiveKit. - Раздел 8 руководства по развёртыванию переписан: TURN больше не «план на будущее», а рабочая конфигурация. Отдельно описано правило ufw для relay-диапазона `49160:49200/udp` — без него TURN отвечает на запросы, но релей не работает, причём в логах coturn при этом тишина. TURN over TLS (5349/443) по-прежнему не настроен: требует монтирования сертификата в coturn. Неработающий `turns:` намеренно не анонсируется, иначе клиент ждал бы таймаута перед переходом к рабочему кандидату. ## [0.0.13] — 2026-07-28 Снижение нагрузки на сеть: клиент перестаёт получать полное качество всех чужих камер независимо от того, какого размера плитка на экране. ### Изменено - Включены `adaptiveStream` и `dynacast` в опциях комнаты. Оба флага в LiveKit выключены по умолчанию, из-за чего каждый участник был подписан на полное качество всех чужих треков, а каждый паблишер слал все слои симулкаста, даже когда их никто не смотрит. Теперь качество подписки выбирается по фактическому размеру плитки, а неотрисованные треки уходят в паузу. На локальном стенде (9 участников, паблишеры 720p) входящий поток одного клиента упал с 11 110 до 778 кбит/с. Вместе с этим начинает экономить уже написанный код, который до сих пор не давал выигрыша: «скрыть остальных» не рендерит карусель (исходящий трафик LiveKit 0.76 → 0.03 Мбит/с), пагинация сетки участников рендерит только текущую страницу, а пауза чужого видео в свёрнутой вкладке работает лишь при включённом `adaptiveStream`. - Контейнеры больше не пересобирают окружение Python при запуске: во все вызовы `uv run` в прод-путях (CMD образа, `command`/`entrypoint`/`healthcheck` сервисов, миграции и seed в `install.sh`) добавлен `--no-sync`. Раньше окружение, собранное на этапе build с `--no-dev`, при каждом старте синхронизировалось заново и подтягивало dev-группу: ~26 МБ загрузок, замедленный старт и ruff/mypy/pytest в рантайме. Healthcheck'и делали то же самое каждые 15 секунд всю жизнь контейнера. Размер `/app/.venv` после запуска: 574 → 456 МБ. Локальная разработка не затронута — там dev-группа нужна и ставится как раньше. ## [0.0.12] — 2026-07-28 Разблокировка backend под нагрузкой: вход в конференцию перестаёт отваливаться, когда участники включают микрофоны. ### Исправлено - Обработчик webhook `track_published` больше не запускает Track Egress внутри своей транзакции. Раньше каждый опубликованный микрофон уходил в сетевой вызов, а на инстансе без профиля `transcribe` (egress-сервиса в деплое нет) этот вызов висел 20–25 секунд, всё это время удерживая соединение с БД. На нагрузочном тесте с 19 участниками пул соединений выгребался за секунды, и вход в конференцию начинал отвечать 500. Теперь запуск уходит в фоновую задачу со своей сессией, а webhook отвечает сразу — LiveKit перестаёт копить очередь доставки и терять события. - Track Egress не запускается вовсе, если транскрибация выключена в настройках инстанса — тот же guard, что уже был в обработчике `room_finished`. - Запуск Track Egress ограничен таймаутом (по умолчанию 3 секунды) вместо ожидания собственного таймаута LiveKit. ### Изменено - Пул соединений с БД задаётся явно (`DB_POOL_SIZE`, `DB_MAX_OVERFLOW`, `DB_POOL_TIMEOUT`) вместо дефолта SQLAlchemy 5 + 10. Считайте бюджет на весь инстанс: каждый воркер держит свой пул, и сумма должна оставаться заметно ниже `max_connections` у Postgres. - Backend запускается с несколькими процессами uvicorn (`UVICORN_WORKERS`, по умолчанию 2). Одиночный процесс означал, что любой блокирующий вызов останавливает и параллельные запросы, и WS-чат всех участников. Дефолт 2, а не по числу ядер: на четырёхъядерном сервере ядра делятся с LiveKit. ## [0.0.11] — 2026-07-28 Выбор режима показа участников в конференции, скрытие остальных и круглая иконка участника при выключенной камере. ### Добавлено - Выбор режима показа участников на сцене вместо автоматической раскладки: «Стандарт» (крупная плитка плюс карусель остальных сбоку, как было), «Плитки» (все участники равными плитками) и «Живые плитки» (плитками — только те, у кого включена камера, остальные в карусели). Кто именно показан крупно в «Стандарте», по-прежнему решает прежняя логика фокуса (новая демонстрация → закреплённый → говорящий с видео → говорящий). Выбор сохраняется между заходами в комнату. - Скрытие остальных участников — на сцене остаётся только основная плитка. Скрыть можно из меню «Вид», из шторки настроек на мобильном и кнопкой над колонкой миниатюр; вернуть — кнопкой «Показать остальных (N)», которая видна всё время, пока кто-то скрыт. В режиме «Плитки» скрывать нечего, переключатель там заблокирован. - Переключатель вида: кнопка «Вид» с поповером в тулбаре на широком экране; на мобильном — секция «Вид» в шторке настроек, чтобы не добавлять шестую кнопку в уже ужатый тулбар. ### Изменено - Демонстрация экрана временно перебивает выбранный режим: пока идёт шэр, сцена ведёт себя как «Стандарт», а по его завершении возвращается к выбранному виду. - Равномерная сетка плиток стала пригодна для телефона: 2 колонки от 360px ширины и портретная раскладка 2×3 вместо двух плиток на страницу, которые давал набор раскладок библиотеки. Лишние участники уходят на следующую страницу — листается свайпом и стрелками. ### Исправлено - Иконка участника при выключенной камере больше не превращается в эллипс: размер считается от узкой стороны плитки (container-запросы), а не как проценты от разных сторон. В крупной плитке иконка занимает примерно её половину, в миниатюрах карусели — всю узкую сторону с отступом 5px; на большой плитке фокуса иконка больше не упирается в прежний потолок 96px. - Мини-плеер в Chrome открывался на самом пользователе вместо того, что он видел крупно: сцена в PiP-окне — отдельный экземпляр компонента и выбирала фокус с нуля, доходя до фолбэка «показать себя». Теперь ключ фокуса переживает переезд в мини-окно и обратно. В Safari (video-фолбэк вместо Document PiP) поведение не менялось. ## [0.0.10] — 2026-07-28 Разбивка метрик по контейнерам в Grafana и плашка с характеристиками сервера. ### Добавлено - Метрики по контейнерам (CPU/память/сеть каждого отдельно) — замена `cAdvisor`, несовместимого с containerd-снапшоттером Docker Engine на сервере `1gb` (убран в `0.0.9`). Свой минимальный сервис `container-exporter` (`deploy/monitoring/container-exporter/`) опрашивает Docker Engine API параллельно в фоновой задаче, независимо от storage-driver'а. Доступ к докер-сокету изолирован через `docker-socket-proxy` — экспортеру разрешены только `GET`-запросы по контейнерам, любые изменяющие запросы блокируются на уровне прокси. Панели «Топ контейнеров по CPU/памяти» вернулись в дашборд «Хост и контейнеры». - Плашка «Характеристики сервера» в том же дашборде: живые «Ядра CPU» / «Объём RAM» / «Диск (/)» из `node-exporter`, GPU — из новой info-метрики backend `vidconf_host_info` (данные `install.sh`, `HW_*` в `.env`). ## [0.0.9] — 2026-07-28 Метрики CPU/RAM/диска хоста в Grafana; дефолтные подвкладки конференций и пользователей в админке. ### Добавлено - Мониторинг железа: `node-exporter` (CPU/RAM/диск/сеть/load average хоста) — профиль compose `monitoring`, без публикации портов наружу. Новый дашборд Grafana «Хост и контейнеры». Три новых алерта Prometheus: `HostMemoryLow`, `HostDiskLow`, `HostCpuHigh` (пороги — под сервер `1gb`: 8 ГБ RAM, 4 CPU, 50 ГБ диска). `cAdvisor` (разбивка по контейнерам) сознательно не включён — несовместим с containerd-снапшоттером Docker Engine на `1gb`, см. `docs/deploy/monitoring.md`. ### Изменено - Админка, вкладка «Конференции»: вкладка «Все» перенесена в конец списка фильтров (после «Завершённые»), по умолчанию открываются «Запланированные». - Админка, вкладка «Пользователи»: по умолчанию открываются «Активные» (было «Все»). ## [0.0.8] — 2026-07-27 Админка: несколько mail-доменов для регистрации, фильтр и поиск по команде в списке пользователей, исправлен баг сохранения настроек. ### Исправлено - Сохранение любой настройки инстанса блокировалось ошибкой «уровень AI недоступен», даже если AI-модуль (транскрибация/суммаризация) выключен и пользователь уровень не трогал — фронт отправлял в `PUT /admin/settings` весь набор полей целиком, включая уже сохранённый `ai_level`. Теперь доступность уровня проверяется только при его фактической смене; фронт отправляет в запросе лишь реально изменённые поля. ### Добавлено - «Эталон mail-домена» в настройках инстанса поддерживает несколько доменов вместо одного — регистрация проходит с email с любого домена из списка. Старое значение из БД (один домен) читается без миграции и переписывается в новый формат при первом же сохранении. - В списке пользователей админки — вкладки «Активные»/«Заблокированные»/ «Все» перед полем поиска. - Поиск по пользователям учитывает и название команды — пользователи без команды по-прежнему остаются в общей выдаче. ## [0.0.7] — 2026-07-27 Настройки устройств: выбор аудиовывода и компактная шторка на мобильном. ### Добавлено - Выбор устройства аудиовывода (динамики/наушники/Bluetooth-гарнитура) в «Настройках устройств» рядом с микрофоном и камерой. Выбор переживает перезаход в комнату. Список показывается только там, где браузер умеет им управлять (Android Chrome и другие Chromium на десктопе/мобильном); в iOS Safari поддержки нет вовсе — вместо списка короткая подсказка, что переключение звука там на стороне системы. - На мобильной ширине «Настройки устройств» открываются компактной шторкой снизу вместо модалки по центру экрана — закрывается свайпом вниз, тапом вне панели или Escape. На десктопе поведение не изменилось. ### Примечания по эксплуатации - Управлять маршрутизацией звука (принудительно включить громкую связь или перекинуть звук на Bluetooth) из браузера нельзя в принципе — это делает ОС, веб-страница может только выбрать устройство вывода там, где браузер это позволяет (`setSinkId`). ## [0.0.6] — 2026-07-27 Управление фокусом основного окна конференции: участника можно закрепить, а без закрепления окно само следует за говорящим. Плюс общий футер на всех страницах сервиса. ### Добавлено - Закрепление участника в основном окне — кнопка-булавка на плитке. Закреплённый участник держит фокус, даже когда говорят другие; повторное нажатие снимает закрепление, как и выход закреплённого из комнаты. Закреплённая плитка помечена рамкой и подсвеченной булавкой; на тач-устройствах булавка видна без наведения. - Общий футер на всех страницах, кроме комнаты конференции: версия инстанса и копирайт со ссылкой на автора. ### Изменения - Основное окно конференции следует за активным говорящим, а не удерживает выбранного один раз участника. Фокус не переключается на короткие реплики (удержание 1.2 с) и не уводится с идущей демонстрации экрана. Среди нескольких одновременно говорящих крупно показывается тот, у кого включена камера. Мини-плеер (Document PiP) работает как раньше. - Демонстрация экрана по-прежнему главнее всего: она перебивает и закрепление, а после её завершения фокус возвращается на закреплённого участника. - Футер админки заменён общим компонентом; в брендовой панели экранов входа строка копирайта с захардкоженным годом убрана — год теперь берётся текущий. ### Исправлено - Календарь: «г.» после года убрана и из подписей дней в самой сетке (видны как всплывающая подсказка и в accessibility-дереве) — в недельном и месячном виде. В 0.0.4 это было исправлено только для подписи периода. ## [0.0.5] — 2026-07-27 Контактный адрес инстанса: настраиваемый адрес для ответов на письма (уходят от `no-reply@`) и кнопка проверки почтовой конфигурации из админки. ### Добавлено - Настройка «Контактный адрес» в админке (вкладка «Настройки») — email подставляется в заголовок `Reply-To` писем подтверждения регистрации, приглашений на конференции и саммари; при выключенной настройке `Reply-To` не проставляется, поведение как раньше. - Кнопка «Отправить тестовое письмо» — синхронная проверка почтовой конфигурации без регистрации фиктивного пользователя. Получатель по умолчанию — email текущего администратора, можно указать другой. Результат виден сразу: успех либо текст ошибки транспорта (сервер недоступен/получатель отклонён), без логина и пароля SMTP в ответе. ## [0.0.4] — 2026-07-26 Календарь конференций: перестроен в раскладку «календарь во всю ширину плюс модальные окна» — карточки событий разгружены, подробности вынесены во всплывающее окно. ### Изменения - Форма создания и редактирования конференции больше не занимает постоянную колонку справа, а открывается в модальном окне — по кнопке «Новая конференция», по карандашику на карточке события или из информационного окна. Добавлен общий хук `useModalDismiss` (закрытие по Escape и возврат фокуса на элемент, из которого окно открыли). - Блок календаря занимает всю ширину страницы. - Карточка события в сетке содержит только название (обрезается многоточием и больше не вылезает за границы ячейки) и — у организатора — кнопку редактирования. Время, номер и статус переехали в информационное окно. - Клик по карточке события всегда открывает информационное окно, в том числе для своих конференций: редактирование стало отдельным действием. - Информационное окно вхождения дополнено статус-бейджем и кнопкой «Редактировать» для организатора. ### Исправления - Подпись периода в недельном и месячном виде больше не содержит «г.» (форматирование через `Intl.DateTimeFormat` вместо локали FullCalendar). ## [0.0.3] — 2026-07-26 Мобильная версия: адаптивная вёрстка для узких экранов на ключевых экранах сервиса, найденная и поправленная по итогам ручного прохода по мобильному интерфейсу. ### Исправления - Вход/регистрация (`AuthLayout`): заголовок «Ваша инфраструктура» вылезал за край брендовой панели на узких экранах — кегль теперь адаптивно уменьшается (`clamp()`) вместо обрезки. - Комната конференции: топбар и тулбар не помещались на мобильной ширине (тулбар с 8 кнопками физически шире экрана, крайние кнопки были обрезаны без возможности до них докрутить). На мобильном тулбар сокращён до микрофона/камеры/устройств/чата/выхода (демонстрация экрана, полноэкранный режим и мини-окно скрыты — редко нужны с телефона), в топбаре скрыты название конференции и строка статуса, а чип «№ … / Пригласить» оставлен — с телефона он нужнее. - Админка: заголовок и 4 вкладки раздела не помещались в ширину (вкладки переносятся в 2 ряда, поясняющий текст под заголовком скрыт на мобильном); таблицы «Конференции» и «Пользователи» обрезались вбок — на мобильном в них остаются только ключевые колонки, название конференции стало кнопкой, открывающей то же окно редактирования, что и раньше (туда же добавлена кнопка удаления — на мобильном столбец действий скрыт). - Подключение к конференции (`/join`): кнопка «Ввести другую ссылку или номер» на экране завершённой конференции вылезала за карточку на узких экранах (единственная кнопка на этом флоу без формы-обёртки, задающей ей ширину, а `.btn` держит `white-space: nowrap`). ## [0.0.2] — 2026-07-26 Релиз воспроизводимого боевого развёртывания: конфигурация деплоя перенесена в репозиторий как источник истины, устранён инцидент безопасности, добавлена пошаговая инструкция для девопсов. ### Безопасность - `postgres` и `redis` сняты с публикации на `0.0.0.0` и привязаны к `127.0.0.1` (docker писал DNAT в обход `ufw`, порты были открыты в интернет). - Порты `backend`, `livekit`-signaling, `prometheus`, `grafana`, `llm` также переведены на loopback — наружу остаются только `80/443/7881` (+ UDP `54000-54100`). - Для `redis` включена обязательная аутентификация (`--requirepass`); пароль проброшен во всех потребителей (backend, worker, exporter, livekit, egress). ### Развёртывание и инфраструктура - `nginx`/`coturn`/`livekit`: TLS на 443, http→https редирект, ACME-webroot; конфиги вынесены в `*.template` и рендерятся через `deploy/render-templates.sh` (`envsubst`). Секреты — только из `.env`, обязательны (`${VAR:?}`), без небезопасных дефолтов. - `--env-file .env` добавлен во все вызовы `docker compose` (без него compose не подхватывал корневой `.env` и брал dev-дефолты — корень бага «конференции не работают у других» и `WARN: LIVEKIT_API_KEY not set`). - Мониторинг развязан от опционального LLM: `job=llm`/алерт `LlmDown` закомментированы для профилей без `llm`/`llm-gpu`. - `install.sh`: fail-fast валидация — установка останавливается с понятной ошибкой, если на боевом домене остались dev-плейсхолдеры (`example.com`, `ws://localhost`, `devkey` и т.п.), вместо тихого подъёма нерабочего прода. - `install.sh`: флаг `--monitoring` (Grafana/Prometheus раньше не поднимались ни в одном пресете). - `.env.example` покрывает все параметры деплоя; дефолтные профили — `media,monitoring`. ### Исправления - `nginx`: `/openapi.json` больше не перехватывается SPA-фолбэком, а отдаётся схемой backend. - Предупреждение в `.env.example`: `LIVEKIT_PUBLIC_URL` в HTTPS-проде обязан быть `wss://`. ### Документация - Добавлено `docs/deploy/DEPLOYMENT.md` — полное руководство от голой Ubuntu 24 до рабочего `https://<домен>`: SSL, `.env`, профили, траблшутинг, доступ к мониторингу через ssh-туннель, описание панелей, runbook включения транскрибации/суммаризации. Ссылки добавлены в `README.md`. - `docs/deploy/install.md`: задокументирован флаг `--monitoring`. ### Примечания по эксплуатации - На боевом сервере исправлен certbot deploy-hook (`nginx -s reload` → `restart`): без этого после автопродления сертификата nginx продолжал бы отдавать старый. - TURN-раздача клиентам (`rtc.turn_servers` + TURN/TLS на 443) остаётся опциональной — кросс-сетевое медиа проверено вживую и работает без неё; нужна только для экстремального NAT (CGNAT/жёсткий корпоративный firewall). ## [0.0.1] Первоначальная версия VidConf. [0.0.10]: https://github.com/MaxRonzhin/vidconf_rel/releases/tag/v0.0.10 [0.0.9]: https://github.com/MaxRonzhin/vidconf_rel/releases/tag/v0.0.9 [0.0.8]: https://github.com/MaxRonzhin/vidconf_rel/releases/tag/v0.0.8 [0.0.7]: https://github.com/MaxRonzhin/vidconf_rel/releases/tag/v0.0.7 [0.0.6]: https://github.com/MaxRonzhin/vidconf_rel/releases/tag/v0.0.6 [0.0.5]: https://github.com/MaxRonzhin/vidconf_rel/releases/tag/v0.0.5 [0.0.4]: https://github.com/MaxRonzhin/vidconf_rel/releases/tag/v0.0.4 [0.0.3]: https://github.com/MaxRonzhin/vidconf_rel/releases/tag/v0.0.3 [0.0.2]: https://github.com/MaxRonzhin/vidconf_rel/releases/tag/v0.0.2 [0.0.1]: https://github.com/MaxRonzhin/vidconf_rel/releases/tag/v0.0.1