← все проекты

Контент Завод Bonimed

Дашборд контент-завода для косметики Bonimed: бриф, товары с импортом Wildberries, видео на Veo 3.1 / Wan 2.7 / Seedance / Kling, автопубликация и СММ-ферма (уникализация ролика и раскладка по пачке аккаунтов через Upload-Post). Форк zavod-order. Посты, карусели и аватары намеренно не заводим.

server: cfru 80.90.184.203, /opt/bonimed-zavod, порт 3150, Postgres 5442, Redis 6392. Пароль входа и ключи в .env и в панели.docs: E:\Проекты для Гитхаба\Контент Завод Bonimed\docsпамять: zavod-order-project, upload-post-capabilities, kie-ai-pricing-api, bonimed-n8n-server
ревьюS1 · Каркас, бриф, товары10/10

Цель: Поднять форк на cfru:3150 без постов и аватаров, завести бриф компании и раздел Товары с автоимпортом карточек Wildberries.

🔴 Форк zavod-order в bonimed-zavod
Скопировать код, вычистить посты, карусели и аватары из схемы, роутов, сайдбара и воркера. Осталось только видео.
Скопирован, посты и аватары вычищены из схемы, кода, меню и форм. HeyGen удалён целиком.
infra
🔴 Компоуз и окружение под новые порты
app 3150, Postgres 5442, Redis 6392, свой том медиа. Ни одного адреса нашей инфраструктуры в коде, всё через .env.
app 3150, Postgres 5444, Redis 6394 (5442 и 6392 оказались заняты соседями). Тома свои.
infra
🔴 Схема БД: товары и ферма
Product, ProductImage, FarmAccount, FarmGroup, FarmBatch, FarmVariant, UniqPreset. ContentType сужается до video. Миграция одной командой.
Product, ProductImage, FarmGroup, FarmAccount, UniqPreset, FarmBatch, FarmVariant. ContentType сужен до video. Миграция 0001_init в репозитории, накатана.
backend
Бренд и оформление под Bonimed
lib/brand.ts, название, палитра под косметику, шрифты. Стилистика дашборда из демо остаётся.
lib/brand.ts: Bonimed, подпись «завод контента и ферма аккаунтов».
ui
Бриф компании и бриф под видео
Продукт, ЦА, тон, преимущества, стоп-слова, ссылка, флаг ссылки первым комментарием. Смена брифа меняет выдачу ИИ.
Скоупы general и video, наследование пустых полей. Проверено сохранением и чтением через API.
feature
🔴 Раздел Товары: список и карточка
Создание вручную, редактирование, архив, поиск. Фото, цена, ссылка, артикул, заметки маркетолога.
Список с фото и ценой, карточка с правкой, выбор обложки, архив вместо удаления.
ui
🔴 Импорт карточки с Wildberries
По ссылке или артикулу: card.wb.ru/cards/v4/detail даёт бренд, название, цену до и после скидки, рейтинг, остаток; basket CDN даёт описание, характеристики и фото. Без ключей. Обработать 429 и снятые с продажи.
Работает по ссылке и по артикулу. Тянет бренд, цену до и после скидки, оценку, отзывы, остаток, описание, 20 характеристик, фото. Площадка режет и по адресу сервера, и по TLS-отпечатку: запрос идёт через curl и MARKETPLACE_PROXY_URL. Без цены товар всё равно заводится с предупреждением.
integration
Хранение фото товара в томе
Скачивание картинок WB к себе, превью, ручная догрузка своих фото. Медиа переживает перезапуск контейнеров.
Фото скачиваются в storage/products, отдаются по сессии, наружу только по подписанной ссылке.
backend
Привязка товара к ролику
У видео выбирается товар, его данные идут в промпт генерации и в текст публикации.
Товар выбирается при создании идеи и в плане от ИИ, данные идут в промпты агентов, обложка уходит референсом в генерацию. В карточке готового ролика товар пока не показывается, вынесено в спринт 2.
backend
🔴 Деплой на cfru:3150 и вход по паролю
Ключи вводятся в панели и шифруются, наружу не отдаются. Ни один API-метод без авторизации.
Живой стенд http://80.90.184.203:3150. Без пароля страницы редиректят, API отдаёт 401. Подписанная отдача медиа проверена: верная подпись 200, подделка и просрочка 404.
infra
В РАБОТЕS2 · Видео и контент-план10/16

Цель: Ролик генерится руками и по плану, расход считается по факту, лимиты денег работают.

🔴 Каталог видеомоделей с единицей тарификации
Veo 3.1 (за ролик, Lite 1080p 0.175, Fast 0.325, Quality 1.275), Wan 2.7 (0.08/сек 720p, 0.12/сек 1080p), Seedance 1.5 Pro (0.035/сек 720p со звуком), Kling 3.0 (0.09/сек 1080p). Обязательно поле cost_unit, иначе цены врут.
backend
Тексты и планы переведены с OpenAI на Kie
Клиент вписал ключ Kie в оба поля панели, api.openai.com отвечал 401 каждую минуту почти сутки. Новый провайдер lib/providers/text.ts: каталог gpt-5-2 и gemini-3-7-flash, адреса и имена моделей проверены живым запросом. Поля Ключ OpenAI в панели больше нет, прокси тексту не нужен, расход на текст пишется в Spend из credits_consumed.
Задеплоено на cfru:3150, миграция 0002_text_via_kie накачена. Проверено живьём: POST /api/plan/generate собрал идею с хуком и сценарием за 14 с, списание 0.29 кредита записано в Spend, баланс 1079.63.
feature
Повтор задания больше не плодит записи Job
Баг форка zavod-order: на каждую неудачу заводилась НОВАЯ запись Job, счётчик попыток обнулялся, задание с непроходимой ошибкой крутилось вечно. За сутки 1724 мёртвые строки, enqueueOnce намертво заблокирован (у материала всегда есть ждущее задание). Починка: requeue в lib/queue.ts кладёт в очередь ту же запись, maxAttempts работает. Проверить тот же баг в zavod-order и navesy-zavod: код общий.
Задеплоено. Мёртвые строки удалены с ведома владельца (1744), очередь Redis очищена, зависшее задание на Kling 3.0 снято, чтобы не тратить 140-200 кредитов без спроса.
feature
Первый кадр ролика собирается моделью картинок
Обложка карточки Wildberries это рекламный коллаж, он уезжал в ролик первым кадром вместе с надписями, и от него же ролик брал пропорции 3:4. Теперь lib/frame.ts: фото товара в jpeg, загрузка в хранилище Kie, gpt-image-2-image-to-image собирает кадр 9:16 по идее и хуку с прямым запретом тащить текст и коллаж. Кадр лежит в ContentItem.framePath, виден в карточке, переделывается кнопкой. У фото товара своя пометка в кадр, отдельно от обложки.
Проверено живьём: кадр 941x1672, банка с настоящей этикеткой, без надписей, 6 кредитов. Миграция 0003_first_frame накачена.
feature
Клиенту: вписать ключи публикации
В панели заполнен только ключ Kie. Upload-Post, VK и Telegram пустые, поэтому публиковать некуда, а согласование включено без бота: готовые ролики раньше молча зависали в статусе готово. Панель теперь предупреждает, воркер пишет в лог. Нужны от клиента: UPLOADPOST_API_KEY плюс привязка соцсетей, токен бота и чат согласования.
feature
Панель без технических текстов, ролик смотрится из списка
Разбор скриншота владельца: в подписи торчала разметка модели :::writing{...}, ошибки показывались ответом провайдера, ролик не открывался по клику, видео в карточке растягивалось на весь экран, в списаниях числились неоплаченные попытки и ключи моделей, бейдж ошибок висел на Расписании, кнопка Опубликовать была активна без подключённых сетей, чекбоксы и списки были системными, на телефоне шапка налезала на меню. Плюс модель нарисовала в ролике плашку 937 рублей, потому что сценарист описал надпись на экране.
Всё выкачено и проверено браузером на живой панели: 8 страниц без техтекстов, плеер открывается, тексты в базе почищены разово, агентам и модели видео запрещены надписи на экране.
feature
Ручная генерация с расчётом цены до запуска
Механика перенесена из Навесов под аспекты Bonimed: только ролики и товары с Wildberries, без аватаров, каруселей и постов. Раздел Ручная генерация: плитки своих роликов, форма создания (тема, товар, модель, длительность, качество, звук), карточка шагов кадр-съёмка-подпись. Каждый платный шаг возвращает 409 с примерной ценой и тратит деньги только по второму нажатию. Таблица ManualStep хранит попытки и списания. Кнопка Сделать ролик добавлена в карточку товара. Оценка цен в lib/pricing.ts сверена с каталогом Kie.
Проверено браузером на живой панели: из карточки товара открывается форма с подставленным товаром, ролик заводится, шаги показывают расчёт (кадр 6 кредитов около 3 рублей, съёмка Kling 5 секунд со звуком 100 кредитов около 48 рублей). Миграции 0004 и 0005 накачены.
feature
Шаг ручной генерации не вешает панель
Владелец нажал первый кадр и панель выглядела повисшей: запрос держался минуту, кнопка показывала Запускаю, остальные кнопки гасли, шаги не открывались. Сам кадр при этом делался нормально. Починка: шаг создаётся и ставится в очередь, выполняет воркер (новый вид задания manual_step), панель показывает Идёт с пояснением и сама подтягивает состояние раз в несколько секунд, гаснет только кнопка своего шага. Зависшие шаги снимает планировщик: кадр через 8 минут, съёмка через 25.
Проверено живьём: шаг подписи ушёл в очередь мгновенно, панель показала Идёт, через 20 секунд сама показала готовый текст и списание 0.27 кредита. Миграция 0006.
feature
🔴 Кадр терял этикетку товара
Клиент прислал: вместо чёрной банки BONIMED MAN FACE REHAB в кадре белая безымянная. Проверка по записи промпта показала, что фото уходит именно картинкой, а виноват наш же запрет: no text, no letters, no logos модель применила к самой упаковке и стёрла брендинг. Правила переписаны: запрет только на графику поверх кадра, надписи на упаковке обязательны и читаемы, упаковка закрыта и повёрнута к камере. Добавлены поля: пожелание к кадру у товара (постоянное) и что поправить в кадре у ролика (разовое, уходит в следующую пересборку).
Проверено пересборкой того же кадра: банка чёрная, крышка закрыта, надпись BONIMED MAN FACE REHAB читается целиком. Миграция 0007.
feature
🔴 Ручное создание ролика
Промпт, модель, длительность, разрешение, референсное фото товара. Оценка стоимости показывается до запуска.
ui
🔴 Генерация через Kie
createTask, поллинг recordInfo, resultUrls. Ретраи, читаемая ошибка, сбой модели не роняет очередь.
Проверено живьём 24.08: Kling 5 с 720p с кадром товара, ролик сохранён, играет в панели, списание 70 кредитов записано. До этого генерация не работала ни на одной модели.
integration
🔴 Учёт расхода по факту и лимиты
Списание меряется разницей баланса до и после, не по прайсу. Дневной и месячный потолок, минимальный баланс, стоп автогенерации с уведомлением.
Расход пишется по факту: видео и картинки по разнице баланса Kie, текст из credits_consumed ответа. В базе строки на 70 (ролик), 6 (кадр), 0.29 (план). Лимиты дня и месяца и стоп по остатку проверяются перед постановкой в очередь.
backend
Контент-план: календарь и список
Месяц листается вперёд и назад, прошлые месяцы открываются. На день можно поставить несколько роликов.
ui
Автоплан от ИИ по брифу и товарам
Идеи разные, разложены по рубрикам, привязаны к конкретным товарам. Одобрить, отклонить, переделать с обязательным комментарием.
Проверено 21.08: POST /api/plan/generate собрал идею с хуком и посекундным сценарием за 14 с через Kie.
feature
Раздел Видео
Список со статусами, превью, фильтры, перегенерация, история версий.
ui
Расписание
Ближайшие отправки, ручной сдвиг времени, часовой пояс.
ui
В РАБОТЕS3 · СММ-ферма2/10

Цель: Одно готовое видео превращается в пачку уникальных копий и расходится по аккаунтам с разносом по времени.

🔴 Профили Upload-Post из панели
GET/POST/DELETE /uploadposts/users: список, создание, удаление. Видно какие соцсети привязаны к профилю.
Кнопка «Подключить соцсеть» заводит профиль через POST /uploadposts/users, имя транслитерируется в латиницу. Удаление аккаунта стирает профиль и на их стороне. Проверено полным циклом: создал, сверил, удалил, профиль исчез из кабинета.
integration
🔴 Привязка соцсети по ссылке
POST /uploadposts/users/generate-jwt со своим логотипом и текстом, редирект обратно в панель. Так заводятся новые инстаграмы.
generate-jwt с redirect_url на /farm?connected=1, человек уходит на страницу входа Upload-Post и возвращается, панель сама сверяет что привязалось. Сделано по образцу /api/smm/connect из Контент Завода.
integration
Группы аккаунтов
Аккаунты объединяются в группы, публикация назначается на группу целиком. Включение и отключение аккаунта.
feature
🔴 Уникализатор ffmpeg
Контраст, яркость, насыщенность, гамма, подрезка 0.2-0.5 сек с начала или конца, скорость 0.98-1.02, кроп-зум 1-3 процента, громкость и подрезка аудио, плавающий CRF и битрейт, полное стирание метаданных через -map_metadata -1 и -fflags +bitexact. Перенос механики из n8n Ферма.
backend
Пресеты уникализации и предпросмотр
Именованные наборы параметров, слабый и сильный. Превью варианта до публикации.
ui
Затирание зоны субтитров
Блюр области, обрезка нижней полосы или delogo с выбором зоны мышью. Честно предупреждать, что вшитые сабы полностью не снимаются.
feature
🔴 Кнопка Масштабировать
На готовом ролике: выбрать группу или аккаунты, число копий, пресет. Панель делает N уникальных файлов и ставит задания в очередь.
feature
Свой текст на каждый вариант
ИИ пишет отдельный текст под каждую копию с лимитами площадок, чтобы подписи не совпадали. Товар и бриф в контексте.
backend
🔴 Публикация с разносом по времени
Джиттер 10-40 минут между аккаунтами, дневной лимит на аккаунт. Одновременная публикация с десяти аккаунтов это заявка на бан.
backend
Журнал публикаций фермы
Куда ушло, куда нет, текст ошибки, ссылка на пост, ручной повтор.
ui
планS4 · Автопилот и аналитика0/8

Цель: Завод работает без ручного участия, видно отдачу по каждому аккаунту.

🔴 Первый комментарий со ссылкой
Поле first_comment и по-платформенные варианты в POST /upload. Поддержаны Instagram, Facebook, Threads, X, YouTube, LinkedIn, Reddit, Bluesky. У TikTok первого комментария нет, интерфейс говорит об этом прямо.
integration
Автогенерация заранее
Планировщик поднимает генерацию за N часов до публикации, чтобы к сроку медиа было готово.
feature
Автопубликация по расписанию
Окна публикации, пауза, соблюдение лимитов денег. Проверено на реальной отложенной отправке.
feature
Согласование в телеграм-боте
Готовый ролик приходит с превью и кнопками, переделка собирает комментарий и запускает перегенерацию.
feature
Аналитика аккаунтов
GET /analytics/{profile_username} и /uploadposts/post-analytics/cached: охваты и просмотры по каждому аккаунту и посту.
integration
Сводка по ферме
Сколько копий ушло, сколько упало, какие аккаунты дают отдачу, какие молчат.
ui
Повтор и снятие публикации
POST /uploadposts/posts/retry и /posts/unpublish из журнала.
integration
Проверка переносимости
Развернуть с нуля на чистой машине по HANDOVER.md и убедиться, что работает. Проект уедет на сервер клиента.
infra

Ворклог (места остановки)

25.08.2026, 06:59:12 · Спринт 2 (видео и деньги) · claude

Добавлена ручная генерация по образцу Навесов, под аспекты Bonimed: только ролики и товары с ВБ. Раздел в меню, форма создания с выбором товара, модели, длительности, качества и звука, карточка шагов кадр-съёмка-подпись, каждый шаг с примерной ценой до запуска и переделкой по отдельности. Появилась таблица ManualStep с историей попыток и списаний, кнопка Сделать ролик в карточке товара, модуль оценки цены сверен с каталогом Kie. Звук вынесен в настройки и включён по просьбе владельца.

Перенести тот же раздел в Альфа центр (zavod-order) с их аспектами: их товары для стройки и их типы контента. Владелец сам прогонит ролик со звуком и сравнит модели.

25.08.2026, 06:34:38 · Спринт 2 (видео и деньги) · claude

Поля в формах выровнены: ряд переписан с flex по нижнему краю на сетку с одинаковыми колонками, поэтому подписи и контролы стоят по одной линии, а подсказки больше не двигают соседей. Звук ролика вынесен в настройки (был выключен константой ради цены): каждая модель объявляет, умеет ли она звук, у Wan звука нет, у Veo он всегда внутри, у Kling и Seedance включается и стоит примерно в полтора раза дороже. Миграция 0004.

Владелец решает, включать ли звук по умолчанию: Kling 5 секунд со звуком примерно 100 кредитов против 70 без. Если нужен звук дёшево, выгоднее Veo Lite: 8 секунд со звуком около 30 кредитов.

25.08.2026, 06:21:41 · Спринт 2 (видео и деньги) · claude

Проход по панели глазами владельца. Убрана разметка модели из текстов (чистка на входе плюс разовая чистка базы), ошибки в интерфейсе стали человеческими, техника ушла в логи. Ролик теперь открывается по клику из списка с плеером и скачиванием, в карточке видео перестало растягиваться на весь экран. Списания по моделям показывают только оплаченные генерации и человеческие названия. Бейдж ошибок переехал на Видео, кнопка публикации гаснет без подключённых сетей, в карточке добавлена кнопка Опубликовать. Чекбоксы и списки перекрашены под тему, на телефоне поправлены шапка и превью. Агентам и модели видео запрещены надписи на экране: в прошлом ролике модель нарисовала плашку с ценой.

Решить с владельцем, убирать ли из интерфейса имя сервиса публикации (по общему правилу провайдеров в UI не показываем, но здесь ключ вводит сам клиент). Прогнать Veo живьём. Материал 3 признака ждёт перезапуска генерации. Публикация по-прежнему ждёт ключей клиента.

24.08.2026, 06:11:06 · Спринт 2 (видео и деньги) · claude

Генерация видео не работала ни на одной модели: Kling падал на This field is required (нет sound, mode, multi_shots, multi_prompt, длительность нужна строкой), Wan и Seedance молча игнорировали aspect_ratio и image_url, Veo терял пропорции. Теперь у каждой модели своя сборка тела запроса, имена сверены с документацией, Veo разделён на Lite, Fast и Quality (цена отличается до восьми раз). Добавлен пайплайн первого кадра: фото товара в jpeg, загрузка в хранилище Kie, gpt-image-2 собирает кадр 9:16 по идее с запретом на текст и коллаж, кадр уходит первым в видео. У фото товара своя пометка в кадр. В настройках появилось качество ролика, модель первого кадра, подсказки по моделям. Проверено живьём: кадр 941x1672 за 6 кредитов, ролик 720x1280 за 70 кредитов, оба сохранены и играют в панели.

Проверить ветку Veo живьём (Lite 8 секунд, 30 кредитов) и прогнать полный круг на идее планировщика со сценарием. Публикация ждёт ключей клиента: Upload-Post, VK, Telegram. Тот же баг повторов и те же имена полей у моделей надо проверить в форках zavod-order и navesy-zavod.

21.08.2026, 15:04:48 · Спринт 2 (видео и деньги) · claude

Планы и тексты переведены с прямого OpenAI на Kie: один ключ на всё. Новый lib/providers/text.ts (каталог gpt-5-2 и gemini-3-7-flash, адреса проверены живым запросом), модель текста выбирается селектом в настройках, поле Ключ OpenAI из панели убрано, расход на текст пишется в Spend из credits_consumed ответа Kie. Побочно найден и починен баг повторов: новая запись Job на каждую неудачу (1724 мёртвые строки за сутки, блокировали enqueueOnce). Обновлены README, ARCHITECTURE, HANDOVER, DECISIONS, .env.example, миграция 0002.

Владелец сам запускает генерацию ролика Полезный кнопкой в панели (Kling 3.0 10 с, примерно 140-200 кредитов из 1080). Осталось: решить, удалять ли из базы старую строку секрета OPENAI_API_KEY (в ней копия ключа Kie), и проверить тот же баг повторов в форках zavod-order и navesy-zavod.

07.08.2026, 03:57:29 · Спринт 1 и 3 · claude

По замечаниям владельца. 1) Починил фото с Wildberries: файловых серверов у площадки больше 30 (карточка 799170196 лежит на basket-36), перебор шёл до 30 и молча отдавал товар без фото. Теперь до 70 и пачками параллельно, плюс скачивание не обрывается на первом промахе. У крема для ног дотянулись 10 фото, описание и характеристики. 2) Добавил загрузку своих фото, удаление фото с сохранением обложки и полное удаление товара с очисткой файлов (архив остался для товаров с материалами). 3) Сделал раздел Ферма с подключением соцсетей по образцу Контент Завода: панель создаёт профиль в Upload-Post и уводит на их страницу входа, после возврата сама сверяет что привязалось. Проверено полным циклом на нашем кабинете, тестовый профиль удалён. Вписал ключ OpenAI владельца, проверил боем через прокси.

Спринт 2: каталог моделей с единицей тарификации, ручная генерация ролика с ценой до запуска, учёт расхода по балансу Kie. Нужен ключ Kie в панели. Спринт 3 дальше: уникализатор ffmpeg, кнопка Масштабировать, разброс времени публикации.

05.08.2026, 10:51:38 · Спринт 1 · claude

Завёл проект bonimed-zavod: роадмап в Atlas (4 спринта, 36 задач), форк «Альфа центра» с вычисткой постов и аватаров, схема БД с товарами и фермой, раздел Товары с импортом карточек Wildberries, подписанная отдача медиа наружу. Стенд живой на cfru:3150, импорт товара проверен на реальной карточке: цена, оценка, остаток, описание, характеристики и фото на месте. Механику уникализации нашёл в n8n «Ферма» на сервере bonimed и разобрал, переносим в код в спринте 3. Проверено фактом: первый комментарий у Upload-Post работает через поле first_comment при публикации (Instagram в списке, TikTok нет), профилями можно управлять по API.

Спринт 2: каталог моделей с единицей тарификации (Veo за ролик, Wan/Seedance/Kling за секунду), ручная генерация ролика с оценкой стоимости до запуска, учёт расхода по балансу, календарь и автоплан. Перед первой платной генерацией согласовать бюджет с владельцем. Долги спринта 1 в docs/SCOPE-CUTS-LOG.md: товар в карточке ролика, загрузка своих фото, HTTPS вместо голого IP.