Definition of Done для AI-сгенерированного кода: простой набор критериев готовности, чтобы выпускать изменения с тестами, миграциями, логами и планом отката.

С AI-кодом легко принять фичу, как только она «показывает результат». Модель быстро пишет много строк, интерфейс оживает, эндпоинт отвечает. Но из-за этой скорости часто пропускают то, что не видно сразу: крайние случаи, деградацию производительности, внятные сообщения об ошибках, поведение после деплоя.
Разница между «работает у меня» и «готово к релизу» обычно всплывает в первый же день после выката. У пользователя что-то ломается, а в логах тишина. Миграция базы не прошла, и сервис поднялся в полурабочем состоянии. В проде появилась новая ошибка, но ее нельзя быстро воспроизвести - потому что нет теста и нет понятного сценария отката.
Definition of Done (DoD) для AI-сгенерированного кода нужен, чтобы каждый раз проверять не только «функцию», но и готовность к эксплуатации. Это особенно важно, когда вы делаете фичи через чат: результат появляется быстро, а значит качество лучше удерживать правилами, а не памятью.
Чаще всего при приемке AI-кода забывают про тесты на ключевые сценарии, безопасные миграции БД и обратимость изменений, понятную обработку ошибок, логирование, а также план отката и короткие заметки для поддержки.
Дальше - о том, что считать достаточным: какой набор тестов закрывает риски, как не «уронить» БД миграцией, что логировать, как продумать откат (в том числе через снапшоты и rollback) и какую документацию оставить, чтобы поддержка не превращалась в угадайку.
AI может быстро нагенерировать код, который «вроде работает». Но для релиза этого мало. «Готово» означает, что фича понятна пользователю, предсказуема в работе и не превращает поддержку в квест.
Продуктовая готовность. Пользователь должен пройти ключевой сценарий от начала до конца: заполнить форму, сохранить данные, увидеть результат, повторить действие. Нужны продуманные пустые состояния, ограничения (например, длина полей) и нормальные тексты ошибок, а не «Something went wrong».
Эксплуатация. Сервис должен вести себя одинаково в обычных и аварийных ситуациях: ошибки обрабатываются, пользователю показывается простое сообщение, а команде остается полезная информация в логах. Когда фичи собираются быстро, через неделю уже сложно вспомнить, что именно было «задумано» в промпте - поэтому единые правила спасают.
Готовность к изменениям. Любые правки схемы данных должны идти через миграции с понятным порядком применения, без риска потерять данные. Хороший признак - обратная совместимость: старая версия клиента или API не падает из-за нового поля.
Готовность поддержки. Достаточно минимальной документации, чтобы любой в команде разобрался за 10 минут: что делает фича и где включается, какие сценарии и ограничения важны, где смотреть логи, какие события считать ошибками и кто отвечает за компонент.
Так DoD превращает AI-сгенерированный код из демо в вещь, которую не страшно сопровождать.
AI быстро добавляет функциональность, но так же быстро приносит скрытые поломки. Поэтому тесты в DoD должны подтверждать не «красоту» решения, а то, что ключевые сценарии работают и базовый путь не сломан.
Минимум, который почти всегда нужен: тесты на критические сценарии фичи и короткий регресс по основным пользовательским потокам. Если добавили «сброс пароля», критично проверить отправку кода, ввод нового пароля и повторный вход. А регрессом - пройти «регистрация -> вход -> выход».
Юнит-тесты полезны там, где есть четкие правила: валидация, преобразования, проверки прав. Интеграционные нужны, когда важны стыки: API + БД, транзакции, миграции, работа с очередью. E2E обычно достаточно на 1-3 самые важные цепочки, где цена ошибки высокая.
Чтобы тесты не были «рандомом», заранее договоритесь о тестовых данных: фикстуры для небольших объектов, сиды для базовых справочников и отдельные тестовые аккаунты с понятными ролями.
Тесты считаются выполненными, только если они проходят в чистом окружении: без ручных правок в базе, без локальных файлов и «секретов на ноутбуке». Это можно проверять на свежем деплое или в отдельном стенде.
Короткий чек:
Если AI сгенерировал код, но миграции не продуманы, релиз ломается на первом же деплое. В DoD миграции должны быть повторяемыми и предсказуемыми.
Миграция - это не только создание таблиц. Обычно меняется схема (таблицы, колонки, ограничения), индексы, иногда данные (заполнение новых полей, пересчет) и доступы (роли, права). В PostgreSQL важно помнить, что индексы и большие обновления данных могут надолго блокировать таблицы.
Держите шаги маленькими и понятными: по названию файла ясно, что происходит, а в миграции - одна основная операция. Рискованные изменения лучше раскладывать на два релиза: сначала добавить новое поле и писать в оба, затем переключить чтение, и только потом удалить старое.
План отката нужен заранее. Идеально - down-миграция, но это не всегда реально (например, если вы уже преобразовали данные). Тогда готовят компенсирующую миграцию: она возвращает систему в рабочее состояние, даже если данные нельзя откатить «один в один». Дополнительно полезно иметь способ быстро вернуть приложение в прежнюю версию, пока вы чините миграцию.
Перед релизом прогоните миграции в нескольких режимах: на пустой базе (подъем с нуля), на базе с реальными данными (проверка времени и неожиданных значений), апгрейд с предыдущего релиза, а также повторный запуск там, где это допустимо. Отдельно проверьте права: приложение после деплоя имеет нужные доступы, лишнего не появилось.
Пример: AI добавил поле status и индекс. Безопаснее сначала добавить nullable-колонку и заполнить ее батчами, затем сделать NOT NULL и индекс, а удаление старых полей оставить на следующий релиз.
Ошибки будут всегда. В DoD важно не «отсутствие ошибок», а одинаковая и понятная обработка.
Заранее определите, где ошибки нужно ловить явно: входные данные (пустые поля, формат, длина), внешние сервисы (таймауты, 502, неожиданные ответы), база данных (нет записи, конфликт уникальности, проблемы с соединением), права доступа и внутренние сбои.
Пользователь должен видеть короткое человеческое сообщение без технических деталей. Команде детали нужны отдельно - в логах и в коде ошибки. Удобно, когда API и UI используют единый формат: понятный текст + машинный код + (при необходимости) идентификатор запроса, чтобы поддержку не заставляли гадать.
Полезно стандартизировать ответы: 400 для ошибок ввода, 401-403 для доступа, 404 когда ресурс не найден, 409 для конфликтов, 500 для неизвестного. Тогда фронтенд, мобильное приложение и поддержка действуют одинаково.
Критерии готовности:
При инциденте нужно быстро понять, что случилось и где. Поэтому заранее договоритесь о минимальном наборе логов и требованиях к качеству.
Логируйте не все подряд, а то, что помогает восстановить цепочку событий: ключевые действия пользователя, важные переходы статусов, внешние вызовы и итог операции. Отдельно фиксируйте ошибки и «медленные места»: время выполнения обработчика, запросов к БД и интеграций. Тогда через неделю можно ответить на вопрос «это сломалось у нас или у партнера?».
Держите простую шкалу и единый формат:
Полезнее всего связывать события в один сценарий. Договоритесь, что каждый запрос получает request-id (или correlation-id) и он прокидывается через фронтенд, бэкенд и фоновые задачи. Тогда проще увидеть полный путь: входящий запрос, проверку прав, обращения к PostgreSQL и ответ.
И еще правило: не пишите в логи то, что опасно хранить. Нельзя логировать пароли, токены, номера документов, полные телефоны и адреса, платежные данные. Если нужен контекст, маскируйте (например, только последние 4 цифры) и записывайте минимум.
Откат - это не просто «вернуть прошлый коммит». Часто откатывать приходится код, конфиг, миграции БД и иногда данные. Если забыть хотя бы один слой, сервис может запуститься, но работать неправильно.
Заранее решите, когда откат допустим, а когда безопаснее сделать forward-fix (быстрое исправление поверх). Откат хорош, если проблема возникла сразу после релиза и вы уверены, что предыдущая версия была стабильной. Forward-fix чаще нужен, если уже были необратимые изменения данных, ушли уведомления пользователям или внешние системы получили новые статусы, которые нельзя «отмотать».
Чтобы откат не превращался в импровизацию, проверьте, что базовый план реально выполним:
Пример: вы выпустили AI-сгенерированный обработчик заказов, и он начал создавать дубли из-за неверной проверки идемпотентности. Быстрый откат вернет стабильное поведение, но только если заранее понятно, что делать с уже созданными дублями (удалить, пометить, слить). Иначе вы просто спрячете проблему.
Критерий DoD простой: шаги отката известны, проверены на тестовом окружении, и понятно, кто «нажимает кнопку».
Даже если фича маленькая, без заметок поддержка и дежурная команда будут тратить время на догадки. Для DoD обычно достаточно короткого файла рядом с кодом, который отвечает на три вопроса: что изменили, как проверить, где подкрутить настройки.
Хороший минимум:
Если нужно быстро проверить проблему на проде, оставьте короткий «план проверки»: какие входные данные воспроизведут ситуацию, как понять, что проблема именно в новой фиче, какие логи или метрики смотреть первыми, какая временная мера допустима до фикса и к кому идти за решением.
Чтобы AI-сгенерированный код не превращался в лотерею, DoD должен быть «воротами» приемки: пока пункты не закрыты, задача не считается готовой, даже если «вроде работает».
Начните с короткого DoD на 10-15 пунктов под ваш проект. Не пытайтесь сразу покрыть все. Важно, чтобы список реально читали и могли выполнить за разумное время.
Дальше встроите DoD в обычный цикл:
Команда добавляет «сброс пароля». AI быстро накидал обработчик и форму, но DoD ловит типичные провалы: миграция для таблицы токенов не тестировалась на существующих данных, в логах случайно оказался email, а при ошибке SMTP пользователь получает «500». После правок появляется понятное сообщение, маскирование данных и проверяемый сценарий отката.
Главная проблема AI-кода проста: выглядит убедительно, быстро запускается, но не готов к жизни после мержа. DoD нужен не для бюрократии, а чтобы одинаково проверять то, что чаще всего ломается в продакшене.
Типичная ловушка - принять результат чата как «готово» без проверок. Рабочий экран или эндпоинт можно получить за минуты, но это только первый слой. Без набора тестов и сценария ручной проверки баги всплывут у первых пользователей, а команда будет гадать, что именно поменялось.
Вторая ошибка - миграция есть, а отката нет. Данные обновили, а потом выяснилось, что нужно срочно вернуть прошлую версию. Без обратной миграции или плана восстановления вы теряете время и рискуете содержимым таблиц. Даже если платформа поддерживает снапшоты и rollback, заранее нужно понимать, что именно вы откатываете: код, схему, данные или все вместе.
Еще одна частая проблема - «обработка ошибок для галочки», когда пользователю всегда показывают одно и то же «что-то пошло не так». Ошибка должна быть предсказуемой: понятное сообщение пользователю и понятная причина для команды (валидация, права доступа, внешний сервис, конфликт данных).
И наконец, логирование. Либо его нет, либо оно шумное и бесполезное. Минимальная проверка:
request-id (или аналог) для поиска;Перед тем как нажать «релиз», полезно на 10 минут переключиться в режим проверки, а не разработки. Для AI-сгенерированного кода это особенно важно: он часто выглядит правильным, но ломается на мелочах.
Проверяйте базовые вещи в чистом окружении (не на машине, «где уже все стоит»): сборка с нуля, зависимости, старт приложения и зеленые тесты. Затем - миграции (пустая база и база с данными) и понятный откат: down-миграция или компенсирующая миграция. Отдельно проверьте один реальный сценарий ошибки: пользователь получает ясное сообщение, а команда видит причину в логах.
После этого оставьте «микро-документацию» на 5-10 строк: как проверить фичу, какие переменные окружения нужны, где смотреть логи, и какой самый частый способ отката.
Запрос: «Добавим форму “Обратная связь”: имя, телефон, комментарий. Сохраняем в БД и показываем спасибо». Команда быстро собирает прототип, а дальше проверяет не «похоже работает», а проходит по DoD.
Сначала смотрят на поведение для пользователя: обязательные поля, понятные ошибки, защита от двойной отправки. Затем - крайние случаи: пустые строки, слишком длинный комментарий, телефон в разных форматах, повторная отправка той же формы.
Для тестов обычно хватает небольшого набора:
Миграция простая: новая таблица feedback, индекс по created_at, ограничения по длинам. Перед релизом миграцию прогоняют на пустой базе и на базе с данными. Если миграция упала, правило одно: не «чинить руками» в проде. Возвращаемся к рабочей точке, фиксируем причину (конфликт имен, блокировка, неверный тип), правим миграцию и повторяем прогон.
Логирование добавляют точечно: факт создания записи, время, статус - без персональных данных. Ошибки пишут с понятным кодом (например, FEEDBACK_SAVE_FAILED) и корреляционным идентификатором запроса.
В документации оставляют несколько строк: что делает фича, какие поля и ограничения, где смотреть логи, как проверить вручную, как откатить.
Чтобы DoD работал, он должен стать привычкой команды. Возьмите один шаблон и прогоните по нему ближайшую задачу, даже если она маленькая. Быстро станет видно, какие пункты лишние, а каких не хватает.
Практичный ритм:
Если вы используете TakProsto (takprosto.ai) и делаете фичи через чат, удобно заранее оформлять критерии в planning mode, а перед рискованными изменениями фиксировать безопасную точку через snapshots. Тогда rollback становится частью плана, а не реакцией на пожар.
Это проверка «готово к эксплуатации», а не «видно результат». AI легко делает рабочее демо, но DoD заставляет каждый раз закрывать одинаковые риски: тесты, миграции, ошибки, логи, откат и минимальные заметки для поддержки.
Держите короткое ядро: критические сценарии, базовый регресс, безопасные миграции БД, предсказуемая обработка ошибок, полезные логи с корреляцией, понятный сценарий отката и 5–10 строк документации для поддержки. Это обычно покрывает 80% проблем, которые всплывают после выката.
Если фича затрагивает деньги, доступы, пользовательские данные или ядро бизнес-процесса — нужен минимум один e2e на самый важный путь. Если изменения локальные и хорошо покрываются интеграционными тестами, e2e можно ограничить 1–2 цепочками, чтобы тесты не стали дорогими в поддержке.
Проверьте, что тесты проходят в чистом окружении без ручных правок в базе и без «секретов на ноутбуке». Если тесты падают после свежего деплоя или на новом стенде, это не «флейк», а сигнал, что зависимость от окружения не контролируется.
Делайте миграции маленькими и предсказуемыми, а рискованные изменения растягивайте на несколько релизов: сначала добавить новое и писать параллельно, потом переключить чтение, и только затем удалять старое. Перед релизом прогоняйте миграции на пустой базе и на базе с данными, чтобы увидеть блокировки и неожиданные значения.
Не всегда. Если миграция уже преобразовала данные необратимо, «down» может быть опаснее, чем полезнее. В таком случае лучше заранее подготовить компенсирующую миграцию, которая возвращает систему в рабочее состояние, даже если данные нельзя откатить один-в-один.
Пользователь должен видеть короткое человеческое сообщение без технических деталей. Команде при этом нужен машинный код ошибки и контекст в логах, чтобы быстро понять причину и повторить проблему без угадывания.
Достаточно логировать ключевые шаги операции, внешние вызовы и итог, а также время выполнения, чтобы находить «медленные места». Важно добавить request-id или correlation-id и не писать в логи секреты и персональные данные, даже если очень хочется «для отладки».
Откат — это не только код, но и конфигурация, миграции и иногда данные. Хороший план — тот, который можно выполнить быстро и безопасно: понятно, к какой версии возвращаемся, что делаем с миграциями и кто принимает решение. Если вы работаете в TakProsto, заранее фиксируйте безопасную точку через snapshots и проверяйте rollback на тестовом окружении.
Хватает короткого описания рядом с кодом: что изменили, как проверить один позитивный и один негативный сценарий, какие настройки важны и где смотреть логи при проблеме. Цель простая — чтобы любой дежурный за 10 минут понял, что делает фича и как диагностировать типовую поломку.