Я пересобрал два легаси-сайта и ни разу не открыл код

от автора

Интернет-магазин на WordPress, написанный подрядчиком десять лет назад: разбираться в нём не нашлось желающих даже за деньги. Лендинг на Тильде, где любая задача сложнее пары блоков упиралась в потолок конструктора. Сейчас оба живут на собственном коде: у лендинга появилось мобильное приложение, а новые фичи в магазине делаются промптом за вечер. Ручной работы на каждый переезд ушло около дня, и за всё это время я не открыл ни одного файла с кодом. Расскажу, как это устроено и где у подхода границы.

Тот самый легаси, которого у всех полно

Сразу откалибрую масштаб. Финтеха с миллионом пользователей, про который я писал в прошлый раз, здесь не будет: витрина и магазин. Зато ровно такого легаси в стране тысячи, и звучит оно всегда одинаково.

История магазина. Сайт на WordPress написал подрядчик лет десять назад. С тех пор подрядчики менялись, периодически терялись, и приходилось искать новых, каждый раз заново объясняя, что где лежит. Когда компания решила навести порядок, она собрала 3 коммерческих предложения на восстановление, каждое от 100 000 рублей. До дела не дошло ни одно.

История лендинга. Его когда-то собрал на Тильде маркетолог, без единого разработчика рядом, и всё отлично работало, пока задачи были уровня «перенести блок». Дальше затык: часть фич конструктор не тянет в принципе, сколько ни плати.

Проекты друг с другом никак не связаны, кроме того, что оба попали ко мне. Оба для меня побочные: лендинг наш собственный, магазин принесли знакомые. Основная работа у меня другая, про неё была первая статья. И оба проекта мы пересобрали одним способом.

Как не надо

Первое, что пробует любой: скормить проект нейронке и попросить «перепиши всё на нормальном стеке». Мы попробовали. Получили сырой сайт, которым невозможно пользоваться. Часть логики потерялась, часть переехала криво, а найти, где именно, нельзя: исходную логику никто никогда не описывал.

Вывод из этого провала простой. Нейронке нельзя отдавать легаси в лоб. Сначала она должна его понять.

Трюк: нейронка пишет ТЗ сама себе

Порядок такой:

  1. Забрали исходники.

  2. Подняли текущее рабочее состояние сайта.

  3. Отправили нейронку составлять ТЗ. Для самой себя.

Весь смысл в третьем шаге. Нейронка собирает файл BUSINESS_LOGIC.md, куда переносит бизнес-логику проекта целиком. Сначала вытаскивает её из кода. Потом прогоняет живой сайт через UI и сверяет описанное с тем, что реально происходит на экране. Расхождения между «как написано» и «как работает» и есть те места, где легаси обычно взрывается.

В промпт на этот этап зашито несколько правил, подсмотренных у живых аналитиков:

  • у любой находки есть источник: строка кода, экран, поле в базе. Догадки помечаются как догадки и уходят в отдельный список вопросов;

  • глупые вопросы это работа. Агент переспрашивает очевидное и сомневается в привычном, чтобы неточности всплыли до старта разработки;

  • сначала домен, потом код. Разбор начинается с бизнес-процессов и доменной модели. Фреймворк подождёт.

Полный промпт этого этапа со всеми правилами и форматом выходных документов лежит под спойлером в конце статьи, забирайте.

На выходе у заказчика впервые появляется его собственный продукт, описанный целиком и по пунктам.

Пересборка вместо переезда

Готовое ТЗ можно молча унести в разработку. Мы вместо этого оба раза отдали его заказчику.

И тут выяснилось, зачем. Заказчик впервые видел свой продукт описанным целиком. Поверх зафиксированного «как есть» нейронка отдельным списком предложила пару фич от себя: в само ТЗ добавлять улучшения ей запрещено, на это в промпте есть правило. А заказчик, глядя на полную картину, начал вспоминать боли, которые копились годами и до которых на старом движке руки не доходили.

Так в ТЗ, кроме старой логики, попали вещи, которых на прежних движках не могло появиться в принципе. У лендинга: API и отдельное мобильное приложение, которое часть функций забрало себе. У магазина: роли и доступы для админов и система отчётов с дашбордами, о которой менеджмент раньше только мечтал.

Как я доверился коду, который не читал

Теперь неудобный вопрос, который вы уже держите в голове: ты выкатил в прод чужой магазин на коде, который сам не открывал. Ты вообще нормальный?

Отвечаю. Коду я не доверял. Я доверял поведению и тестам.

Цикл разработки замкнут на самопроверку. Нейронка гоняет новый сайт через UI и сравнивает с оригиналом, пока не добьётся сходства один в один: тот же интерфейс, то же поведение на тех же данных. После функционального тестирования идёт нефункциональное: ошибки, граничные состояния, нагрузка. Сверху покрытие тестами.

Технически всё это делал Claude Code. UI-прогоны он вёл сам через расширение в Chrome: открывал старый сайт и новую версию, проходил сценарии и сравнивал результат. Я в эту петлю не вмешивался, пока она не сходилась.

Важная оговорка, чтобы не выглядело нотариусом, который заверяет собственную подпись: финальная приёмка была не за агентом. Весь путь по обоим сайтам мы прошли руками, вместе с заказчиком. Нашли пару косяков, закрыли их ещё двумя промптами.

Про платежи сразу: магазин работает в B2B, оплата всегда шла через менеджера, эквайринга на сайте нет. Проверять платёжку UI-дифом не пришлось, её просто нет. С данными тоже без драмы: забрали базу старого магазина и перенесли, товары и заказы на месте, каталог сверился тем же UI-дифом.

Моя работа была слоем выше. Я читал ТЗ и архитектурные документы, гонял 2 итерации тестирования и одну итерацию правок между ними. Стек нового проекта, Node.js и React, знаю только из архитектурного документа. Оба запуска прошли гладко: всплыли мелкие UI-правки, работы на вечер.

Что изменилось после переезда

Самое важное в этой истории случилось уже после запуска, поэтому про «стало» подробно.

Магазин. Раньше любая доработка означала поиск подрядчика: найти человека, договориться, заплатить, подождать, надеяться, что он не пропадёт на середине. После переезда заказчик уже пересобрал главную страницу, обновил контент с картинками и добавил новые фильтры в каталог. Каждая такая задача теперь занимает вечер: нейронка работает с кодом, который сама же написала и задокументировала. Заодно, кстати, закрылся и вопрос надёжности: логи и тесты заложены с первого дня, так что если сайт ведёт себя странно, видно, что случилось и кто чинит.

Лендинг. Сразу честно про деньги: подписка Тильды стоила 15 тысяч в год, новый хостинг стоит 700 рублей в месяц. Экономия около нуля, и уезжали мы за другим: за фичами, которые конструктор не тянул ни за какие деньги. Мобильное приложение, о котором при Тильде нельзя было даже заводить разговор, теперь просто есть.

Порог доработки упал с «ищем подрядчика за 100 тысяч» до «пишем промпт». Ради этого всё и затевалось. Сайт перестал быть вещью, которую страшно трогать.

Кто на самом деле тормозил

Одно наблюдение напоследок. Ручной работы по дню на проект, а календарём лендинг занял 2 недели, магазин полгода. Куда делось время? В заказчика. С лендингом определились быстро, владельцы магазина полгода перепридумывали, что им вообще нужно, и переписывали требования по кругу.

Раньше за спиной медленного заказчика стояли месяцы разработки, и его тормоза терялись на общем фоне. Теперь разработка занимает день, и стало видно, что весь срок держит скорость решений на стороне бизнеса. Разогнали самую дорогую часть работы и обнаружили, что дорого было в другом месте.

Где так делать не стоит

На двух проектах зашло. Это не повод делать так везде. Открытых вопросов я вижу минимум два.

Первый: поддержка кода, который никто не читал. Сейчас всё работает, покрыто тестами и дорабатывается без проблем. Когда через год прилетит по-настоящему хитрый баг, разбираться придётся с нуля, и почём это выйдет, я честно не знаю. Порог у меня простой: баг, который не объясняют ни тесты, ни логи, означает, что пора сесть и прочитать код. Восстановленное ТЗ и тесты сделают это погружение дешевле, чем в классическом легаси. Бесплатным не сделают.

Второй: UI-диф ловит только то, что можно увидеть и прокликать. Редкие граничные сценарии, не попавшие в тесты, он пропустит. Витрина и магазин такое переживут. Систему, где за ошибкой стоят деньги или жизнь, я бы так не пересобирал.

Третье признание: отдельного аудита безопасности мы не делали. Нефункциональные прогоны ловили ошибки и граничные состояния, но пентеста по новой админке не было. Для витрины и B2B-магазина, где оплата идёт через менеджера, мы сочли риск приемлемым. Для чего-то с онлайн-платежами или чувствительными данными это блокер, и там я бы начал с аудита.

И общее ограничение: методу нужно живое состояние. Что-то, что можно запустить, прокликать и с чем сверять. Продукт, который существует только в голове заказчика, так не мигрируешь: сверять не с чем.

Если захотите повторить

  1. Поднять текущее состояние легаси, забрать исходники.

  2. Нейронка пишет BUSINESS_LOGIC.md: логика сначала из кода, потом сверка через UI. Промпт целиком в спойлере ниже.

  3. Нейронка предлагает архитектуру и стек.

  4. ТЗ уходит заказчику: валидация, новые фичи, забытые боли.

  5. Разработка. Логирование и мультиязычность закладываются с первого дня.

  6. UI-диф до сходства один в один, потом нефункциональное тестирование и покрытие тестами.

  7. Итерация правок с бизнесом, вторая версия.

Пайплайн миграции: реверс-ТЗ, архитектура, разработка, UI-диф, тесты, приёмка

Пайплайн миграции: реверс-ТЗ, архитектура, разработка, UI-диф, тесты, приёмка

Из инструментов хватило Claude Code и расширения для Chrome. Токены обеих миграций уложились в стандартную подписку, в лимиты мы не упёрлись.

Промпт первого этапа целиком

Роль. Ты системный аналитик и реверс-инженер. Тебе дали чужой легаси-проект без документации. Восстанови его бизнес-логику из двух источников: исходного кода и поведения живого продукта в UI. Результат будет использован, чтобы переписать продукт с нуля на новом стеке. Всё, что ты потеряешь или переврёшь, потеряется в новой версии.

Цель. Собрать комплект документов, в центре которого BUSINESS_LOGIC.md с полной бизнес-логикой продукта. Каждое утверждение должно быть проверяемым и иметь источник.

Железные правила

  1. Доказательная база. У любого утверждения есть источник: ссылка на код (путь/файл:строка), экран и действие в UI или поле в БД. Утверждение без источника не пишется.

  2. Факт и догадка помечаются по-разному. Подтверждено кодом: 🟢. Видно только в UI или только в коде: 🟡. Домыслено по косвенным признакам: 🔴. Домыслы не выдаются за факты никогда.

  3. Не выдумывать. Если логику установить нельзя, пиши «не установлено» и заводи пункт в списке открытых вопросов. Пустое место честнее правдоподобной выдумки.

  4. Неудобные вопросы — часть работы. Переспрашивай очевидное, сомневайся в привычном, ищи противоречия между кодом и UI. Всё сомнительное идёт в OPEN_QUESTIONS.md до старта разработки.

  5. Сначала домен, потом код. Начинай с бизнес-процессов, сущностей и терминов. Детали реализации — второй слой.

  6. Сверка в обе стороны. Логику из кода проверяй прогоном через UI. Логику из UI ищи в коде. Расхождения между «как написано» и «как работает» фиксируй отдельно: это самые опасные места миграции.

  7. Гигиена данных. Не переноси в документы секреты, ключи и реальные персональные данные. Описывай структуру и правила, не значения.

Выходные файлы (каталог /docs): BUSINESS_LOGIC.md (сценарии, правила, состояния, расчёты), DOMAIN.md (глоссарий и доменная модель), FEATURES.md (карта экранов по ролям), INTEGRATIONS.md (внешние интеграции, фоновые задачи, уведомления), DISCREPANCIES.md (расхождения код/UI), OPEN_QUESTIONS.md (вопросы заказчику).

Формат бизнес-правила:

### BR-001. Короткое имя правила- Статус: 🟢 | 🟡 | 🔴- Когда срабатывает: <триггер или условие>- Что происходит: <поведение, значения, расчёт>- Источник: <файл:строка> ; <UI: экран -> действие> ; <db: таблица.поле>- Открытые вопросы: <ссылка на пункт в OPEN_QUESTIONS.md>

Процесс по фазам. Фаза 0, инвентаризация: структура репозитория, точки входа, роуты, модели, схема БД, конфиги; параллельно пройди продукт под каждой ролью и составь список экранов. Фаза 1, домен: сущности, связи, глоссарий, ключевые бизнес-процессы верхнеуровнево. Фаза 2, пофичный разбор: для каждой фичи логика сначала из кода, потом воспроизведение в живом UI и сверка; проверяй валидации, граничные значения, сообщения об ошибках, пустые состояния. Фаза 3, сквозное: роли и доступы, деньги, статусы и переходы, фоновые задачи, уведомления, интеграции. Фаза 4, сборка: собери BUSINESS_LOGIC.md целиком, попробуй поднять все 🔴 и 🟡 до 🟢 дополнительной сверкой, остальное оформи вопросами.

Протокол UI-сверки. Заходишь под нужной ролью, выполняешь действие описанными шагами, фиксируешь фактический результат и сравниваешь с ожиданием из кода. Проверяй не только счастливый путь: пустые формы, невалидный ввод, доступ не под своей ролью.

Самопроверка перед сдачей. Каждое утверждение имеет источник. У каждого правила есть статус. Каждый экран разобран или явно помечен «логики нет, статика». Все расхождения в DISCREPANCIES.md. В OPEN_QUESTIONS.md нет «наверное» без вопроса заказчику. В документах нет секретов и персональных данных.

Чего не делать. Не улучшать продукт и не предлагать стек на этом этапе: только фиксация «как есть». Не сглаживать странности: странность документируется как странность. Не считать код истиной в последней инстанции: если UI ведёт себя иначе, это не ошибка UI, это находка.

Цифры

  • Проектов: 2, друг с другом не связаны.

  • Ручной работы: ~1 рабочий день на проект.

  • Автоматизировано от объёма миграции: ~80% (оценка на глаз, трекера с секундомером не было).

  • Лендинг: Тильда ~15 000 ₽/год, новый хостинг 700 ₽/мес. Экономия около нуля, переезд ради фич.

  • Магазин: стартовая вилка 3 КП от 100 000 рублей, до дела не дошло ни одно.

  • Доработки после запуска (новая главная, фильтры каталога, контент): вечер на задачу, без подрядчиков.

  • Календарём: лендинг 2 недели, магазин полгода. Всё сверх дня работы держал заказчик.

  • Расходы на нейронку: стандартная подписка, лимиты не выжжены.

  • Строк кода, прочитанных мной: 0.

  • Откатов после запуска: 0 (справедливости ради, и ставки невысокие: витрина и B2B без онлайн-оплаты).

Что я вынес из двух переездов

  1. Легаси проще пересобрать по восстановленному ТЗ, чем чинить вслепую. Наивное «перепиши на нормальном стеке» даёт кашу.

  2. Восстановленное ТЗ ценнее самой миграции. Заказчик впервые видит продукт целиком и начинает чинить то, до чего годами не доходили руки.

  3. Доверие переезжает с кода на тесты и поведение. Если UI-диф сошёлся один в один и тесты зелёные, читать код становится необязательно. Со всеми оговорками из раздела про границы.

  4. Главный результат миграции: у сайта исчез статус «трогать страшно». Код, который нейронка написала и задокументировала, она же и дорабатывает. Пропавший подрядчик больше не приговор.

Вопрос к вам: у кого живёт сайт, который страшно трогать? Что мешает пересобрать: техника, деньги или «работает же»? Расскажите в комментариях.

Кухню про нейронку в разработке и цену граблей пишу в канале «НейроCTO»: https://t.me/n_cto

ссылка на оригинал статьи https://habr.com/ru/articles/1063738/