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

В легаси-системе первый опасный шаг часто выглядит разумно: найти самый старый модуль, переписать его и заодно «навести порядок». Через неделю выясняется, что этот код обслуживает ночной обмен данными, а его странные проверки защищают бизнес-процесс, о котором нет документации. Тактика первых недель должна решать другую задачу: превратить неизвестную систему в набор наблюдаемых зависимостей, ограничить риск и только потом менять поведение. Ниже — план для первых десяти рабочих дней, который подходит команде, подключившейся к существующему сервису, монолиту или внутренней платформе.
Сначала зафиксируйте границы, а не список улучшений
Первые два-три дня не стоит тратить на массовое чтение исходников. Вам нужно понять, где система начинается и заканчивается: кто вызывает её, какие данные она принимает, что отдаёт наружу и какие операции нельзя остановить даже на короткое время.
- Запишите назначение системы одним предложением, без названий внутренних модулей.
- Составьте список пользователей и потребителей: веб-клиент, мобильное приложение, бухгалтерия, фоновые задания, внешние партнёры.
- Отдельно отметьте критические операции: оформление заказа, начисление денег, выдача доступа, синхронизация остатков.
- Зафиксируйте рабочие окна, ночные задания, ручные процедуры и точки, где требуется согласование другой команды.
- Соберите владельцев: кто принимает решение о релизе, кто отвечает за инфраструктуру, кто знает бизнес-правила.
Результат этого этапа — не красивая архитектурная схема, а короткий файл с границами ответственности и списком неизвестных. У каждого неизвестного должна появиться следующая проверка: посмотреть конфигурацию, поговорить с владельцем, найти лог или воспроизвести сценарий.
В легаси опаснее всего не старый код, а уверенность, что вы уже поняли, что он делает.
План первых десяти рабочих дней
Не пытайтесь закрыть всё одновременно. Разделите работу на разведку, безопасное наблюдение и одно небольшое изменение. Такой порядок снижает цену ошибки: если вывод оказался неверным, вы потеряете не неделю миграции, а несколько часов проверки.
- Дни 1–2: соберите карту запуска. Найдите точку входа приложения, команды сборки и запуска, файлы конфигурации, зависимости, хранилища и внешние сервисы. Для каждой среды отдельно запишите, чем отличаются переменные, очереди, базы и права доступа. Проверка: новый участник может по документу понять, как поднять сервис или к кому обратиться за недостающим доступом.
- Дни 2–3: восстановите путь одного запроса. Возьмите реальный пользовательский сценарий и проследите его от входа до записи в базу или отправки сообщения. Не берите сразу самый редкий процесс. Проверка: на схеме есть последовательность компонентов, идентификатор операции и место, где можно увидеть ошибку.
- Дни 3–4: определите безопасную поверхность наблюдения. Проверьте логи, метрики, трассировку, алерты и историю релизов. Если корреляционного идентификатора нет, договоритесь, как связать входящий запрос, фоновой обработчик и запись об ошибке. Проверка: по одному известному событию можно восстановить хотя бы его время, результат и компонент, который завершил операцию.
- Дни 4–5: составьте реестр рисков. Для каждого риска укажите условие срабатывания, возможный ущерб, способ обнаружения и обратное действие. Формулировка «код плохой» не подходит. Лучше: «при повторной доставке сообщения операция может списать сумму дважды; обнаружение — сверка идентификатора операции; защита — идемпотентная проверка».
- Дни 6–7: выберите малое изменение. Подойдут дополнительный лог на границе компонента, тест на найденный сценарий, исправление явной ошибки в документации или безопасная проверка входных данных. Не начинайте с изменения схемы базы, массового форматирования и переезда фреймворка. Проверка: изменение можно откатить одной понятной операцией, а его эффект наблюдаем.
- Дни 8–10: проведите контролируемый релиз. До выкладки запишите ожидаемое поведение, признаки ухудшения и владельца решения об откате. После релиза сравните ошибки, задержку, объём запросов и бизнес-результат с исходным состоянием. Проверка: команда может ответить, что изменилось, где это видно и что делать при отклонении.
Три режима работы с неизвестной системой
Команды обычно выбирают один из трёх путей. Ошибка не в самом выборе, а в том, что режим не называют и незаметно переходят от наблюдения к опасной перестройке.
| Режим | Когда применять | Что выигрываете | Чем платите |
|---|---|---|---|
| Сначала наблюдение | Нет тестов, слабые логи, много внешних зависимостей | Снижаете риск неверной гипотезы и получаете исходную картину | Первые изменения почти не видны пользователю |
| Малый вертикальный срез | Есть один понятный сценарий и доступ к тестовой среде | Проверяете полный путь от входа до результата | Нужно заранее ограничить данные и предусмотреть откат |
| Изоляция узла | Проблема локальна и компонент можно заменить за контрактом | Уменьшаете радиус отказа конкретного модуля | Появляются временные адаптеры, дублирование и новые точки поддержки |
Критерий выбора простой: если вы не можете назвать способ обнаружить ухудшение, выбирайте наблюдение. Если сценарий известен, а границы компонента стабильны, берите вертикальный срез. Изоляцию оставляйте для узла, чей контракт можно проверить независимо от его внутренней реализации.
Какие артефакты действительно помогают
Карта зависимостей
Показывайте не все классы, а компоненты и связи, которые влияют на результат операции. У каждой стрелки должна быть подпись: HTTP-вызов, сообщение, чтение из базы, файл, ручной импорт. Отдельно помечайте синхронные и асинхронные переходы. В легаси именно очередь или ночной скрипт часто скрывает продолжение операции.
Журнал решений
Записывайте не только решение, но и отвергнутые варианты: почему не стали менять схему, какой контракт нельзя нарушить, какую гипотезу пока не подтвердили. Через месяц это защитит команду от повторного обсуждения и от исправления «странности», которая оказалась обязательным ограничением.
Реестр неизвестного
Разделите вопросы на три группы: «мешает релизу», «влияет на операционные риски», «можно отложить». Так команда не потратит спринт на выяснение автора старой функции, если пока важнее понять, что происходит при повторной доставке платежного сообщения.
Идемпотентность1 — свойство операции давать тот же итог при повторном выполнении с теми же данными. Для легаси это особенно важно там, где запросы, сообщения или фоновые задания могут быть доставлены повторно.
Что ломается первым
- Документация расходится с продом. Не исправляйте только текст. Сверьте его с конфигурацией, журналом релизов и фактическим маршрутом запроса, а затем укажите дату проверки.
- Тестовая среда не похожа на рабочую. Запишите различия: объём данных, версии базы, внешние интеграции, расписания и права. Результат теста нельзя переносить на прод без этой оговорки.
- Логов много, но связать их нельзя. Не добавляйте ещё десятки сообщений. Сначала выберите несколько событий, которые должны сопровождать операцию, и обеспечьте единый идентификатор там, где это допустимо.
- Откат существует только на словах. Проверьте, можно ли вернуть версию приложения, конфигурацию и формат данных. Если изменение базы необратимо, это отдельный риск, а не обычный релиз.
- Малое изменение разрастается. Когда задача начинает затрагивать несколько сервисов и неописанные бизнес-правила, остановите её и разделите на исследование и отдельный проект.
Как измерять прогресс без выдуманных цифр
Для легаси нет универсального порога «система достаточно изучена». Зафиксируйте исходное состояние перед первым изменением и сравнивайте его с тем же сценарием после релиза. Минимальный набор зависит от сервиса, но обычно включает долю ошибок, задержку ключевой операции, количество повторных попыток, отказы внешних зависимостей и бизнес-результат — например, завершённые заказы или успешно обработанные документы.
Замеры должны иметь условия: версия приложения, среда, период, объём данных и тип нагрузки. Если метрики пока нет, не подменяйте её впечатлением команды. Сначала добавьте наблюдаемость на одной критичной цепочке и пометьте, какие выводы пока основаны только на логах или ручной проверке.
Что делать дальше
После первых десяти дней выберите один риск из реестра и превратите его в план на ближайший цикл: добавить тест на реальный сценарий, закрыть пробел в наблюдаемости или отделить компонент за стабильным контрактом. Перед большим рефакторингом повторите замер исходного поведения и определите критерий остановки. На проде следите не только за техническими ошибками, но и за тем, не изменился ли результат операции для пользователя.
Версии языка, фреймворка, базы, рантайма и инструментов фиксируйте рядом с картой запуска. Если система собирается разными способами или часть компонентов уже обновлена, это нужно указать явно: советы для одной версии могут быть неприменимы к другой. Инвалидация кеша, миграция базы и замена очереди требуют отдельных планов — в первые недели их стоит только обозначить, если они не связаны с выбранным малым изменением.
Инфографика для маркетплейса: Три главных преимущества товара короткими фразами, выноски в безопасной зоне превью, точный размер площадки.
Спросить за 60 ₽Источники: Google SRE Book: Monitoring Distributed Systems, OpenTelemetry Documentation: Observability primer
Частые вопросы
Нужно ли сначала полностью прочитать исходный код?
Что делать, если в системе вообще нет тестов?
Как выбрать первое изменение, если всё кажется опасным?
Что делать, если у меня другая версия фреймворка или базы?
Как понять, что разведка затянулась и пора менять код?
Что делать, если после релиза не сработали метрики или откат?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.