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

Что делает унаследованные системы трудными для изменений
Самое трудное в унаследованной системе обычно не старый код. Это годы срочных правок, негласных допущений и неописанных решений, которые в него накопились. Сервис может выглядеть ужасно и при этом быть стабильным. Чистый на вид модуль может зависеть от скрытых обходных путей, которые поддерживают выручку.
Эти обходные пути делают сбои трудными для поиска. Ошибка в оформлении заказа может начаться в налоговой логике, но команда заметит её только тогда, когда счета не пройдут двумя шагами позже. Скрипт поддержки, cron-задача или разовая правка базы данных могут держать систему в рабочем состоянии месяцами, а потом исчезнуть, когда новый разработчик наведёт порядок.
Команды наследуют и привычки. Кто-то перезапускает worker каждую пятницу. Кто-то вручную повторяет неудачный импорт. Кто-то из поддержки знает, каким записям клиентов нужно поставить ручную метку перед успешной оплатой. Продукт работает, но часть его живёт в головах людей.
Поэтому любые мелкие правки кажутся рискованными. Безобидное изменение в профилях пользователей может сломать вход. Переименование во внутреннем API может остановить письма о начале онбординга. Биллинг часто оказывается самым проблемным местом, потому что старые скидки, повторные попытки и ручные исправления накапливаются, пока никто уже не понимает, какое правило ещё важно.
Люди тоже усложняют ситуацию. Владение быстро становится размытым. Один инженер писал сервис, другой его разворачивал, а третий знал странное исправление для продакшена, но ушёл несколько месяцев назад. Когда никто не отвечает за рискованный путь от начала до конца, каждый релиз превращается в коллективное предположение.
Диаграммы этого не решают. Схемы из прямоугольников и стрелок скрывают, что происходит под нагрузкой, при плохих данных, после повторных попыток или во время частичного сбоя. На них редко видно, какая задача умирает в полночь, какое действие администратора пропускает проверку или какой сегмент клиентов вызывает самые неприятные баги.
Небольшая SaaS-команда может думать, что у неё пять чистых сервисов. В продакшене у неё на самом деле может быть двенадцать движущихся частей, если считать фоновые задачи, скрипты, вебхуки и ручные шаги поддержки. Этот разрыв и объясняет, почему первым делом нужно изучать живое поведение и бизнес-риски, а не перерисовывать архитектуру.
Ваши первые 7 дней
Если вы унаследовали запутанный продукт, первая неделя нужна, чтобы остановить новый ущерб. Сначала контроль, потом уборка. Большие рефакторинги могут подождать. Рискованные изменения схемы базы данных — тоже. Если команда продолжает менять фундамент, пока вы ещё только разбираетесь, исчезает и та небольшая стабильность, которая у вас была.
Заморозьте работы, которые могут сломать основные потоки без очевидной пользы на этой неделе. Обычно это означает широкие переписывания, правки базы данных, затрагивающие живые биллинговые данные, и «быстрые исправления», которые обходят ревью, потому что всем давит срочность.
Потом составьте простой список всех систем, которые касаются денег и активации. Вам не нужна идеальная схема. Вам нужна рабочая карта того, что происходит, когда пользователь регистрируется, начинает пробный период, платит, продлевает подписку, понижает тариф или отменяет её. Во многих стартапах реальный путь прыгает между приложением, платёжным провайдером, email-инструментом, админкой и несколькими скриптами, о которых никто не вспоминает, пока что-нибудь не сломается.
Достаточно короткого чеклиста:
- Отметьте области, где пока нельзя делать крупные изменения.
- Проследите регистрацию, оплату, продление и отмену во всех задействованных инструментах.
- Прочитайте последние заметки об инцидентах, логи неудачных деплоев и треды с хотфиксами.
- Спросите поддержку и продажи, где у клиентов сейчас болит.
- Назначьте по одному владельцу на каждую рискованную область, даже если это временный владелец.
Поддержка и продажи обычно дают более полезные сигналы, чем комментарии в коде. Поддержка слышит, где пользователи застревают. Продажи слышат, из-за каких сделок тормозят, потому что продукт выглядит ненадёжным. Если обе команды называют один и тот же шаг, обратите на него внимание.
Последние инциденты показывают, где кодовая база огрызается. Ищите повторяющиеся паттерны: сломанные вебхуки, неудачные миграции, задачи, которые тихо перестают работать, деплои, требующие ручной очистки, или состояния платежей, которые расходятся между системами. Эти проблемы важнее аккуратных папок.
Один владелец на каждую рискованную область не даёт проблеме размываться между людьми. Владелец не обязан знать все ответы в первый день. Ему нужно понимать область, отслеживать открытые вопросы и говорить да или нет, когда кто-то хочет её менять.
К концу первой недели сюрпризов должно стать меньше, ответственность — понятнее, а у вас должен быть короткий список мест, где одно плохое изменение может навредить выручке.
Проследите пути, которые приносят деньги
Прежде чем трогать схемы архитектуры, идите за деньгами. Сломанные денежные пути вредят бизнесу прямо сейчас, поэтому они срочнее, чем широкий аудит кода.
Начните с одного реального пути от посетителя до платного аккаунта. Проследите клики, формы, API-вызовы, фоновую работу и настройку аккаунта, которые происходят после того, как человек решил купить. По возможности используйте реальные логи, обращения в поддержку и платёжные записи. Память часто подводит.
Многие команды обнаруживают больше одного денежного пути. Самостоятельная регистрация обычно идёт одним маршрутом, а более крупный клиент может проходить через выставление счетов, ручное одобрение или отложенное предоставление доступа. Отрисуйте каждый путь отдельно. Если смешать их слишком рано, вы скроете места, где деньги на самом деле застревают.
Запишите каждую систему, которая касается этого пути: приложение, где клиент начинает, сервисы авторизации и биллинга, выдачу доступа, фоновые задачи, очереди, задачи по расписанию, вебхуки и внешние сервисы вроде оплаты, налогов, email или CRM.
Расположите их в порядке выполнения, а не в порядке оргструктуры. Запутанные системы обычно ломаются между системами — там, где один сервис думает, что задача завершена, а следующий сообщение так и не получил.
Потом отметьте точки, где деньги останавливаются. Сбои на этапе оформления заказа очевидны, но тихие сбои наносят больший ущерб. Счёт может сгенерироваться, но так и не уйти. Задача продления может пропустить пакет. При выдаче доступа система может списать деньги и не создать аккаунт. На каждом шаге задавайте один прямой вопрос: как мы узнаем, что это сработало?
Ищите и ручные шаги спасения. Команды поддержки часто поддерживают выручку за счёт выгрузок в таблицу, копирования ID клиентов, ручных повторов или прямых правок в админке. Эти обходные пути показывают, где система уже ломается при обычной нагрузке. Они же показывают, где маленькое исправление может сэкономить часы каждую неделю.
Добавьте по одному бизнес-метрику рядом с каждым путём. Новый чек-аут влияет на конверсию. Продления влияют на регулярную выручку. Выдача доступа влияет на активацию, отток и возвраты. Выставление счетов влияет на сбор денег. Вот где приоритизация долга становится реальной. Вы перестаёте сортировать проблемы по тому, насколько уродливо выглядит код, и начинаете сортировать их по тому, сколько боли приносит каждый сбой.
Для начала достаточно грубой карты. Если на ней видны владельцы, точки отказа, ручные исправления и метрика, на которую влияет каждый путь, вы можете защитить части, которые приносят деньги, а менее срочный хаос пока оставить в покое.
Сортируйте долг по боли для бизнеса
Большинство унаследованных систем выглядят хуже, чем есть на самом деле. Одни части безобразны, но стабильны. Другие выглядят обычными и тихо теряют деньги каждую неделю.
Оценивайте каждую проблему по боли для бизнеса, а не по тому, насколько она раздражает команду. Медленная задача повторных попыток биллинга, из-за которой срываются продления, важнее, чем грязная админская страница, которую никто не открывает. Хрупкий поток регистрации, создающий обращения в поддержку, важнее старого кода, который всё ещё работает.
Используйте короткую оценочную таблицу:
- Потерянная выручка: блокирует ли это регистрации, продления, апгрейды или счета?
- Заблокированная работа: тормозит ли это команду каждый спринт или останавливает релизы?
- Нагрузка на поддержку: создаёт ли это повторяющиеся обращения, ручные исправления или ночные алерты?
- Частота: случается ли это каждый день, каждую неделю или только иногда?
- Стоимость: сколько часов или денег сгорает на каждом инциденте?
Держите числа грубыми. «Около четырёх неудачных продлений в неделю» или «два часа инженера на каждый релиз» — этого достаточно. Вам не нужна идеальная модель. Вам нужен понятный порядок атаки.
Так вы отделяете уродливый код от кода, который вредит бизнесу. Сервис на 2000 строк может раздражать каждого разработчика в команде, но если никто его не меняет и клиенты его не замечают, оставьте его пока в покое. Небольшой скрипт, который раз в месяц ломает письма со счетами, может нанести больший ущерб.
Выбирайте несколько исправлений, которые убирают повторяющиеся пожарные выезды. Хорошие ранние цели часто снова и снова находятся на одном и том же пути: платежи, онбординг, продления, отчёты или передача в поддержку. Если одно исправление убирает еженедельный инцидент, экономит пять часов поддержки и снижает риск возвратов, оно каждый раз выигрывает у широкого наведения порядка.
Этот этап должен казаться скучным. Исправляйте то, что стоит денег, блокирует людей или будит кого-то в 2 часа ночи. Пусть низкоболезненный хаос остаётся хаосом, пока у команды не появится время на уборку без риска для бизнеса.
Поставьте защитные ограждения вокруг кодовой базы
Когда вы наследуете запутанный продукт, самый быстрый способ его сломать — слишком рано изменить не то место. Поставьте заморозку на изменения в биллинге и логине, если проблема не срочная. Эти две области одновременно влияют на денежный поток, доступ к аккаунту, нагрузку на поддержку и доверие клиентов.
Начните с видимости, а не с уборки. Включите алерты для потоков, которые приносят деньги: оформление заказа, продления, повторные попытки оплаты, апгрейды тарифов и создание счетов. Если один из этих путей ломается в 14:00, команда должна узнать об этом в 14:01, а не после того, как клиент пришлёт злое письмо.
Сначала держите алерты простыми. Следите за жёсткими отказами, необычными падениями конверсии и фоновыми задачами, которые перестали запускаться. Быстрый сигнал важнее красивых дашбордов.
С откатами нужен тот же подход. У каждого деплоя должен быть короткий, проверенный путь назад. Если релиз ломает вход для половины пользователей, никому не нужен долгий созвон об опциях. Команде нужен понятный шаг, который можно выполнить за минуты.
Несколько правил полезнее, чем ещё одна архитектурная схема:
- Просите маленькие pull request'ы с одной понятной целью.
- Не смешивайте багфикс, рефакторинг и изменение схемы базы данных.
- Добавляйте заметку об откате до того, как изменение пойдёт в продакшен.
- Ведите короткий журнал срочных исправлений, когда они случились и что их вызвало.
Последний пункт звучит скучно, но быстро окупается. Через две недели начинают проявляться паттерны. Возможно, неудачные продления идут из-за одного старого worker'а. Возможно, проблемы с логином следуют за правками конфигурации, а не за изменениями кода. Вы перестаёте гадать и начинаете видеть, где кодовая база действительно вредит бизнесу.
Олег Sotnikov часто работает с компактными командами и AI-усиленными процессами разработки, и здесь действует тот же принцип: жёсткие ограничения лучше героизма. Команда может двигаться быстро внутри понятных рамок. Без этих рамок одно «маленькое» изменение может съесть неделю и оставить выручку под угрозой.
Ошибки, которые сжигают первый месяц
Первый месяц идёт не так, когда команда обращается с унаследованной системой как с чистого листа. Это не он. Клиенты уже зависят от странных потоков, старых обходных путей и скрытых задач, которые проявляются только при сбое. Если начать переписывание до того, как вы нанесёте на карту пути, приносящие деньги, можно сломать продления, апгрейды, выставление счетов или действия поддержки, которые удерживают аккаунты в живых.
Удивительно много времени уходит на споры о стиле кода. Команды спорят о названиях папок, правилах lint или о том, какой фреймворк кажется чище, пока на фоне растут неудачные продления. Это наоборот. Если деньги перестали двигаться, никому не важно, насколько аккуратно выглядят импорты. Хорошая приоритизация долга начинается с боли бизнеса, а не с того, что раздражает громче всего.
Старые схемы тоже съедают дни. У многих унаследованных систем есть архитектурные диаграммы, которые казались точными два года назад и с тех пор давно устарели. Реальные логи, последние инциденты и запросы к базе данных рассказывают лучшую историю. Если на схеме сказано, что один сервис отправляет биллинговые события, а логи показывают три cron-задачи и ручное исправление в админке, верьте логам.
С владением возникает другая тихая путаница. Менеджер может перевести сервис из одной команды в другую, потому что изменилась оргструктура. Потом ночью случается сбой, и никто не знает, кто может перезапустить задачи, читать алерты или говорить с клиентами. Перед тем как менять владельца, проверьте, кто разбирал последние инциденты и у кого ещё есть доступ и контекст для исправления.
Общие сервисы — это место, где благие намерения быстро превращаются в ущерб. Если пять человек одновременно правят авторизацию, биллинг или уведомления, никто не поймёт, какое изменение вызвало следующий сбой. Заморозьте широкие правки, пока не зададите простые правила:
- Один владелец утверждает изменения в каждом общем сервисе.
- Перед работой с неясным кодом все добавляют базовое логирование.
- Команда собирает рискованные изменения в запланированные окна.
- Люди записывают шаги отката до деплоя.
Именно здесь внешняя помощь CTO может сэкономить время. Олег Sotnikov уже делал такую работу в продакшен-средах, где важны и uptime, и расходы, и закономерность тут одна: сначала проверяйте живое поведение, а потом решайте, что менять. Аккуратная схема может подождать. Путь биллинга — нет.
Простой пример SaaS
Компания B2B SaaS покупает небольшой продукт и наследует его код. В первый же день новый CTO узнаёт, что существует два потока регистрации. Один начинается на сайте. Другой начинается с того, что сотрудники продаж создают аккаунты для более крупных клиентов.
Оба потока списывают деньги с карты, но только один надёжно создаёт аккаунт и применяет правильный тариф. Клиенты на некоторых годовых планах платят, получают чек и затем упираются в тупик. Рабочее пространство не появляется, приветственное письмо не приходит, и никто не может войти.
Поддержка удерживает компанию на плаву с помощью таблицы. Каждое утро кто-то проверяет неудачные заказы, сравнивает платёжные записи с таблицей пользователей и просит инженера вручную завершить создание аккаунта. Это работает ровно настолько, чтобы скрыть проблему, но съедает часы и рождает возвраты, злые обращения и недоверие.
Нервная команда может тут же рвануть в переписывание биллинга. Обычно это ошибка. CTO сначала замораживает изменения тарифов, тесты купонов и правки регистрации. Никто не добавляет новый пакет, пока команда не сможет объяснить, как деньги проходят через систему.
Потом CTO простыми словами наносит путь на карту. Посетитель выбирает тариф, платит, получает запись клиента, получает рабочее пространство, получает права и попадает в приложение. Поток с участием продаж выглядит похоже, но один шаг вызывает старую задачу выдачи доступа, которая падает, если не хватает метаданных тарифа.
Теперь работа маленькая и понятная. Команда добавляет логи вокруг сбойного шага выдачи доступа, проверяет, какие тарифы его запускают, и исправляет несоответствие метаданных. Параллельно поддержке дают простое административное действие для повторного запуска настройки вместо правки строк в таблице.
Только после этого они говорят о более широком наведении порядка. Биллинговый сервис всё ещё может выглядеть ужасно. Код регистрации всё ещё может дублироваться. Но первое исправление останавливает утечку денег и сокращает ежедневный хаос для поддержки.
Такой порядок работает. Сначала защитите выручку, уберите ручной цикл исправления и поймите, где код ломается под реальным трафиком клиентов. Работа над архитектурой может подождать неделю. Неудачная настройка аккаунта — нет.
Что проверить перед следующим шагом
Прежде чем кто-то перерисует архитектуру, остановитесь и проверьте, что команда на самом деле знает. Большинство плохих решений в унаследованных системах возникают из-за ложной уверенности, а не из-за нехватки усилий.
Короткая проверка может сэкономить недели метаний. Если ответы расплывчаты, команда ещё не готова к крупному рефакторингу.
- Попросите трёх человек назвать потоки, которые приносят деньги. Они должны уметь показать их без открытия кода.
- Поставьте рядом с каждым сервисом, который может навредить выручке или доступности на этой неделе, текущего владельца.
- Проверьте откат на недавнем изменении, даже если безопасным способом.
- Ещё раз просмотрите список долга и спросите, какие пункты стоят денег, создают нагрузку на поддержку или блокируют продажи.
- Сравните список с тем, что сообщают поддержка и продажи.
Такой короткий аудит лучше архитектурных споров. Красивые схемы создают ощущение продуктивности. Понятное владение, скорость отката и карта путей выручки говорят, что можно менять безопасно.
Одна полезная проверка в жизни работает особенно хорошо: спросите: «Если этот сервис упадёт в пятницу вечером, кто заметит первым, кто это исправит и как мы восстановимся?» Если в комнате становится тихо, притормозите. Сначала нужен базовый контроль, а уже потом — более глубокий долг.
Команды часто ранжируют долг по тому, что их раздражает, потому что они живут в коде каждый день. Бизнес чувствует боль в других местах. Неловкий внутренний модуль может подождать, если клиенты его не видят. Хрупкая биллинговая задача — нет.
Если чек-аут ломается дважды в неделю, а команда хочет переписать админку, потому что код выглядит некрасиво, выбор прост. Почините путь, который приносит компании деньги, а потом заслужите право на остальную уборку.
Что делать дальше
Сделайте следующий спринт маленьким и прямым. Выберите один важный путь выручки и соедините его с одним дефектом, который продолжает вредить клиентам или сотрудникам. Так у команды будет одна цель роста и одна болевая цель, а этого обычно достаточно, чтобы двигаться вперёд, не раскачивая систему сильнее.
Хорошо работает такой простой набор:
- Один поток оформления заказа, регистрации, продления или распределения лидов, который напрямую влияет на деньги.
- Один баг, из-за которого появляются возвраты, ручная работа, пропущенные счета или большая нагрузка на поддержку.
- Один владелец для каждого пункта.
- Одна метрика успеха, которую команда может проверить через неделю.
Потом обсудите этот короткий список с инженерами, поддержкой и финансами. Инженеры знают, где ломается код. Поддержка слышит одну и ту же жалобу всю неделю. Финансы видят, где задержки, кредиты и переделки превращаются в реальные расходы. Когда все три группы указывают на одну и ту же проблему, приоритет обычно верный.
Держите заморозку достаточно долго, чтобы собрать факты, но не оставляйте её открытой бесконечно. Поставьте дату пересмотра в календарь прямо сейчас. Семь–четырнадцать дней часто хватает стартапу, чтобы подтвердить, что срочно, что может подождать, и какие рискованные изменения должны оставаться заблокированными.
Результатом должен стать короткий письменный план, а не грандиозное переписывание. Одной страницы достаточно. Укажите выбранный путь выручки, выбранный дефект, владельца каждого пункта, метрику спринта и дату, когда вы пересмотрите заморозку.
Если команда всё ещё спорит по кругу, может помочь внешний разбор. Олег Sotnikov делает такую Fractional CTO-работу для стартапов и небольших компаний, а oleg.is — простой способ увидеть этот фокус. Полезная часть тут не в большой стратегической презентации. Она в том, чтобы получить ясное понимание, где продукт хрупок, что должно оставаться замороженным и какое исправление быстрее всего снизит риск.
Следующий шаг должен казаться почти скучным. Если он помещается на одной странице и команда может начать работать над ним уже на этой неделе, значит вы, скорее всего, целитесь в правильную вещь.