Коротко: разобраться в чужом легаси без документации — методичная работа: карта системы по точкам входа, БД и логам, характеризационные тесты перед изменениями.

Разобраться в чужом коде без документации — это не магия, а методичная работа: восстановить карту системы по точкам входа, БД и логам, прежде чем что-то менять. Расскажу, как я подходил к легаси-микросервису, к которому не прилагалось ни строчки описания, и какие приёмы экономят недели.

С чего я начинаю, когда документации нет

Первое правило — ничего не трогать руками, пока не построена карта. Соблазн «сейчас быстро поправлю» в незнакомой системе почти всегда оборачивается каскадом сюрпризов. Я начинаю с трёх источников правды, которые врать не умеют: схема базы данных, точки входа (контроллеры, консольные команды, обработчики очередей) и продакшен-логи.

Шаг 1. Карта по базе данных

Схема БД — самый честный документ в проекте. Названия таблиц, внешние ключи и индексы рассказывают о доменной модели больше, чем README. Я выгружаю DDL и рисую связи: что от чего зависит, где денормализация, какие поля выглядят как статусы конечного автомата.

-- быстрый обзор: размеры и связи
SELECT table_name, table_rows
FROM information_schema.tables
WHERE table_schema = DATABASE()
ORDER BY table_rows DESC;

-- где какие внешние ключи
SELECT table_name, column_name, referenced_table_name
FROM information_schema.key_column_usage
WHERE referenced_table_name IS NOT NULL;

Шаг 2. Точки входа

Дальше ищу, как в систему вообще попадают данные: маршруты HTTP, CLI-команды, потребители очередей, крон-задачи. Это границы системы. От каждой точки входа я прослеживаю один путь до БД целиком — так появляется понимание «вертикальных срезов» бизнес-логики, а не разрозненных файлов.

Шаг 3. Логи и трассировка

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

Характеризационные тесты — мой страховочный трос

Прежде чем менять поведение, я фиксирую текущее — даже если оно кажется неправильным. Это «характеризационные тесты» (термин Майкла Физерса): тест, который описывает не «как должно быть», а «как есть сейчас». Он ловит регрессии при любой моей правке.

// фиксируем фактическое поведение, не идеальное
public function testLegacyPriceCalculationStaysSame(): void
{
    $calc = new LegacyPriceCalculator();
    // значение получено прогоном на реальных данных, а не из ТЗ
    self::assertSame(1180.0, $calc->total(orderId: 42));
}

Когда такие тесты накрывают критичные пути, рефакторинг перестаёт быть прыжком в темноту.

Чего я НЕ делаю

  • Не переписываю «попутно». Любая «заодно» правка в легаси — это новый необъяснённый баг через месяц.
  • Не верю комментариям. Комментарии устаревают, код — нет. Истина в том, что выполняется.
  • Не оптимизирую раньше понимания. Сначала карта и тесты, потом изменения.

Что в итоге работает

За несколько дней методичной работы — схема БД, точки входа, логи, характеризационные тесты — непонятный «чёрный ящик» превращается в систему, которую можно безопасно менять. Скучно? Да. Зато без героических ночных откатов.

Если вам достался legacy без документации и нужно в нём безопасно разобраться или довести до рефакторинга — это ровно та работа, которую я делаю на консультации и в рамках разработки.