Roboweb/Блог
    Все статьи
    Разработчикам16 сентября 20268 мин чтения

    Код-ревью сгенерированного кода: чек-лист перед продом

    Чек-лист ревью кода, собранного ИИ: секреты, проверка ролей на сервере, валидация, персональные данные в логах, зависимости, 199-ФЗ и минимальные тесты.

    Код-ревью сгенерированного кода: чек-лист перед продом

    Код, который собрала ИИ-команда, проходит сборку и работает в превью, — но из этого не следует, что он готов к продакшену с живыми пользователями и персональными данными. Этот чек-лист ревью составлен на примере экспорта Roboweb — Next.js (App Router) + Prisma + PostgreSQL — и отвечает на два вопроса: что проверить в конфигурации, доступах, работе с данными, зависимостях и авторизации и какие тесты написать до выкладки.

    Почему сгенерированный код проверяют как код нового сотрудника

    Как проверить код, написанный нейросетью? Так же, как код нового сотрудника. Представьте, что в команду пришёл толковый, но новый разработчик и быстро собрал фуллстек-приложение. Вы не выкатите такое приложение в прод без ревью — не потому, что разработчик плох, а потому, что он не знает ваших требований к безопасности, данным и инфраструктуре. К сгенерированному коду применим тот же подход:

    • код сделан по описанию продукта, а не по вашей модели угроз;
    • решения, которые выглядят разумно, проверяются на вашем окружении, а не принимаются на доверии;
    • ответственность за прод остаётся на команде, которая его выкладывает.

    Экспорт Roboweb и сам это признаёт: это стартовый каркас, функционально полный фуллстек, а в README перечислены ограничения и прямо сказано, что безопасность из коробки — не production-grade. Это нормальная отправная точка, если заложить время на ревью. Карта файлов и назначение каждого — в статье о структуре экспорта Next.js + Prisma.

    Секреты и конфигурация: что не должно попасть в репозиторий

    В экспорте есть .env.example с переменной DATABASE_URL и .gitignore. Проверьте:

    • настоящий .env не попал в коммит, а .gitignore действительно его исключает;
    • в истории репозитория нет строк подключения и ключей — смотрите всю историю, а не только последний коммит;
    • в папке public нет ничего секретного: всё, что там лежит, включая public/rw-export.js, отдаётся любому посетителю;
    • в разметке app/_site.ts нет внутренних адресов, тестовых учётных данных и служебных комментариев;
    • для базы в проде заведён отдельный пользователь с минимально нужными правами, а не суперпользователь;
    • строки подключения для разработки, тестового стенда и прода разные.

    Если секрет хоть раз попал в историю, удалить коммит недостаточно — меняйте сам секрет.

    Доступы: проверка ролей на сервере, а не только в интерфейсе

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

    1. Откройте app/api/data/[table]/route.ts и выпишите права чтения и записи по каждой таблице. Сверьте с продуктом: каталог читают все; заявку аноним может создать, но не прочитать; строки личного кабинета доступны только владельцу.
    2. Повторите запросы к API без cookie сессии и с cookie другого пользователя. Кабинет должен отдавать только строки вошедшего пользователя — убедитесь в этом запросами, а не глазами.
    3. Пройдите по маршрутам app/api/fn/. Перенесённый маршрут сам сессию не требует: он передаёт функции id пользователя или null и заранее читает таблицы из списка READS целиком, без фильтра по владельцу. Везде, где функция возвращает данные пользователей, добавьте проверку сессии и фильтр по владельцу. Учтите и то, что поле writes из ответа функции в выгрузке не применяется: запись в базу нужно реализовать через Prisma.
    4. Если есть оформление заказа, отправьте в app/api/fn/checkout запрос с подменённой ценой. Сумма считается на сервере по ценам каталога — проверьте, что подмена ни на что не влияет.
    5. Посмотрите lib/session.ts и lib/auth.ts: время жизни сессии, флаги cookie в продовой конфигурации, выход из аккаунта. Просроченные сессии нужно периодически чистить — заведите для этого задачу по расписанию.
    6. Проверьте ограничение частоты: lib/ratelimit.ts вызывается только в маршрутах регистрации и входа, запросы к app/api/data и app/api/fn не ограничены. Адрес клиента берётся из последнего значения заголовка x-forwarded-for. README требует HTTPS и доверенный reverse-proxy: если приложение доступно напрямую, в обход proxy, этот заголовок подставит кто угодно, а без proxy все запросы попадут под один общий лимит.

    Данные: валидация ввода, запросы к базе, персональные данные в логах

    Типы и схема. В экспорте поля данных в моделях Prisma имеют тип String?, это указано в README; служебные id, createdAt и модели аккаунтов уже типизированы, а почта посетителя в SiteUser уникальна. Перед продом уточните типы, обязательность, уникальность и связи. Схема разворачивается через prisma db push, миграций в комплекте нет — для прода переведите проект на миграции, чтобы изменения схемы были воспроизводимыми и проходили ревью вместе с кодом.

    Валидация. Проверяйте ввод на сервере: длину строк, формат телефона и почты, допустимые значения. Ограничения HTML-формы обходятся одним прямым запросом.

    Запросы. Prisma параметризует обычные запросы, но ищите сырой SQL со склейкой строк, если его добавили при доработке. Для списков задайте лимиты и пагинацию, чтобы один запрос не выгружал всю таблицу.

    Персональные данные в логах. Заявки и аккаунты — это имена, телефоны и почта. Проверьте, что тела запросов не пишутся в лог целиком, а ошибки не возвращают клиенту стек и содержимое записей. Загляните и в логи reverse-proxy: персональные данные не должны оказываться в адресной строке. Для проектов в России учитывайте требования 152-ФЗ к обработке персональных данных.

    Зависимости и сборка: аудит пакетов, типы, линтер

    • Версии в package.json заданы диапазонами: next ^15, react ^19, prisma и @prisma/client ^6. Закоммитьте lock-файл, чтобы прод собирался из тех же версий, что прошли тесты.
    • Запустите аудит зависимостей и сверьте установленную версию Next.js с известными уязвимостями; обновление патч-версий сделайте регулярной задачей.
    • В tsconfig.json стоит strict: false — осознанное решение экспорта: ужесточать типы должен разработчик. Включайте строгий режим постепенно, по модулям, и исправляйте найденное.
    • Подключите линтер и запускайте его вместе со сборкой в CI. Скрипт build уже выполняет prisma generate и next build — сборка должна проходить на чистой машине без ручных шагов.
    • Убедитесь, что после ваших доработок пароли по-прежнему хешируются через bcryptjs с разумным параметром стоимости.

    Авторизация и закон: нет ли иностранных способов входа

    В экспорте свои маршруты авторизации: app/api/auth/register, login, logout и me. Риск появляется при доработке, когда кто-то добавляет «быстрый вход» через сторонний сервис. Для проектов, работающих в России, это вопрос закона: владельцам сайтов запрещено открывать доступ после авторизации через иностранные сервисы, а с 07.07.2026 за это штрафуют по 199-ФЗ (ст. 13.55 КоАП). Штраф для юрлиц — 500–700 тыс. ₽, при повторном нарушении — до 1,4 млн ₽.

    Что проверить:

    • в зависимостях и конфигурации нет провайдеров входа через Google, Apple, GitHub или Telegram;
    • в интерфейсе нет соответствующих кнопок, а на сервере — маршрутов обратного вызова;
    • способы входа сверены с перечнем разрешённых: российский номер телефона, Госуслуги или ЕБС, Яндекс ID, VK ID, Сбер ID; встроенный вход по почте и паролю в этом перечне не назван — нужно ли привязывать аккаунты к номеру телефона или другому разрешённому способу, уточните у юриста.

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

    Минимальные тесты на ключевые сценарии

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

    1. Регистрация, вход, запрос me, выход; после выхода me больше не возвращает пользователя.
    2. Серия неудачных попыток входа упирается в ограничение частоты.
    3. Аноним отправляет форму, запись появляется в базе, но прочитать заявки аноним не может.
    4. Пользователь А не получает строки пользователя Б ни через кабинет, ни прямым запросом к API.
    5. Оформление заказа с подменённой ценой возвращает сумму по ценам каталога.
    6. Серверная функция, которой нужна сессия, отказывает запросу без неё.
    7. Сборка и разворачивание схемы на пустой базе проходят без ручных шагов.

    Запускайте их в CI на каждое изменение.

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

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

    Практический шаг: заведите этот чек-лист задачей в трекере на первый же экспорт и закройте все пункты до того, как проект увидят реальные пользователи.

    Понравилась статья?

    Поделитесь с коллегами и друзьями

    Telegram

    Готовы запустить свой продукт?

    Опишите идею — ИИ соберёт фуллстек с бэкендом, а код останется вашим активом

    Создать проект бесплатно