30 авг. 2024 г.·7 мин чтения

Ручная проверка рискованных изменений кода в командах с AI

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

Ручная проверка рискованных изменений кода в командах с AI

Почему одинаковый подход не работает

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

С AI-ассистентом проблема становится ещё заметнее. Он может за несколько минут изменить десять файлов, переименовать поля, переставить логику и обновить тесты, даже не остановившись подумать, влияет ли маленькая правка на счета, доступ к аккаунту или старые записи в базе. Код может выглядеть чисто, а результат для бизнеса всё равно окажется неверным.

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

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

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

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

Где нужна жёсткая граница ревью

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

Начните с трёх зон: деньги, идентичность и постоянные данные.

Денежные правила всегда должны проходить через человека

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

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

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

Изменения в доступе и данных требуют той же границы

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

Риск не ограничивается классическими уязвимостями безопасности. Изменение auth, которое выглядит безобидно, может загнать пользователя в бесконечный цикл входа, слишком рано завершать сессии или отнять доступ у не той роли. Это сразу бьёт по поддержке, продажам и доверию клиентов.

Изменения схемы заслуживают такого же отношения. Миграции, backfill, удаления, смена типа столбца и очистка могут пойти не так даже тогда, когда код выглядит аккуратно. AI-инструменты часто генерируют SQL, который работает на тестовой таблице, но спотыкается на большой.

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

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

Выберите простые уровни риска

Многие команды делают правила ревью слишком размытыми. Простая цветовая система легче соблюдается, когда работа идёт быстро.

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

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

Red — это зона, где правило становится строгим. Биллинг, auth, изменения схемы, права доступа, миграции и разрушительные действия всегда относятся сюда. Если код может изменить, кого и на какую сумму спишут, кто получит доступ, как хранятся данные или можно ли их удалить, человек должен утвердить это до merge и до deploy.

Короткой версии достаточно:

  • Green: текст, верстка, безопасная чистка и рефакторинг без изменения поведения
  • Yellow: обычная продуктовая работа с влиянием на пользователя
  • Red: биллинг, auth, изменения схемы, права доступа, миграции и удаления

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

У каждой red-зоны должен быть один назначенный человек. Один отвечает за ревью биллинга. Другой — за auth. Третий — за схему и изменения данных. Им не нужно писать каждую строку, но они должны знать типичные точки отказа и давать чёткое согласование.

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

Настройте правило контрольной точки пошагово

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

Запишите правило на одной странице. Если новый инженер не может объяснить его за минуту, оно слишком длинное.

  1. Определите red-область. Перечислите точные файлы, сервисы, таблицы базы, миграции, очереди, cron jobs и webhooks, которые могут влиять на биллинг, auth, права доступа, данные клиентов или изменения схемы. Будьте конкретны. «Всё, что связано с платежами» — слишком расплывчато. «billing/, invoice_worker, subscriptions table, auth middleware, user_roles table» — уже понятно.

  2. Добавьте одно правило согласования для всего, что попадает в эту red-область. Изменение не может merge или deploy, пока его не утвердит назначенный человек. Не оставляйте это на уровне «кто-то из engineering». Используйте реальные имена или роли, например техлида по биллингу или инженера, который отвечает за authentication.

  3. Попросите ассистента помечать риск у каждого предлагаемого изменения. Метка должна быть простой: green, yellow или red. Если ассистент изменяет файл из red-зоны, он должен прямо об этом сказать и коротко объяснить почему.

  4. Отключите auto-apply для red-изменений. Ассистент может подготовить патч, тесты и заметки, но решение о применении должен принимать человек. Это особенно важно для изменений схемы, проверок прав и логики биллинга, где одна тихая diff-поправка может вызвать громкий сбой.

  5. Держите prompt для ревьюера коротким. Попросите утверждающего проверить четыре вещи: изменение соответствует задаче, понятен сценарий отказа, тесты покрывают рискованный путь и откат возможен.

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

Что должен проверить ревьюер

Постройте guardrails для AI
Поставьте понятные правила согласования для AI-изменений, которые затрагивают деньги, доступ или данные.

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

Потом прогоните небольшой набор проверок самостоятельно. Одного happy path мало. Если пользователь может обновить тариф, проверьте ещё и отклонённую карту и пользователя с истёкшей сессией.

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

Ревьюер должен подтвердить несколько базовых вещей:

  • Старое правило и новое правило работают так, как ожидает команда.
  • Один обычный сценарий работает, а сценарии отказа падают корректно.
  • Роли, права доступа и истечение сессии по-прежнему совпадают с правилами продукта.
  • Изменения в базе идут в правильном порядке, с бэкапом и планом отката.
  • Логи или output dry-run не показывают неожиданных записей, удалений или ошибок прав доступа.

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

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

Логи помогают, потому что показывают, как изменение ведёт себя в реальных условиях. Dry run может показать, что скрипт затронет 240 строк вместо 24. Логи auth могут показать повторяющиеся сбои обновления токена после изменения правила сессии.

К изменениям биллинга нужен тот же подход. Ревьюерам стоит искать двойные списания, пропущенные счета и повторные попытки, которые могут дважды ударить по одному и тому же клиенту. Это маленькие diff-изменения с дорогими последствиями.

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

Простой пример для небольшой SaaS-команды

Пятичленная SaaS-команда просит ассистента подготовить тест для ценовой логики. Задача звучит скромно: поднять лимит проектов на trial-тарифе и добавить новый лимит для тарифа среднего уровня.

Сначала патч выглядит безобидно. Потом кто-то замечает, что ассистент ещё и поменял login middleware, потому что код для цен читает данные тарифа во время входа в систему. В той же ветке он сгенерировал миграцию базы, которая переименовывает user.plan в user.subscription_plan.

Это именно тот тип патча, который нельзя пропускать только через зелёный тестовый прогон. Изменения в биллинге, auth и схеме пользователя сами по себе несут риск. Когда один diff объединяет все три, команде нужно остановиться и отнестись к нему как к случаю ручного согласования.

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

Сама миграция выглядит аккуратно. Логика цен почти работает. Проблема прячется в пути возврата денег. Если клиент сделал апгрейд, достиг нового лимита тарифа, а потом в тот же день попросил возврат, изменённый middleware всё ещё читает новое имя тарифа из cache сессии. А код биллинга при решении о снятии платных функций проверяет старое имя столбца. Такое несоответствие может оставить клиента с платным доступом на несколько часов даже после возврата денег.

Тесты это пропустили, потому что они проверяли новые покупки, а не возвраты после изменения схемы. Ревьюер замечает проблему до релиза, отправляет патч назад и просит добавить ещё один тест на откат и кэшированные сессии.

Вот как выглядит внимательное ревью на практике. Команда не блокировала ассистента из-за того, что он использовал AI. Она заблокировала смешанное изменение, которое одновременно затрагивало доход, идентичность и данные клиентов.

Ошибки, которые ослабляют процесс

Сократите дорогие инциденты
Закройте пробелы в ревью биллинга, auth и потоков данных до того, как они превратятся в инциденты.

Процесс разваливается, когда команды превращают его в поздний ритуал. Если кто-то проверяет изменение в биллинге, auth или схеме только после того, как релиз уже поставлен в очередь, ревью превращается в гонку. Люди бегло смотрят код, ставят approval под давлением и надеются, что тесты поймали достаточно.

Проблема становится ещё сильнее, когда настоящие правила живут в голове одного человека. Допустим, только один senior-инженер знает, какие billing flags могут вызвать двойные списания или какое изменение auth может закрыть доступ админам. Все остальные гадают. Ревью кажется непоследовательным, команда двигается медленнее, а этот один человек становится узким местом.

Ещё одна частая ошибка — красить слишком многое в red. Если каждое изменение конфигурации, текста и маленький рефакторинг получают такую же метку, как изменение платёжного потока, люди перестают воспринимать метку всерьёз. Жёсткие границы ревью должны оставаться узкими. Используйте их для правок, которые могут списать неверную сумму, изменить, кто получит доступ, или поменять сохранённые данные так, что потом будет трудно откатить.

Тесты помогают, но не заменяют человека в логике денег и доступа. Набор тестов подтверждает те случаи, которые ваша команда ожидала. Но он всё равно может пропустить неудачную повторную попытку, которая спишет деньги дважды, проверку роли, дающую доступ через старый путь прав, или webhook, который пришёл не по порядку. Ошибки в биллинге и auth часто выглядят нормально в staging и потом вредят реальным пользователям.

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

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

Быстрые проверки перед утверждением

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

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

Перед тем как кто-то деплоит изменение в биллинге, auth или схеме, approval должен ответить на несколько простых вопросов:

  • Какие пользователи смогут платить, входить, обновлять тариф, отменять его или потерять доступ после этого релиза?
  • Какая таблица, поле, enum или permission изменила форму, и продолжают ли работать старые записи?
  • Как вы откатитесь за десять минут, и кто сделает это, если релиз пойдёт не так?
  • Какой реальный аккаунт или staging-case команда тестировала, и что происходило шаг за шагом?
  • Кто утвердил изменение, и где команда зафиксировала это согласование?

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

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

Доказательства тестов должны быть реальными, а не расплывчатыми. «Проверили вход на staging с истёкшей подпиской и потом снова активировали её» — полезно. «Выглядит нормально» — нет. Запись об approval может жить в комментарии к pull request, в задаче или в release note. Место важно меньше, чем постоянство.

Такая привычка занимает несколько дополнительных минут. Но она может сэкономить день на исправления.

Что делать вашей команде дальше

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

Начните с одной страницы. Напишите простые правила, которые отвечают на один вопрос: какие изменения никогда не должны попадать в релиз без проверки человеком?

Для многих команд первые red-линии легко назвать: логика биллинга, pricing, возвраты, счета, authentication, роли, permissions, работа с сессиями, правки схемы базы, миграции, удаление данных, экспорт клиентских данных и доступ к аккаунту.

Формулировки держите жёсткими. Если diff затрагивает одну из этих зон, ассистент должен это отметить, а ревьюер — утвердить до merge или deploy. Без исключений для мелких правок. Маленькое изменение схемы всё равно может сломать production.

Потом научите ассистента замечать такие правки заранее. Пути файлов помогают, но их недостаточно. Добавьте простые триггеры вроде файлов миграций, auth middleware, кода платёжного сервиса, проверок ролей и таких слов, как «refund», «invoice», «token», «permission» или «ALTER TABLE». На первый день не нужен идеальный детектор. Нужен тот, который ловит очевидные случаи.

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

Назначьте одного владельца списка. Без владельца правила расплываются.

Если линия всё ещё кажется размытой, внешняя помощь может сэкономить время. Oleg Sotnikov на oleg.is работает как Fractional CTO и startup advisor, помогая командам выстраивать практичные guardrails для AI-assisted delivery, архитектуры продукта и рискованных изменений в биллинге, auth и потоках данных. Полезный результат — не толстая политика. Это короткий набор правил, которым ваша команда действительно будет следовать в следующий понедельник.

Часто задаваемые вопросы

Почему нельзя проверять все изменения кода одинаково?

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

Какие изменения всегда требуют ручного утверждения?

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

Может ли маленький diff всё равно быть рискованным?

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

Как нам обозначать green, yellow и red-изменения?

Используйте простое правило: green — это правки текста, верстки или работы без изменения поведения; yellow — обычная продуктовая работа; red — биллинг, auth, права доступа, изменения схемы, миграции и удаления. Если одно изменение попадает в несколько уровней, выбирайте более высокий.

Кто должен утверждать red-изменения?

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

Стоит ли AI автоматически применять изменения в биллинге, auth или схеме?

Нет. Пусть ассистент готовит патч, тесты и заметки, но для red-работы auto-apply должен быть выключен. Человек должен решить, можно ли это мёржить и деплоить.

Что должен проверять ревьюер в изменениях биллинга?

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

Что нужно проверить перед запуском изменения схемы?

Перед релизом миграции подтвердите порядок деплоя, шаги отката и то, как старый и новый код работают с данными во время выката. Затем проверьте на реалистичных записях, чтобы поймать неверные записи, сломанные запросы или backfill, который затрагивает больше строк, чем ожидалось.

Разве тестов недостаточно для работы с биллингом и auth?

Тесты ловят то, что ваша команда ожидала, но могут пропустить редкие сценарии вроде повторных попыток, устаревших сессий, старых прав доступа или событий webhook не по порядку. Ошибки в биллинге и auth часто выглядят нормально в staging, но позже всё равно вредят реальным пользователям, поэтому человек должен продумать бизнес-результат.

Как начать этот процесс и не замедлить команду?

Сделайте первую версию короткой и прямой. Напишите одну страницу с red-файлами, таблицами, сервисами и триггерами, а затем требуйте назначения конкретного ревьюера перед merge или deploy. Так у вас будет понятное правило без лишнего торможения для низкорисковой работы.