Культура code review: каким должно быть ревью, которое растит команду
Когда я стал тимлидом в небольшой команде, первое, что я понял: code review — это не проверка кода на входе, а самый дешёвый инструмент обучения команды. У нас много джунов и мало сеньоров — типичная ситуация для местных команд. Каждый PR — это возможность провести урок на реальном коде и в реальном контексте. Если выстроить ревью как «охранника», джун начнёт бояться писать код. Если как «наставника» — за шесть-семь месяцев он вырастет заметно. В этой статье я описываю подходы, которые сам внедрил в команде и которые сработали на практике.
Что ищет ревью — порядок приоритетов
Не все комментарии весят одинаково. Я дал команде чёткий порядок, сверху вниз:
- Корректность и безопасность. Работает ли код, покрыты ли edge case'ы, нет ли SQL-инъекции или захардкоженного токена. Если проблема найдена на этом уровне, остальные пункты не обсуждаем — сначала чинится это.
- Соответствие архитектуре. Вписывается ли код в существующую структуру проекта? Если логика, которой место в service-слое, написана в контроллере, — сейчас она работает, но через полгода обойдётся дорого.
- Читаемость. Поймёт ли другой человек этот код без контекста: именование, размер функций, сложные условия.
- Стиль. Пробелы, скобки, порядок импортов. Этот уровень вообще не отдавайте человеку — отдайте его линтеру и форматтеру. Пока человек обсуждает место запятой, на архитектуру времени не остаётся.
Последний пункт экономит больше всего времени: споры о стиле — главный пожиратель времени в ревью. После того как мы сделали Prettier и ESLint обязательными в CI, комментариев стало меньше, но ценность каждого выросла.
Размер PR: после 400 строк ревью умирает
PR на 800 строк никто не читает честно — пробегают глазами и жмут «LGTM». По моему опыту, 200–400 строк — граница, до которой внимание ревьюера держится до конца. При внедрении культуры маленьких PR мне помогли три вещи:
- Привычка разбивать задачу. Большую фичу планировать не как один огромный PR, а как цепочку последовательных маленьких: сначала модель и миграция, потом сервис, потом endpoint, в конце UI.
- Feature flag. Незавершённую функциональность можно мержить за флагом — и отговорка «подожду, пока всё будет готово» исчезает.
- Записанное правило. Мы в команде договорились письменно: «если PR больше 400 строк, сначала обсуждаем, можно ли его разбить». Когда правило записано, напоминание о нём — не личный упрёк, а часть процесса.
Тон комментариев: вопрос, а не приговор
Даже технически верный комментарий, написанный в неверном тоне, приносит вред: автор уходит в оборону, и обсуждение становится не про код, а про эго. Поэтому наше главное правило — вопрос, а не приговор. Одну и ту же мысль можно сказать двумя способами. Реальный пример из наших ревью:
Плохо: «Это неправильно. Упадёт на пустом массиве, перепишите.»
Хорошо: «А что будет, еслиitemsпридёт пустым массивом? Кажется,reduceбез initial value бросит ошибку — проверите?»
Вторая форма делает три вещи: не вынуждает автора защищаться, подталкивает его подумать самому, и если ревьюер ошибся, неловкой ситуации не возникает — вопрос не является обвинением.
Ещё две договорённости наводят порядок в тоне:
- Префикс
nit:. Перед мелким вкусовым предложением пишемnit:— автор не обязан его выполнять. Например: «nit: эти два if можно свернуть в один early return». - Разделение обязательного и предложений. Комментарий, блокирующий merge, помечается явно — префиксом «blocking:» или request changes. Остальное — предложения. Автор не должен угадывать, какие комментарии обязательны.
Ревью для джуна: не исправляй за него, направляй
Самая распространённая ошибка — переписать код джуна в «правильный вариант» самому. Он сделает copy-paste и ничему не научится. Вместо этого дайте направление: «Эта функция делает три вещи. Какую часть, по-вашему, можно вынести отдельно?» Процесс самостоятельного поиска ответа — это и есть обучение. Да, это дольше. Но это время — инвестиция в обучение, а не просто расход на ревью.
И в первых PR обязательно говорите и о хорошем. Одна фраза «Вы написали тесты, отлично — большинство в первом PR об этом забывает» полностью меняет отношение джуна к ревью. Человек, получивший только список недостатков, в следующий раз будет бояться открывать PR — а это ровно тот результат, который нам не нужен.
Сторона автора: ревью начинается с вас
Качество ревью зависит не только от ревьюера. Три привычки автора:
- Описание PR. Ответьте на три вопроса: что изменилось, почему (ссылки на задачу мало — напишите одно предложение контекста) и как это проверялось. Ревьюер не должен тратить время на раскопки контекста.
- Self-review. Открыв PR, станьте первым ревьюером сами: прочитайте diff от начала до конца. Благодаря этой привычке половину комментариев я исправляю сам, до того как их увидит ревьюер — забытый console.log, недоназванная переменная, лишний файл.
- Не принимать комментарии на свой счёт. Ревью направлено на код, а не на вас. Избавиться от чувства «мой код — это я» непросто, но необходимо: быстрее всех растут разработчики, которые воспринимают комментарий не как атаку, а как подарок.
Процесс: SLA, дежурный и болезнь LGTM
Культура — это не только тон. Её держат три организационных правила:
- SLA на ревью — 24 часа. После открытия PR первый ответ должен появиться в течение суток. Чем дольше ожидание, тем сильнее автор забывает контекст, ветка устаревает, копятся merge-конфликты. Важно: за 24 часа нужен не полный разбор, а первый ответ — «увидел, посмотрю завтра» тоже считается, автор понимает, что происходит.
- Дежурный ревьюер. В маленькой команде, когда все заняты, PR повисает в воздухе. Недельное дежурство — человек, который на этой неделе первым отвечает за ревью, — решило у нас эту проблему.
- Ритуал против штампа LGTM. Approve не читая — командная болезнь. Мы ввели маленькое правило: перед approve нужно написать минимум один вопрос или содержательный комментарий. Не нашли вопрос — значит, не читали diff. Этот двухминутный ритуал заново оживил ревью.
Вывод
Code review — одно из самых дорогих общих времён команды, и отдача от этой инвестиции напрямую зависит от культуры. Отдайте стиль линтеру, делайте PR маленькими, задавайте вопросы вместо приговоров, давайте джуну направление, а не готовый ответ, и как автор берегите время ревьюера. Ничего из этого не сложно технически — всё это вопрос привычек. Но результат ощутимо реален: каково качество ревью, такова и скорость роста команды.