Как спасти vibe-coded приложение для продакшена
Переписывание нужно редко — нужен скучный продакшен-слой, который AI пропустил. Вот пять вещей, которые vibe-coded приложение делает не так, и порядок, в котором я их чиню.

Спасти vibe-coded приложение для продакшена удаётся гораздо чаще, чем оправдать переписывание с нуля. Демо работает. Кнопки нажимаются. Друг попробовал и впечатлился. А потом регистрируется реальный пользователь, проходит первый платёж — и всё рушится. Такие передачи проектов прилетают ко мне регулярно: основатель собрал рабочий прототип за выходные с помощью AI-инструмента, привлёк немного денег или нашёл первого клиента, и теперь приложению нужно выжить при встрече с публичным интернетом. Код — почти никогда не проблема. Не хватает скучного продакшен-слоя, который AI тихо пропустил. И встроить этот слой — задача для senior-инженера, а не ещё один промпт.
Почему демо обманывает
Демо доказывает, что один сценарий срабатывает один раз, для одного человека, на одной машине, без денег и без атакующего. Продакшен — противоположность по всем четырём пунктам. Он прогоняет несчастливые пути, для незнакомцев, на инфраструктуре, которую вы не контролируете, с реальными платежами и реальными злоумышленниками, которые ковыряют каждый эндпоинт.
AI-инструменты для кода отлично делают демо и структурно слепы ко всему остальному. Они оптимизируют под «пусть экран сделает то, что я попросил», потому что именно это вы видите и одобряете в чате. Никто не пишет в промпте «и заодно ротируй утёкший API-ключ, добавь индекс в базе и проверь подпись Stripe-вебхука» — поэтому ничего из этого не появляется. Модель не ленится. Она даёт ровно то, что вы попросили, а попросили вы демо. Этот разрыв остаётся невидимым, пока его не найдёт трафик, — поэтому работа по спасению начинается с того, чтобы точно его назвать.

Пять вещей, которые vibe-coded приложение делает не так
В проектах, которые я подхватываю, почти всегда всплывают одни и те же пять дыр. Это тот хребет, который я проверяю первым, и это тот же список, по которому я иду в услуге по спасению vibe-coded приложений.
Auth: токены в localStorage
AI собирает рабочий логин, а потом кладёт токен сессии в localStorage, потому что это путь наименьшего сопротивления. Теперь любой межсайтовый скрипт на вашей странице может его прочитать, а украденный токен — это украденный аккаунт. Сессии должны жить в httpOnly cookies с разумным сроком жизни и с настоящим выходом, который инвалидирует сессию на сервере. Это самая частая дыра и самая опасная.
Secrets: API-ключи в клиентском бандле
«Работает на моей машине» обычно означает, что ключи захардкожены где-то удобно — а удобно часто значит в браузерном бандле. Ваш секретный ключ Stripe, URL базы данных, токены сторонних сервисов уезжают в dev tools каждого посетителя. Решение — настоящее разделение окружений: секреты остаются на сервере, утёкшие немедленно ротируются, и ничего чувствительного не уходит на клиент.
Data: нет индексов и N+1 запросы
База нормально работает на двенадцати строках, на которых вы тестировали. Потом список, который грузит каждую связанную запись отдельным запросом, встречает тысячу строк — и страница открывается девять секунд. Нет индексов на колонках, по которым вы фильтруете и сортируете, запросы внутри циклов, нет пагинации. В демо этого не видно, потому что в демо нет данных. И всё это становится видно в ту неделю, когда приходят пользователи.
Payments: непроверенные вебхуки
Флоу оплаты выглядит готовым — деньги двигаются, страница успеха рендерится. Но вебхук, подтверждающий платёж, не проверяет подпись, так что любой, кто найдёт эндпоинт, может отправить POST с поддельным событием «оплачено» и получить продукт бесплатно. Хуже того, приложение часто выдаёт доступ на клиентском редиректе, а не на проверенном серверном событии, так что закрытая вкладка означает оплаченный заказ, который так и не провижинится. Платежи — это место, где непроверенное доверие напрямую превращается в потерянные деньги.
Deploys: работает на моей машине
Нет staging-окружения, нет миграций, нет отката. Деплой — это зайти по SSH и подтянуть main или нажать кнопку без возможности вернуться, если что-то сломалось. Первый плохой деплой кладёт всё целиком без отмены. Прежде чем трогать что-то ещё, я чиню именно это — потому что нельзя безопасно починить остальные четыре пункта без места для тестов и способа откатиться.

Спасение, а не переписывание — в каком порядке я чиню
Инстинкт при получении грязного кода — выбросить его и начать с чистого листа. Этот инстинкт обычно ошибочен и всегда дорог. Рабочее приложение уже содержит реальные продуктовые решения и реальную обратную связь от пользователей. Моя задача — сделать его безопасным, а не сделать его своим. Поэтому я работаю в фиксированном порядке, safety-first:
- Version control и staging. Завести код в Git с чистой историей, поднять staging-окружение, которое зеркалит продакшен, добавить миграции и путь отката. Теперь любое последующее изменение обратимо. Без этого ничего больше не безопасно.
- Secure. Перенести секреты на сервер и ротировать всё, что утекло, починить auth и хранение сессий, закрыть вебхуки оплаты. Сначала остановить кровотечение, потом что-либо оптимизировать.
- Harden. Добавить индексы в базу, убить N+1 запросы, добавить пагинацию, валидацию ввода и rate limiting, подключить трекинг ошибок, чтобы узнавать о сбоях раньше, чем о них напишут пользователи.
Будь то Laravel на API или Next.js на фронтенде — порядок не меняется, меняются только детали. Это та же триажная логика, что я описывал в оценке за 48 часов: сначала снять неопределённость, а дальше работа становится арифметикой.
Переписывание с нуля нужно редко. Нужен скучный продакшен-слой, который AI пропустил, — а это решение senior-инженера, а не промпт.
Когда переписать действительно быстрее
Я бы соврал, сказав, что спасение всегда побеждает. Иногда честный ответ — переписать, и я скажу вам, когда это так.
Переписывайте, когда модель данных фундаментально неверна так, что от неё зависит каждая фича — починка фундамента всё равно означает переписывание всего сверху. Переписывайте, когда AI нагенерировал тысячи строк дублированного, нетипизированного спагетти без швов, за которые можно ухватиться, где каждое изменение рискует тремя регрессиями. Переписывайте, когда выбранный фреймворк не тянет туда, куда продукту нужно расти, или когда дыр в безопасности столько, что их аудит стоит дороже, чем начать заново.
Тест, которым я пользуюсь: смогу ли я внести следующие десять изменений безопасно и без страха? Если да — спасаем. Если каждое изменение это орёл-или-решка, код — это обуза, а не актив, и точечное переписывание ядра (сохранив продуктовые решения, выбросив реализацию) — путь дешевле. Суть в том, что это осознанное суждение от того, кто делал и то, и другое, а не рефлекс.
Что на самом деле значит «production-ready»
Production-ready — это не ощущение, это чек-лист. Секреты на сервере и ротированы. Auth на secure cookies с настоящей инвалидацией сессий. У базы есть индексы, нет N+1 запросов, есть пагинация. Вебхуки оплаты проверяют подпись, а доступ выдаётся на проверенных серверных событиях. Есть staging, миграции и откат. Ошибки трекаются и логируются. Ввод валидируется, эндпоинты под rate limiting. Бэкапы существуют, и вы хотя бы раз пробовали восстановиться из одного.

Ничего из этого не выглядит эффектно и ничего из этого не видно в демо. Именно поэтому AI это пропустил и именно поэтому это требует senior-инженера. Если вам нужна вторая пара рук, которая делала это на реальных продакшен-системах, — это работа fractional CTO и спасения vibe-coded приложений, которой я занимаюсь. А если вы агентство, которому нужно сделать это тихо под вашим именем, — это работа в формате white-label senior dev.
Частые вопросы
Vibe coding — это плохо?
Нет. Vibe coding — действительно хороший способ быстро дойти от идеи до рабочего прототипа, и я ежедневно пользуюсь AI-инструментами. Ошибка — считать прототип готовым. Он доказывает, что продукт стоит строить, но не делает безопасным выпуск к реальным пользователям и реальным деньгам. Используйте его, чтобы стартовать, а потом приведите кого-то, кто добавит продакшен-слой до запуска.
Переписать или починить моё AI-приложение?
В большинстве случаев — починить. Рабочее приложение уже содержит реальные продуктовые решения, поэтому выбрасывать его дорого и обычно не нужно. Переписывать стоит только когда модель данных фундаментально неверна, в коде нет швов для безопасных изменений или дыры в безопасности дороже аудитить, чем заменить. Решающий вопрос — сможете ли вы внести следующие десять изменений без страха.
Что ломается первым, когда AI-приложение попадает в продакшен?
Почти всегда одна из пяти вещей: токены сессии в `localStorage`, API-ключи в клиентском бандле, отсутствие индексов и N+1 запросы, вебхуки оплаты без проверки подписи, отсутствие staging или отката. Демо прячет все пять, потому что в нём нет реальных пользователей, реальных данных и атакующих.
Можно ли довести AI-собранный MVP до production-ready?
Да, и обычно это правильный ход. Путь такой: сначала version control и staging, затем безопасные auth, секреты и платежи, затем харденинг слоя данных и деплоев. Продуктовый код, который у вас уже есть, — это актив. Не хватает скучной инфраструктурной работы вокруг него, и её можно добавить, не начиная с нуля.
Сколько времени занимает спасение vibe-coded приложения?
Зависит от размера дыр, но критичные для безопасности правки — секреты, auth, проверка платежей — это обычно дни, а не недели, потому что список предсказуем. Харденинг данных и деплоев занимает чуть дольше. Я всегда начинаю с короткого аудита, чтобы сроки и стоимость были известны до начала работы, а не открыты в неопределённость.


