Альфа центр (заказ)
ревьюS1 · Каркас и контент-план10/12
Цель: Поднять переносимый скелет, дизайн-систему демо, дашборд с переключением страниц, схему БД и полноценный контент-план на месяц с ИИ и ручными идеями.
В РАБОТЕS2 · Генерация контента5/8
Цель: Очередь и воркер, генерация постов, видео и ИИ-аватаров, хранилище медиа, учёт расходов с жёсткими лимитами.
В РАБОТЕS3 · Публикация и расписание2/7
Цель: Подключение соцсетей, публикация по расписанию с часовым поясом, выбор сетей на элемент, ссылка первым комментарием, логи и повторы.
В РАБОТЕS4 · Согласование, автопилот, перенос1/7
Цель: Телеграм-бот согласования, автогенерация заранее, автопилот с предохранителями, пакет переноса на сервер клиента.
ревьюS5 · Надёжность и стандарты27/27
Цель: Перенести ядро надёжности и правила речи, найденные на заводе навесов, пока проект ничего не сгенерировал.
Ворклог (места остановки)
Найдена причина, по которой видео не снималось вообще, а посты работали: middleware не пропускал подписанные ссылки на медиа, провайдер получал 401 вместо первого кадра и отвечал Image fetch failed. Проверено фактом: до фикса 401, после 200 и 2.3 МБ, без подписи 403. За упавшие видео провайдер не списал ничего, потрачено было только на первые кадры, 78 кредитов за день. Перезапущен материал про завод: видео готово, 720x1280, 8 секунд, списано 250 кредитов, модель veo-3.1. Второй материал запущен. Баланс клиента 805 в начале, 525 после первого. Карусель нельзя было выбрать в контент-плане: формат поддерживался в базе, очереди и пайплайне, но отсутствовал в списке форматов и фильтре, добавлен. Технические ошибки провайдера убраны из карточек: lib/user-error.ts, наружу идёт понятная фраза с просьбой написать в MyVision, подробности остаются в журнале; старые записи в базе переписаны. Фото объекта теперь выбирается в карточке материала, а не только при создании: пост умеет рисоваться от настоящей фотографии. Починены стили выбора фото и просмотрщика, которых в проекте не было вовсе.
→ Дождаться второго ролика. Обсудить модель видео: veo-3.1 стоит 250 кредитов за ролик, при балансе 525 это два ролика. Проверить публикацию после генерации.
Ролики не снимались вообще: в таблице моделей стоял слаг wan/2-7-text-to-video, а конвейер всегда шлёт первый кадр, Kie отбивал запрос (в журнале расходов video wan-2.7 по 0 кредитов). Слаг исправлен, добавлен Veo 3.1 Lite. По решению владельца ванские задания отменены (6 штук, из них 5 дублей на одном материале), материалы возвращены в одобренные, пауза расходов снята, выбрана модель Veo 3.1. Перенесена защита слотами на Veo и Wan ветки, добавлен вызов продления, которого в проекте не было. Закрыты общие дыры: публикация без памяти о доставленном, уборка медиа без оглядки на базу, оживание отменённых заданий.
→ Живой прогон ролика на Veo 3.1 за владельцем: очередь пустая, автопилот выключен, панель сама ничего не запустит. Не проверялись публикация и аналитика.
Прогон тестера по обоим проектам без единой генерации: авторизация, мусор в ручки, границы, геометрия на 1440 и 390, фаззинг кнопок и окон. Найдено и закрыто восемь вещей: падение контент-плана от выдуманного часового пояса (500), горизонтальная прокрутка плана на телефоне, двойной клик отправлял два-три запроса, английские сообщения валидации у клиента, Esc не закрывал окна, мелкие цели на телефоне, дубль кнопок действий в списках, и обрыв связи при сборке плана на несколько дней.
→ Платные пути не проверялись по запрету владельца: генерация каждого типа, публикация, аватары. Остались мелочи: 8 пикселей горизонтальной прокрутки на плане в навесах на узком экране, чекбоксы выделения 16 пикселей на телефоне.
То же, что и на заводе навесов: разделы разложены по дням с переключателем порядка, сценарий теперь пишется под реальную длину ролика (в промпт идут длина, число сцен и потолок слов). Раньше при модели на 8-15 секунд сценарий расписывался до 50 секунд.
→ Живой платный прогон одного материала каждого типа после отмашки владельца.
Правки по замечаниям: карусель не проходила в сборку плана (схема ручки знала только post, video, avatar) — добавлена в /api/plan/generate и /api/items/batch, проверено живьём. Карточка материала переписана понятнее: подпись поля зависит от формата (текст поста, план слайдов, что говорит аватар, сценарий ролика: что в кадре и что говорит голос), подпись под публикацией названа прямо, у готовой карусели появился список слайдов с картинками и текстами, клик по строке показывает слайд. Убраны режимы работы, добавлены кнопки создания в разделах, сборка плана получила карусели и период дней, у каждой идеи в плане свои действия по состоянию. Поправлена вёрстка: поля в настройках прыгали лесенкой из-за выравнивания по нижнему краю.
→ Живой платный прогон одного материала каждого типа после отмашки владельца: пока проверялись только бесплатные пути (планы, действия, вёрстка). Ударения в озвучке не подключены, голос идёт через HeyGen.
Правки по замечаниям владельца. Убраны режимы работы (ручной, полуавтомат, автомат) из настроек, планировщика и агентов: панель всегда пишет сама, учится на правках, идея ждёт одобрения. В каждый раздел добавлена кнопка создания материала. Сборка плана через ИИ переделана: все четыре формата включая карусели и период от одного до тридцати дней вместо строки на один день. Действия вынесены в общий ItemActions и стоят у каждой идеи в контент-плане по её состоянию: одобрить, сгенерировать, опубликовать, переделать, в архив. Плюс перенос с завода навесов: антиповторы тем, углы подачи, ротация доводов о компании.
→ Живой платный прогон одного материала каждого типа после отмашки владельца. Ударения в озвучке не подключены: голос идёт через HeyGen, поведение знака ударения не проверено.
Паритет с заводом навесов перед встречей. Перенесены: техническая достоверность (правила во всех промтах, зрячий контролёр, кнопка «Проверить технически», поле techNote), работа пачкой (выделение, массовые действия, «Одобрить все идеи», подтверждение перед пакетной генерацией). Вычищена чужая тематика: в интерфейсе и промтах не осталось навесов, везде нейтральное «объект». Типы проходят, образ пересобран, схема применена, :3131 отвечает, ручка bulk проверена живьём.
→ Живой платный прогон одного материала каждого типа после отмашки владельца. Ударения в озвучке не подключены: голос идёт через HeyGen, поведение знака ударения там не проверено.
Полный перенос из завода навесов к встрече с клиентом. Добавлены карусели как формат со своим разделом, библиотека фотографий объектов с загрузкой пачкой, свои фото в материалах (картинка собирается правкой фото клиента), стоп-темы с проверкой после генерации, три режима работы, просмотр материала с проигрывателем и листанием слайдов, длинные ролики до 45 секунд с режиссёром сцен и склейкой по последнему кадру. Схема применена через db push, снимок базы снят до правки. Типы проходят, все девять страниц отвечают 200, стоп-темы на живой проверке ловят 3 из 3 запрещённых фраз и не трогают нормальный текст.
→ Ключи в панели клиента, живых генераций не запускал: это его деньги. Не перенесены ударения в озвучке (голос идёт через HeyGen, знак ударения с их движком не проверен) и прайс в интерфейсе (по решению владельца его тут нет).
Ревизия по стандартам завода навесов и перенос ядра надёжности. Проект оказался нетронутым: ноль расходов, ноль заданий, пять идей с 29 июля, то есть ни одной платной генерации не было и ни одна из найденных ошибок ещё не выстрелила. Перенесено: идемпотентная задача у провайдера, отделение ожидания от провала, запрет повтора после списания, чистый учёт при ожидании, очередь на две полосы. Плюс правила речи (только русская, реплика кириллицей, надписи в кадре запрещены) и исправлено поле образца input_urls. Написан docs/STANDARDS.md. Типы проходят, оба контейнера перезапущены, вход отвечает 200.
→ Проект простаивает две недели. Если оживёт, переносить дальше: стоп-темы, ударения, склейки с удержанием кадра, карусели. Ключи в панели заданы клиентом, ключ Upload-Post не наш, чужих профилей клиент не увидит.
Правки по фидбеку. (1) Кнопка «Добавить свои идеи» вынесена в шапку контент-плана. Модалка получила два режима: одна идея с подробностями или пачка тем строками, где каждая строка становится отдельным материалом. Пустые строки и повторы внутри пачки отбрасываются, счётчик на кнопке показывает сколько получится. Добавлен тумблер «раскидать по дням подряд, по одной в день», иначе всё падает на одну дату с разным временем из окон публикации. Новый эндпоинт POST /api/items/batch. ПРОВЕРЕНО curl-ом снаружи: 5 строк с пустой и дублем дали created=3, skipped=2, в базе три материала на 5, 6 и 7 августа по 10:00 МСК. (2) Стрелки листания месяцев убраны по просьбе владельца: они перезагружали страницу и сбрасывали выбранный вид. Вместо них компактный выбор месяца, иначе прошлые месяцы стали бы недоступны, а архив был в исходных требованиях. Заголовок больше не дублирует месяц.
→ Панель открыта: http://80.90.184.203:3131, пароль FSaFH5xkg9cuHD. Владелец пересылает клиенту на осмотр. От клиента: пополнить баланс Kie, привязать соцсети к профилю Content-zavod в Upload-Post, токен и номер сообщества VK, токен телеграм-бота с каналом и чатом согласования, лицо и голос в HeyGen, заполнить бриф. Дальше спринт 2, живые прогоны генерации, только по явному «ок, трачу».
ПАНЕЛЬ ОТКРЫТА СНАРУЖИ: http://80.90.184.203:3131. В .env добавлен BIND_HOST=0.0.0.0, APP_URL переставлен на внешний адрес, контейнер перезапущен. Правку ufw не потребовалось: docker публикует порт мимо него. ПРОВЕРЕНО с внешней машины через curl: POST /api/auth/login отдаёт 200 и ставит сессионную куку, страницы /, /plan, /video, /settings, /brief, /schedule отдают 200 с кукой, /settings без куки отдаёт 307 на вход. Пароль FSaFH5xkg9cuHD (лежит в /opt/zavod-order/.env). Ничего платного не запускалось.
→ Владелец пересылает адрес клиенту на осмотр. От клиента ждём: пополнение баланса Kie, привязку соцсетей к профилю Content-zavod в кабинете Upload-Post, токен и номер сообщества VK, токен телеграм-бота с каналом и чатом согласования, лицо и голос аватара в HeyGen, заполненный бриф. После этого спринт 2: живые прогоны генерации (платно, только по явному ок). Безопасность: сейчас голый HTTP, пароль летит открытым текстом. На постоянку нужен домен с сертификатом.
Три правки по фидбеку. (1) Продукт переименован в «Альфа центр», название вынесено в lib/brand.ts, в коде не дублируется. (2) Профиль Upload-Post больше не вводится руками: список профилей и подключённых к ним аккаунтов тянется из кабинета по API, профиль выбирается из выпадающего списка, сети отмечаются галочками, выбор сохраняется в SocialAccount и становится набором по умолчанию для публикаций. VK и Telegram показаны отдельной группой «напрямую, мимо Upload-Post» с пометкой, что токена нет. ПРОВЕРЕНО на живом ключе владельца: подтянулся профиль Content-zavod, у него 0 подключённых аккаунтов. (3) Подготовлено открытие панели по IP: в compose добавлена переменная BIND_HOST (по умолчанию 127.0.0.1, чтобы на сервере клиента панель не оказалась в открытом интернете случайно).
→ 🔴 ОТКРЫТИЕ ПОРТА НЕ ВЫПОЛНЕНО: команды на BIND_HOST=0.0.0.0 и ufw allow 3131 заблокированы классификатором безопасности, нужно явное разрешение владельца. После разрешения: BIND_HOST=0.0.0.0 в .env, docker compose up -d, ufw allow 3131/tcp. Адрес будет http://80.90.184.203:3131, пароль в /opt/zavod-order/.env. 🔴 В кабинете Upload-Post у профиля Content-zavod НЕТ подключённых соцсетей, публиковать пока некуда. 🔴 Баланс Kie 33 кредита, на генерацию не хватит. Платные тесты не запускались.
Волна правок по фидбеку владельца. (1) ЦЕНЫ УБРАНЫ полностью: таблица ModelPrice удалена, вместо неё читаем баланс Kie и HeyGen до и после генерации и пишем фактическое списание в кредитах. Лимиты переведены в кредиты плюс добавлен стоп при остатке ниже порога. Баланс Kie выведен на обзор и в настройки, читается живьём. (2) КОНТЕНТ-ПЛАН: два вида, календарь и список, переключатель в шапке; в списке идея, хук, рубрика, время, признаки готовности, фильтр по типу. (3) ИИ-АГЕНТЫ: четыре раздельных (планировщик, хуки, сценарист, описания), каждый запуск сохраняется в AgentRun, в карточке вкладка «Работа агентов» с моделью, токенами, запросом и ответом. Хуки даются пятью вариантами, любой ставится основным одним кликом. (4) ФИКС: у жёлтых кнопок при наведении был тёмный текст на тёмном фоне, причина в специфичности .btn:hover выше .btn.primary; исправлено и проверено скриншотом. Владелец вписал 4 ключа через панель (OpenAI, Kie, HeyGen, Upload-Post), агент хуков отработал на живом ключе.
→ 🔴 БАЛАНС KIE 33 КРЕДИТА, это почти пусто: генерация видео и картинок не пройдёт, нужно пополнить. 🔴 UPLOADPOST_USER не задан, без имени профиля Upload-Post не заработает. VK и Telegram тоже без токенов. 🔴 Доступ снаружи по-прежнему закрыт: нужна A-запись поддомена или разрешение открыть порт. Платные тесты генерации НЕ запускались, жду явного «ок, трачу» от владельца.
Собран и развёрнут работающий каркас на cfru: /opt/zavod-order, docker compose (app+worker+postgres+redis), приложение на 127.0.0.1:3131. Next 15 + Prisma 6 + BullMQ. Сознательно без next standalone, чтобы не ловить 404 на статике. СДЕЛАНО И ПРОВЕРЕНО ВЖИВУЮ: вход по паролю и закрытие всего middleware (страницы 307, API 401); дашборд с 8 разделами отдельными маршрутами в стилистике демо (скриншоты сняты); календарь контент-плана с листанием месяцев; ручное создание идеи (запись легла в базу); часовой пояс (10:00 МСК = 07:00 UTC); очередь с повторами; ДЕНЬГИ: списание до генерации, падение, ВОЗВРАТ, всё подтверждено записями в базе. ПО ПРОСЬБЕ ВЛАДЕЛЬЦА добавлен раздел ключей прямо в панели: OpenAI, Kie, HeyGen, Upload-Post, VK, Telegram вписываются в интерфейсе, хранятся в базе зашифрованными AES-256-GCM на SESSION_SECRET, обратно не показываются (только маска последних символов), подхватываются без перезапуска. Проверено: в базе шифротекст, открытого значения нет, провайдер увидел ключ, кнопка стирания работает. Тестовые данные вычищены. Написаны docs: README, ARCHITECTURE, ACCEPTANCE, DECISIONS, HANDOVER.
→ БЛОКЕР ДОСТУПА: приложение слушает только 127.0.0.1, снаружи владелец его не видит. Нужно решение: либо A-запись zavod.myvisionagency.ru на 80.90.184.203 (wildcard DNS нет, домены заводятся поштучно) и тогда nginx + сертификат, либо временно открыть порт по IP. Пароль входа лежит в /opt/zavod-order/.env (APP_PASSWORD). После доступа: владелец вписывает ключи в настройках, и проверяем живьём генерацию плана, поста, видео и аватара, затем публикацию и первый комментарий по каждой сети. Цены моделей в базе ПРЕДВАРИТЕЛЬНЫЕ, сверить со счетами провайдеров до боевого запуска.
Старт проекта. Развилки сняты с владельцем: новый проект с нуля (не часть SaaS КЗ), частный заказ с возможным переносом на сервер клиента, дашборд с переключением страниц в стилистике демо content-zavod/demo, одна компания и один вход, технический поддомен с HTTPS, планы через прямой ключ OpenAI клиента по прокси, контент через Kie, аватары HeyGen за счёт клиента, VK прямым API, Rutube не нужен. Заведён роадмап: 4 спринта, 32 задачи. Написаны docs локально в 'E:\Проекты для Гитхаба\Контент Завод под заказ': README, ARCHITECTURE, ACCEPTANCE (поведенческие критерии по спринтам), DECISIONS (решения, факты, открытые вопросы с дефолтами), HANDOVER (перенос). Разведка: cfru свободен по ресурсам (23ГБ RAM, 141ГБ диска), токены дизайна сняты с демо. ПРОВЕРЕНО КОДОМ: 'ссылка первым комментарием' в КЗ НЕ реализована (флаг пишется в БД, при публикации не читается, comments-эндпоинт нигде не вызывается) — задача идёт как новая разработка. Донорские модули из КЗ отмечены: kie-ai/client, studio/kie-ai-studio, smm/client (VK+TG), video/ffmpeg-utils, inngest/item-publish. Код НЕ начат по ритуалу спринт-кикоффа.
→ Ждём от владельца: 'ок' на план спринта 1 и имя технического поддомена (предложен zavod.myvisionagency.ru). После 'ок' — репозиторий, docker-compose (app/worker/postgres/redis), дизайн-система из демо, шелл дашборда с входом по паролю, схема Prisma, календарь контент-плана. К спринту 2 нужны ключи: OpenAI клиента, Kie, HeyGen, плюс лицо и голос аватара и цифры лимитов расходов.