Код, который собрала ИИ-команда, проходит сборку и работает в превью, — но из этого не следует, что он готов к продакшену с живыми пользователями и персональными данными. Этот чек-лист ревью составлен на примере экспорта 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 нет внутренних адресов, тестовых учётных данных и служебных комментариев;
- для базы в проде заведён отдельный пользователь с минимально нужными правами, а не суперпользователь;
- строки подключения для разработки, тестового стенда и прода разные.
Если секрет хоть раз попал в историю, удалить коммит недостаточно — меняйте сам секрет.
Доступы: проверка ролей на сервере, а не только в интерфейсе
Главный вопрос ревью: что сервер вернёт или позволит сделать запросу, который пришёл в обход интерфейса. Скрытая кнопка — не защита.
- Откройте app/api/data/[table]/route.ts и выпишите права чтения и записи по каждой таблице. Сверьте с продуктом: каталог читают все; заявку аноним может создать, но не прочитать; строки личного кабинета доступны только владельцу.
- Повторите запросы к API без cookie сессии и с cookie другого пользователя. Кабинет должен отдавать только строки вошедшего пользователя — убедитесь в этом запросами, а не глазами.
- Пройдите по маршрутам app/api/fn/. Перенесённый маршрут сам сессию не требует: он передаёт функции id пользователя или null и заранее читает таблицы из списка READS целиком, без фильтра по владельцу. Везде, где функция возвращает данные пользователей, добавьте проверку сессии и фильтр по владельцу. Учтите и то, что поле writes из ответа функции в выгрузке не применяется: запись в базу нужно реализовать через Prisma.
- Если есть оформление заказа, отправьте в app/api/fn/checkout запрос с подменённой ценой. Сумма считается на сервере по ценам каталога — проверьте, что подмена ни на что не влияет.
- Посмотрите lib/session.ts и lib/auth.ts: время жизни сессии, флаги cookie в продовой конфигурации, выход из аккаунта. Просроченные сессии нужно периодически чистить — заведите для этого задачу по расписанию.
- Проверьте ограничение частоты: 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 и не потерять пользователей.
Минимальные тесты на ключевые сценарии
Полное покрытие для выхода в прод не обязательно, но без тестов на ключевые сценарии любая доработка может тихо сломать доступы. Минимальный набор интеграционных тестов:
- Регистрация, вход, запрос me, выход; после выхода me больше не возвращает пользователя.
- Серия неудачных попыток входа упирается в ограничение частоты.
- Аноним отправляет форму, запись появляется в базе, но прочитать заявки аноним не может.
- Пользователь А не получает строки пользователя Б ни через кабинет, ни прямым запросом к API.
- Оформление заказа с подменённой ценой возвращает сумму по ценам каталога.
- Серверная функция, которой нужна сессия, отказывает запросу без неё.
- Сборка и разворачивание схемы на пустой базе проходят без ручных шагов.
Запускайте их в CI на каждое изменение.
Бывает, что ревью показывает: переделывать придётся больше, чем оставить. Если продукту нужны сложные платёжные сценарии, высокая нагрузка или строгие отраслевые требования, честнее сразу планировать полноценную разработку, а сгенерированный каркас считать прототипом. Где проходит эта граница, разобрано в статье о том, когда ИИ-сборка не подходит. Взгляд на безопасность со стороны бизнеса — своя база, свой код, контроль доступа — в материале о безопасности данных.
Сгенерированный каркас снимает с команды типовую часть работы. Ревью, типы, миграции и тесты за команду не сделает никто — и именно они отделяют прототип от продакшена.
Практический шаг: заведите этот чек-лист задачей в трекере на первый же экспорт и закройте все пункты до того, как проект увидят реальные пользователи.


