демо

Посмотрите, как бот ревьюит

Мы собрали 13 приложений на 11 языках и отправили в каждое Merge Request. Бот отревьюил их так же, как ревьюит рабочий код. Всё открыто: заходите в MR и читайте замечания целиком.

Что здесь настоящее, а что — нет

  • Приложения — синтетические. Мы написали их сами специально для демо. Это не чужой продакшн и не код клиентов: показывать чужой код мы не будем никогда.
  • Часть дефектов заложена нами. В каждый MR мы осознанно внесли по несколько типовых ошибок — иначе ревьюить было бы нечего.
  • Прогоны — настоящие. Это живые Merge Request в открытых репозиториях. Комментарии оставил бот, мы их не редактировали, не удаляли неудачные и не переписывали формулировки.
  • Бот нашёл больше, чем мы закладывали. В каждом MR есть находки, которых мы не планировали, — включая пару настоящих ошибок в нашем же демо-коде. Их видно в тех же тредах.
  • Цифры на карточках — это треды самого бота. Не усреднённые и не «до 40%»: пересчитайте комментарии в MR и получите те же числа. Открывайте и сверяйте.
  • Гейты остались красными. Замечания в демо никто не чинил: блокирующие находки открыты, и статус проверки в этих MR красный. Так честнее — зелёный скриншот сказал бы меньше.

Демо показывает, как выглядит ревью. Насколько оно полезно именно вашей команде — проверяется только на вашем коде и ваших правилах: поставьте на один репозиторий и посмотрите.

по стекам

Каждый язык — свой репозиторий

В каждом репозитории лежат договорённости команды (docs/adr) и конфиг ревью с правилами, которые из них выведены. Бот проверяет именно их — поэтому находки говорят на языке проекта, а не общими словами.

TypeScript

Angular

preset: angular

Офлайн-корзина: очередь изменений без сети и синхронизация при её появлении

замечаний
14
блокируют merge
10
с кнопкой «Применить»
0
Сервис сам подписывается на холодный HTTP-поток и его же отдаёт наружу: один клик «Синхронизировать» уходит на сервер двумя запросами.

TypeScript

NestJS

preset: nestjs

Импорт суточной выгрузки поставщика: полный срез заказов за день одним CSV

замечаний
11
блокируют merge
8
с кнопкой «Применить»
2
У позиции заказа нет поля priceKopecks — оно называется unitPriceKopecks, поэтому цена не сохранялась бы вовсе. Бот сверил код с сущностью, а не с намерением.

TypeScript

React

preset: react

Офлайн-корзина: очередь изменений без сети и синхронизация при её появлении

замечаний
13
блокируют merge
6
с кнопкой «Применить»
3
localStorage.clear() выполняется до ответа сервера: при обрыве сети несинхронизированные изменения исчезают вместе с остальными данными приложения.

Python

Django

preset: django

Импорт суточной выгрузки поставщика: полный срез заказов за день одним CSV

замечаний
11
блокируют merge
7
с кнопкой «Применить»
1
Эндпоинт удаляет позиции всех заказов и переписывает выгрузку, но не объявляет ни permission_classes, ни authentication.

Go

Gin

preset: gin

Импорт суточной выгрузки поставщика: полный срез заказов за день одним CSV

замечаний
15
блокируют merge
11
с кнопкой «Применить»
6
INSERT не заполняет колонку source, по которой строкой выше идёт DELETE: следующий импорт удалит не то, что вставил предыдущий.

Java

Spring Boot

preset: spring

Импорт суточной выгрузки поставщика: полный срез заказов за день одним CSV

замечаний
12
блокируют merge
7
с кнопкой «Применить»
3
SELECT lastval() возвращает последовательность в пределах соединения — на пуле соединений позиция привяжется к чужому заказу.

Kotlin

Android · Compose

preset: android

Офлайн-корзина: очередь изменений без сети и синхронизация при её появлении

замечаний
13
блокируют merge
9
с кнопкой «Применить»
0
Автосинхронизация запущена прямо в теле composable: каждая перерисовка экрана заводит ещё один бесконечный цикл в GlobalScope.

Ruby

Rails

preset: rails

Импорт суточной выгрузки поставщика: полный срез заказов за день одним CSV

замечаний
11
блокируют merge
6
с кнопкой «Применить»
2
Новые запросы фильтруют по source и external_id, а миграции с индексами в MR нет — таблица заказов растёт, запрос останется.

PHP

Laravel

preset: laravel

Импорт суточной выгрузки поставщика: полный срез заказов за день одним CSV

замечаний
11
блокируют merge
7
с кнопкой «Применить»
1
Цикл импорта не обёрнут в try/catch: исключение на одной строке валит весь импорт, а в логе не остаётся ни строки, ни причины.

Rust

Actix Web

preset: actix

Импорт суточной выгрузки поставщика: полный срез заказов за день одним CSV

замечаний
8
блокируют merge
7
с кнопкой «Применить»
3
Разбор строки индексирует parts[0..5] без проверки длины: короткая строка выгрузки роняет обработчик паникой.

C#

ASP.NET Core

preset: aspnet

Импорт суточной выгрузки поставщика: полный срез заказов за день одним CSV

замечаний
12
блокируют merge
6
с кнопкой «Применить»
1
Прежние заказы поставщика удаляются до цикла, поэтому проверка на существующий external_id внутри цикла уже ничего не находит — дедупликация мертва.

Dart

Flutter

preset: flutter

Офлайн-корзина: очередь изменений без сети и синхронизация при её появлении

замечаний
14
блокируют merge
8
с кнопкой «Применить»
0
Timer.periodic заведён прямо в build() у StatelessWidget: таймеры плодятся на каждой перерисовке и не отменяются никогда.

Swift

iOS · SwiftUI

preset: ios

Офлайн-корзина: очередь изменений без сети и синхронизация при её появлении

замечаний
15
блокируют merge
10
с кнопкой «Применить»
3
Перед синхронизацией стираются все ключи UserDefaults приложения, а не только очередь корзины.
если gitlab.com у вас закрыт

Вот та же сводка — целиком

В части корпоративных сетей внешний GitLab недоступен. Чтобы demo не оказалось для вас набором нерабочих ссылок, приводим сводку из MR по C# / ASP.NET дословно — так её видит разработчик в Merge Request.

ReviewGateкомментарий бота в MR

🤖 ReviewGate — AI-ревью

MR добавляет импорт суточной выгрузки поставщика, но реализация несёт серьёзные риски: неограниченный DELETE стирает позиции ВСЕХ заказов (не только поставщика), SQL-инъекция через интерполяцию external_id, деньги считаются в double, весь процесс не транзакционен и не защищён авторизацией, а обработка строк CSV делает по несколько запросов к БД на каждую запись. Требуется существенная переработка перед мержем.

Пресет: aspnet.

❌ Severity gate (critical) НЕ пройден: блокирующих замечаний 6.

Замечаний: 12 (⛔ 1 · 🔴 5 · 🟠 5 · 🔵 1); новых строчных: 8. По правилам команды (📐): 6.
Из ранее найденного — уже на ревью, не дублирую: 4.

▸ 🔬 Диагностика прогона

⚙️ Это ревью: 52,3K токенов вход (из них 7,6K из кэша) · 42K выход · ≈ 0,75 $

Строка стоимости — не наша бухгалтерия, а функция бота: он считает прогон по прайсу, который вы указали в конфиге, в вашей валюте. Свёрнутый блок «Диагностика прогона» раскрывается в MR: там видно, какие модели вызывались и что судья отбросил. Кода в блоке нет — только метаданные.

на что смотреть

Что искать в открытом MR

Замечания на строках

Находки привязаны к строкам диффа. Открывайте вкладку Changes — они там же, где их читает разработчик.

Сводка и severity gate

Один комментарий с итогом прогона и вердиктом. Во всех демо порог выставлен на critical, поэтому проверка красная, пока блокирующие замечания не закрыты.

Блок «Диагностика прогона»

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

Кнопки «Применить»

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

Диалог в треде

В каждом запросе разработчик спорит с одной из находок, и бот отвечает в том же треде — где-то отстаивает замечание разбором кода, где-то соглашается с нюансом, которого не учёл.

Тот же бот — на вашем репозитории

Демо ревьюил обычный ReviewGate — тот же движок и те же настройки из .reviewgate/config.yml, что ставятся у вас в контуре. Разница только в том, что эти репозитории публичные: ваш код в своём контуре и остаётся.