Сохранить порядок дополнительных Compose-файлов при обновлении и подключать их помощнику на чтение. Добавить проверки override, постоянных каталогов dev-данных и документацию проекта. Явно задать русский язык в тестах русских подписей.
Раньше compose монтировал с хоста Caddyfile, init-скрипты базы и генератор
секретов. Из-за этого установка требовала рядом распакованный репозиторий, а
файл, забытый при сборке релиза, Docker молча подменял пустым каталогом — и
стек падал на первом старте у человека. Плюс production-образ backend вообще
не собирался: COPY content ссылался на каталог, которого в репозитории нет,
так что релиза не существовало ни на GitHub, ни на GitLab.
Теперь весь дистрибутив — один compose.yaml со страницы релиза:
curl -fsSL .../compose.yaml -o compose.yaml
docker compose up -d --wait
- Caddyfile переехал в свой образ шлюза (caddy validate — в сборке),
init-скрипты базы — в свой образ postgres, генератор секретов — в
backend-образ. Bind-mount'ов в production-манифесте не осталось.
- Состояние установки — именованные тома вместо каталогов рабочего каталога.
Заодно чинит загрузку файлов на Linux: том наследует владельца из образа
(hub), тогда как bind-mount доставался контейнеру как root:root.
- scripts/pin-release-compose.py закрепляет ссылки на образы по digest и
падает, если хоть один ключ остался подстановкой.
- GitHub-workflow собирает четыре образа и прикладывает к релизу compose.yaml
(основной путь) и release.env (для `chatballs deploy`).
- tests/cli/test_release_compose.py держит свойство: манифест без bind-mount'ов
и полностью закрепляем по digest.
- Из окружения шлюза убраны CHATBALLS_APP_DOMAIN и CHATBALLS_ACME_EMAIL —
Caddyfile их не читает.
Dev-контур не меняется по смыслу: compose.dev.yaml по-прежнему собирает всё
из исходников и держит состояние в ./data.
AUDIT-TODO.md — временный список остального из аудита; удаляется целиком,
когда закрыт последний пункт.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Первичное требование: поднял докер — прошёл мастер — дальше всё в интерфейсе.
Ни одной переменной окружения задавать не нужно и негде.
Запуск и секреты:
- .env.example удалён, мёртвые переменные вычищены; секреты инстанса
генерирует одноразовый сервис secrets в именованный том, пароли БД —
через POSTGRES_*_PASSWORD_FILE;
- Caddy: catch-all :80 и on_demand TLS вместо хостов в конфиге — свежая
коробка отвечает по IP и по любому домену, до мастера дойти можно;
- адрес установки, SMTP и TURN переехали в настройки (InstanceSettings,
миграции 0027–0030), внешние ссылки строятся от него;
- deploy/cli больше не читает .env; сборка образов в ghcr через GitHub
Actions, release.env с digest-пинами;
- куки Secure/__Host- выставляются по факту TLS запроса, а не настройкой.
Порталы (дизайн-базлайн v2, кадры PT1–PT8):
- список, карточка портала, библиотека материалов, редактор статьи и
настройки — ширины и ритм как в остальных разделах;
- файлы статьи: изображение вставляется в текст своим механизмом, файл
прикрепляется вложением и выводится на портале списком с иконкой формата;
- ссылки на файлы приводятся к относительным: абсолютный хост резал CSP
портала и картинка не появлялась;
- «Опубликовать» сверяется с сервером и публикует то, что на экране, а не
ранее выбранную редакцию;
- колонка «Оценки» в списке статей и блок оценок в редакторе.
Первый запуск: полоса «демо-данные устанавливаются» — установка идёт в
worker, и без неё человек видел пустые разделы без объяснения.
Починен фон: вторичное хранилище стало best-effort — при живых остаточных
S3-ключах повторная загрузка файла падала в 500.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- каталог code/custocrm → code/chatballs; CLI custocrm → chatballs; пакеты
hub_platform → chatballs, hub_backend → chatballs_backend (app labels прежние)
- переменные CUS_* и CUSTOCRM_* → CHATBALLS_*; образы chatballs-*; compose-проект
и база chatballs (были edevs_hub); роли Postgres chatballs_* (были custocrm_*);
схема RLS chatballs и GUC chatballs.organization_id; cookie chatballs_*
- CI: APP_DIR code/chatballs, DEPLOY_ROOT /opt/chatballs
- deploy/migrate/rename-to-chatballs.sh — миграция существующей установки без
потери данных: остановка старого проекта, .env (с резервной копией),
переименование суперпользователя initdb через временную роль, остальных ролей,
базы, схемы и функции RLS; проверено на локальном стеке
- dev-стек хранит Postgres в bind-mount data/postgres, как prod (именованный том
compose.dev был устаревшим снимком и вводил в заблуждение)
- снятие демо удаляет объекты, созданные поверх демо-данных тестировавшим
(звонки по демо-диалогу), вместо падения на PROTECT
- реальные домены *.custocrm.ru и идентификаторы документов не тронуты
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Open source: «развернуть за минуту». Никаких параметров в .env и CLI —
при пустом инстансе браузер показывает мастер (/api/v1/setup/): название
организации, имя, e-mail, пароль владельца и флаг «Установить демо-данные».
Запись идёт на соединении platform (роль app не создаёт организации) через
tenancy/routing.use_database; после первого владельца мастер закрыт (409).
bootstrap_owner и захардкоженные Edevs/Котова из установки удалены
(bootstrap_edevs_owner остаётся тестовым helper'ом).
Демо ставится в организацию установщика; реестр DemoRecord (post_save во
время сида) даёт точное удаление в обратном порядке с разрывом PROTECT-циклов
только между демо-объектами. Установка/удаление — outbox → worker; статус и
витринные учётки (админ + сотрудники разных групп, пароль Chatbolls-Demo-2026)
— карточка «Демо-данные» в «Настройках» (/company/demo/).
Сид переписан под дизайн-базлайн v2 («Ателье Норд»): 6 сотрудников (группы,
блокировка, TOTP, приглашения), 4 агента (активные/черновик/выключенный),
подключения TG/MAX/почта/два веб-виджета (анонимный и авторизованный) с
ошибкой у одного, знания с иерархией категорий и вложениями (md/txt/pdf),
30 дней истории LLM, 13 диалогов во всех состояниях с метками, приоритетами,
заметками, ответственными, историей контакта, спамом и архивом, веб-гость
через настоящую сессию виджета, шаблоны «/», портал поддержки со статьями
(опубликованные/черновик/архив, вторая ревизия, оценки), звонки с метриками и
приглашением, уведомления всех типов, привязки уведомителя. Аватары
контактов — портреты владельца, публичный /api/v1/demo-media/. Голосовые —
слоты под клипы владельца (media/voice/README.md).
Тест покрытия: каждая модель hub_platform получает демо-запись; удаление
возвращает счётчики к исходным. compose-профиль demo-seed и seed-demo.ps1
удалены; seed_demo --organization --apply/--remove для разработки; start.sh
для Linux/macOS; README — раздел «Быстрый старт».
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>