Привет, Хабр! Меня зовут Саша Мищенко, я тимлид платформенной команды в Профи.ру. Сегодня хочу поговорить о легаси — о том, как мы к нему относимся и как уживаемся в одной компании.

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

Вместо этого я хочу рассказать:

  • почему мы не переписываем код просто из-за того, что он старый;

  • как балансируем между быстрыми релизами и долговечной архитектурой;

  • какие фейлы происходят, когда команду уносит в одну из крайностей.

Поехали.

Зачем вообще снова говорить о легаси?

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

Это может пугать, расстраивать и дизморалить. Но легаси есть почти везде. Если код живёт достаточно долго, он становится частью истории продукта. Меняются разрабы, требования рынка, стек, а кодовая база, как верблюд, тянет на себе всё это разнообразие времён и подходов.

Есть пруфы: 64% важных для компаний инструментов написано на легаси. До сих пор! И у этого есть причина: золотое правило — «Не сломано — не трогай». 

25 лет назад Джоэл Спольски предостерёг разработчиков от полного переписывания кода, который работает. Всё ещё актуально (но не всегда).

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

Если уж и переписывать, то за что-то очень понятное и осязаемое: скорость поставки, безопасность, масштабирование. Да и то постепенно. 

Но иногда соблазн велик: выбросить всё, создать новую папку и на год исчезнуть в прекрасной новой архитектуре. Признайтесь, бывало такое желание? 

О фейлах и людях

Не буду говорить о старых известных кейсах вроде Netscape: хочется свежих историй.

14 июля Cloudflare уронила публичный резолвер 1.1.1.1 на 62 минуты. Корень проблемы — баг от 6 июня. Пока систему не трогали, он себя не проявлял. Но когда запустили общее обновление, то оно сузило список рабочих площадок до одной, тестовой. И она, естественно, была недоступна, потому что предназначена для теста. Отсюда и массовый сбой.

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

Из хорошего: в Cloudflare быстро восстановили анонсы по всему миру. Но, что самое главное, они написали подробный postmortem. Рассказали о том, что случилось и как так вышло. Это сработало, в основном пользователи даже не разозлились:

Или вот:

Есть и другой кейс, обезличенный, но не менее показательный. Пользователь ИТ-форума рассказал, как в его стартапе с выручкой $100 млн решили всё переписать на микросервисы на Ruby. 

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

По итогу вся эта авантюра съела весь раунд инвестиций (Series D) и три года разработки. Пу-пу-пу…

И в целом неудивительно. Нашёл исследование от VFunction за 2022 год, где говорится о том, что 79% попыток модернизировать кодовую базу проваливаются. Конечно, за три года ситуация могла измениться, но не факт, что в лучшую сторону. Может быть, риски и стали меньше благодаря возможностям ИИ, но сам человеческий подход остался прежним — 100%.

Делаю такой вывод из ещё одного свежего (почти) кейса

Ситуация. У компании есть легаси-дашборд: до первого рендера — около четырёх секунд ожидания с белыс экраном, а ещё старые виджеты. Приняли решение починить.

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

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

Из плюсов: вынесли важные уроки из этой ситуации и больше так не делают. Из минусов — всё остальное.

Модернизация с хорошим концом

Но мир легаси не без чудес. Вот парочка свежих примеров.

Весной 2025-го исследователи взяли большой кусок COBOL и прогнали его через LLM-пайплайн, чтобы получить эквивалент на Java. Чтобы было проще читать и легче масштабировать. 

Каждый файл при этом проверили через автотесты.

В итоге 93% переведённых модулей после сборки и тестов вели себя так же, как исходник. Для сравнения: ручками получилось ~75%. 

Да ещё и намного быстрее.

Не всё, конечно, шло гладко: иногда ИИ не справлялся и путался в коде. Но с такой точностью можно и потерпеть.

Почитать подробнее о кейсе можно тут.

Аналогичная история у Google. Благодаря LLM они смогли провести внутренние миграции и перейти с 32-битных цифр на 64-битные. Вручную это бы заняло вечность.

Как это делают профи

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

Пришло время рассказать не о том, как у других, а о том, как у нас. 

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

Продуктовые отвечают за новые фичи и поддержку действующего функционала — за всё, что видит или увидит пользователь.

Мы, платформенная команда, работаем на скорость и качество поставки этих фич: Development Experience, пайплайны, архитектурные правила, линтеры, пресеты, дизайн-система. 

Для чистоты архитектуры у нас есть несколько инструментов.

Живая база знаний с инструкциями. Это экономит часы и дни онбординга: прислал ссылку — и человек не дёргает коллег по пустякам. Косяки случаются, но мы над этим работаем.

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

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

Код-стайл. Автоматизируем всё что можно. У нас есть подход: если новое правило нельзя проверить и применить автоматически, велика вероятность, что оно не будет работать в реальности. Значит, мимо. В общем, стараемся использовать готовые пресеты, линтеры и codegen. 

Например, для контроля зависимостей в архитектуре используем eslint-plugin-boundaries, а для проверки кода — @typescript-eslint/recommended.

А ещё у нас есть Storybook. В нём мы делаем всё то же, что и остальные, плюс нашли бонусную фичу для тестирования. Например, если крестик у модалки не работает в продукте, тестировщик открывает компонент в Storybook, быстро понимает, что это (баг UI-Kit или продуктовой логики), и относит его туда, куда нужно. Минимизируем пин-понг, где QA отсылают то в один отдел, то в другой. 

А теперь о том, что у нас по легаси. 

Frontend: Redux → React Query + Jotai

У нас был тяжёлый, неповоротливый Redux с кучей мидлвар и пугающими редьюсерами. При архитектуре feature-sliced, а у нас именно такая, он только мешал. Мы понимали, что масштабировать его дороже и больнее, чем постепенно убрать. 

Теперь работаем на React Query для кеша и серверного состояния, а также на Jotai — для атомарных сторов. Получилось гибко, удобно и понятно. Но признаюсь, легаси-куски на Redux ещё кое-где остались. Пока что собираемся с силами, чтобы заглянуть в эти тёмные переулки.

Веб-платформа: кастом → Next.js

Когда я пришёл, у нас был фронтовый «монолит»: фронт и бэк рядом на Node, свой SSR, свой роутинг. Всё это очень долго собиралось и очень долго релизилось. 

Мы пытались не трогать базу, а просто прикручивали фичи поверх, но быстро поняли: лучше не надо. В итоге решили перейти на Next.js, а бэкенд увести в отдельные микросервисы на Node.js.

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

Но это красивые истории, где мы двигались осознанно. А есть история как раз о том, как не надо.

Пару лет назад писали новое клиентское приложение. Пилили фичи, а тесты оставили на потом. По итогу, когда отдали в QA, на нас обрушились около 200 багов — от функциональных до перформанса. 

Бизнес был недоволен, сроки выросли втрое, да и разработчиков это сильно демотивировало. Несколько спринтов потратили только на багфикс. Зато усвоили урок: расширили отдел QA и закрепили за каждой продуктовой зоной своего тестировщика. Больше не экспериментируем с пайплайном.

В общем, стараемся учиться на своих ошибках и думать на пару шагов вперёд. 

Хочу подытожить историей моего приятеля, ML-инженера из одной шведской компании.

На одном из проектов ему достался веб-сервис на Haskell, ещё до появления LLM. Код сложный — про алгоритмы вычислительной химии. Актуальной документации не было, и спросить не у кого: все старички ушли.

В итоге ему пришлось въезжать в код с нуля и пошагово разбираться в языке. В общем, ситуация показательная: сразу понимаешь, как делать не надо. С тех пор он расписывает задачи, пишет доки и никогда не предлагает в прод что-то супернестандартное, если не знает, кто будет этим владеть и кто будет это поддерживать через год. 

Мы поступаем так же. Это скучно звучит, но отлично работает.

Вместо вывода

Легаси — это нормально. Это показатель того, что ваш продукт прожил достаточно, чтобы обзавестись историей. А чтобы код при этом не превратился в болото, следите за: 

  • Скоростью и удобством разработки — CI/CD, выбор инструментов. 

  • Time to market — как быстро фича превращается из идеи в релиз.

  • Темпом онбординга и фидбэком от новых сотрудников по документации и кодстайлу.

Спасибо, что дочитали. Если у вас есть свои истории о том, как вы балансировали между скоростью и архитектурой, поделитесь в комментариях.

А я в ближайшее время планирую написать подробнее о том, как мы переезжали на RN. Думаю, будет интересно :-)

Комментарии (11)


  1. greenork
    12.08.2025 12:13

    На картинке со стулом должны быть пики


    1. Pumppeedd Автор
      12.08.2025 12:13

      Ну я уж не стал)))) хотя признаюсь, хотелось


  1. LeshaRB
    12.08.2025 12:13

    В картинке стул и велосипед, нет ли оптической иллюзии?
    Между рулем и сидением идет прямая, но стул как-то странно развернут


    1. Pumppeedd Автор
      12.08.2025 12:13

      Ага, там иллюзия стабильности


    1. elzvi
      12.08.2025 12:13

      ну это же в целом как та самая из говна и палок архитектура, которая соединяется черт пойми как, но создаёт иллюзию работы)) ну и справедливости ради чаще всего стабильно работает. до поры до времени


  1. Viacheslav01
    12.08.2025 12:13

    На КДПВ заказчик хотел мотоцикл?


    1. Pumppeedd Автор
      12.08.2025 12:13

      скорее стремянку на колесиках))


  1. dkuzminov
    12.08.2025 12:13

    Есть гигантская разница между "мы не трогаем код потому что нам не нужно" и "мы не трогаем код потому что боимся". "Не трогай то, что работает" -- это не мудрость, а народное суеверие, в котором, впрочем, много практического смысла. Но этот практический смысл ограничивается теми вещами, которые мы привыкли вовремя выбрасывать и заменять новыми.

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


    1. Pumppeedd Автор
      12.08.2025 12:13

      Да, всё так.

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

      Топы и рук-ли, у которых на первом месте KPI и план по выручке, делают своё дело.


      1. dkuzminov
        12.08.2025 12:13

        И? Я говорю о том, что ВИЧ, если за ним не следить, убивает, вы же "Да, все так, но с нашей системой здравоохранения..." При этом статья называется "ВИЧ вас убьет. Или нет?"


        1. elzvi
          12.08.2025 12:13

          вы как будто дискуссию ради дискуссии на пустом месте решили развить. текст не про это же)