MirrorVote - пет-проект, в котором весь код приложения написан нейросетью в Claude Code, а архитектуру, деплой и эксплуатацию делал человек. Это честная иллюстрация рабочего процесса 2026 года: AI ускоряет набор кода, но проектирование системы, границы доверия и архитектурные компромиссы остаются за инженером. Код быстро генерируется, а решения о безопасности, платежах и стоимости ошибок по-прежнему принимает человек.
Где проходит эта граница, видно на конкретных задачах. AI уверенно пишет обработчики, CRUD и вызовы API. Он не решает, как ограничить доступ к чужим строкам в базе, как не списать деньги дважды при повторном webhook и как не уйти в минус по стоимости вызовов LLM. Главный тезис простой: роль инженера смещается от написания кода к проектированию системы, и MirrorVote на Supabase и OpenRouter показывает это лучше многих теоретических статей.
Если коротко, MirrorVote - это AI-помощник выбора образа. Пользователь загружает несколько фотографий, система приводит их к единому виду (фон, свет, поза) и оценивает наряды с учётом повода. Дальше можно собрать мнение друзей по публичной ссылке. За простой обёрткой стоит полноценный набор интеграций: авторизация, хранение файлов, платежи и несколько вызовов LLM на один запрос.
Что такое MirrorVote и почему это показательный кейс
Проект ценен тем, как он собирался, а не набором функций. Код писался через вайбкодинг в Claude Code, исходники лежат в Git. Всё, что касается архитектуры, развёртывания и эксплуатации, тянул на себе человек. Такое разделение труда - не случайность, а следствие природы AI-инструментов: они отлично работают внутри понятной задачи и теряются на стыках между сервисами.
Пользовательский сценарий MirrorVote в двух словах
Один запрос на примерку запускает цепочку шагов. По разбору проекта последовательность выглядит так:
- Авторизация через Google OAuth, на выходе - JWT-токен для последующих запросов.
- Загрузка фотографий для анализа.
- Проверка пользователя и доступного лимита в PostgreSQL.
- Вызов LLM: обработка фотографий, анализ образов, формирование рекомендаций.
- Сохранение обработанных изображений в Storage, результатов анализа и оценок в PostgreSQL, списание лимита.
- Возврат пользователю обработанных изображений и результата анализа.
Отдельная ветка сценария - публичная ссылка для голосования: пользователь генерирует её и делится с друзьями. Простая функция на первый взгляд, но она открывает доступ к данным и требует аккуратной настройки прав.
Почему PoC - это не продакшен, и какие упрощения допустимы
Для PoC не нужна промышленная надёжность, и это позволяет урезать каждый этап классического цикла разработки. В материалах по проекту перечислены те самые упрощения. Анализ требований сводится к минимальному пользовательскому сценарию или MVP. Проектирование ограничивается минимальной схемой БД и только критичными интеграциями: Auth, LLM, платежи. Код пишется через вайбкодинг и хранится в GitHub. Тестирование - ручные проверки основных сценариев. Развёртывание - локально или на облачном VPS, вручную либо через GitHub Actions. Эксплуатация - базовая observability: ошибки в логах, доступность приложения, стоимость внешних сервисов.
Упрощения не отменяют архитектурных решений. Они лишь снижают планку по нагрузке и надёжности. Границы доступа, идемпотентность платежей и обработку сбоев LLM всё равно нужно продумать, иначе PoC съест деньги или данные раньше, чем дойдёт до пользователей.
Стек MirrorVote: Supabase Edge Functions, OpenRouter и обвязка на VPS
Стек у проекта типовой для небольших AI-сервисов. Supabase закрывает базу, файлы и серверную логику, OpenRouter даёт доступ к моделям, а VPS с Nginx образует внешний контур. Разберём, зачем нужен каждый компонент и где он начинает требовать ручной работы.
| Компонент | Роль в системе |
|---|---|
| Supabase Edge Functions на Deno | Серверная логика без отдельного бэкенда |
| PostgreSQL | Пользователи, лимиты, результаты анализа и оценки |
| Storage | Хранение обработанных изображений |
| Nginx на VPS | Reverse proxy, TLS, маршрутизация запросов |
| Google OAuth | Авторизация и выдача JWT |
| ЮKassa | Приём платежей |
| OpenRouter (Gemini 2.5 Flash, Gemini 2.5 Flash Image) | Обработка и анализ изображений |
Почему Supabase Edge Functions на Deno
Edge Functions позволяют держать серверный код рядом с базой и хранилищем, без отдельного бэкенда и своего деплоя. Среда выполнения - Deno. Для пет-проекта это экономит время: не нужно поднимать сервер, настраивать окружение и CI для бэкенда. Логика обработки изображений и вызовов LLM живёт рядом с данными.
У подхода есть границы. Функции на Edge чувствительны к холодным стартам, у них ограничено время выполнения, а секреты вроде ключей OpenRouter нужно хранить аккуратно и не тянуть в клиент. Тяжёлые задачи, например обработку шести изображений за раз, стоит проверять по длительности, чтобы не упираться в лимиты платформы.
Зачем Nginx на VPS, если есть Supabase
Supabase даёт API и хостинг функций, но внешний вход в приложение удобно держать на своём домене. Nginx на VPS работает reverse proxy: принимает запросы из интернета, терминирует TLS, раскидывает трафик по нужным сервисам. Это даёт контроль над доменом, заголовками и базовой защитой, а ещё позволяет прятать внутренние адреса за одним входом.
За предсказуемость приходится платить ручной работой: конфиг Nginx, обновление сертификатов, слежение за состоянием сервисов. Для PoC это терпимо, в продакшене такой слой требует автоматизации.
Выбор Supabase снижает объём инфраструктурного кода, но переносит часть ответственности на настройку RLS и политик доступа. Здесь начинается зона, где AI помогает, но не берёт решения на себя.
Что AI не закрывает: инженерные задачи, которые пришлось решать вручную
Публичный разбор проекта не приводит конкретных SQL-политик и кода обработчиков, поэтому дальше - принципы, которые применяют в таком стеке и которые AI не выводит сам. Он не знает бизнес-контекст, не взвешивает архитектурные компромиссы и не несёт ответственности за безопасность и деньги.
RLS и защита публичных ссылок в Supabase
RLS (Row Level Security) в PostgreSQL ограничивает доступ на уровне строк. В MirrorVote это критично: пользователь видит только свои данные, а публичная ссылка для голосования открывает лишь нужные изображения и ничего лишнего. Без RLS любой запрос к таблице через API может вернуть чужие записи, потому что Supabase отдаёт доступ к таблицам напрямую.
Подход строится на политиках, привязанных к JWT: политика проверяет идентификатор пользователя и роль, а доступ к Storage ограничивается отдельно от таблиц. AI может сгенерировать каркас политики, но проверить границы доступа и продумать сценарии атаки должен инженер. Публичная ссылка - самый рискованный элемент: её легко сделать слишком широкой и открыть доступ к лишним фотографиям.
Идемпотентная обработка платёжных webhook ЮKassa
Платёжные сервисы повторяют webhook при сбоях сети или таймаутах. Если обрабатывать каждое уведомление как новое, пользователю спишут лимит дважды, а в базе появятся дубли. Идемпотентность решает это через уникальный идентификатор события и проверку, обрабатывалось ли оно раньше. На практике это таблица обработанных событий, транзакции и проверка статуса перед изменением баланса.
AI напишет код обработчика, но не выберет стратегию: где хранить ключи идемпотентности, что делать с частично выполненным платежом, как вести себя при расхождении статусов. Это архитектурное решение, и оно напрямую влияет на деньги.
Retry при ошибках LLM API через OpenRouter
Вызовы LLM через OpenRouter могут падать: таймауты, лимиты, недоступность модели. Без повторов пользователь теряет запрос, а с неаккуратными повторами оплачивает одну примерку несколько раз. Нужен retry с экспоненциальной задержкой и ограничением числа попыток, при этом списание лимита не должно дублироваться.
Retry - это часть архитектуры, а не цикл в коде. Приходится решать, где хранить состояние между попытками, как уведомлять пользователя о задержке, что логировать. AI предложит шаблон, но границы и стратегию выбирает инженер.
Observability и контроль стоимости вызовов
Базовый набор для PoC: логи ошибок, контроль доступности приложения, учёт стоимости внешних сервисов. В MirrorVote важно считать вызовы LLM через OpenRouter и платежи. Простые приёмы - логировать каждый вызов с моделью и объёмом токенов, держать дашборд по расходам и ставить алерт при превышении порога. AI сам это не настроит: нужен инженерный взгляд на метрики и пороги, а также понимание, какие отклонения считать авариями.
Экономика сценария: сколько стоит одна примерка в MirrorVote
По оценке, приведённой в описании кейса, обработка и анализ шести изображений через Gemini 2.5 Flash и Gemini 2.5 Flash Image обходятся примерно в $0,30 за примерку. Это ориентир для PoC, а не гарантированный тариф: стоимость зависит от модели, размера изображений и текущих цен провайдера.
Как считать стоимость LLM-вызовов на пользователя
Формула простая: число вызовов умножить на среднюю стоимость вызова. Обработка изображений и анализ образов - разные вызовы с разной ценой, поэтому их считают отдельно. На примере MirrorVote шесть изображений проходят через обработку, затем модель анализирует наряды, и суммарно выходит около $0,30. Для пет-проекта это приемлемо, при росте пользователей нужны лимиты и регулярный контроль расходов.
Выбор модели сильно меняет цифру. Если сравнивать провайдеров и версии, разница в стоимости может быть кратной, и это отдельная задача - подобрать модель под бюджет и качество. Такие компромиссы между архитектурой LLM, контекстным окном и стоимостью инференса разобраны в материале про выбор LLM и стоимость инференса.
Где заканчивается PoC и начинается продакшен-экономика
PoC может позволить себе ручные проверки и отказ гнаться за производительностью. Продакшен приносит требования к SLA, масштабированию и снижению стоимости. Решения, принятые на старте, становятся узким местом: без кэширования одинаковые примерки оплачиваются заново, а без батчинга вызовы дорожают. Критерии перехода понятны: растёт число пользователей, растёт счёт за LLM, появляются требования к надёжности. Тогда стоит пересматривать архитектуру и экономику сценария, а не ждать, пока расходы выйдут из-под контроля.
Чему учит MirrorVote: роль инженера смещается, а не исчезает
AI ускоряет написание кода, но архитектура, безопасность, платежи и эксплуатация остаются за инженером. Роль смещается от набора строк к проектированию системы, границам доверия и компромиссам. MirrorVote даёт готовый список участков, где нужен человек: RLS и публичные ссылки, идемпотентность webhook, retry для LLM, observability, контроль стоимости.
Выводы о том, что программисты больше не нужны, пока опережают данные. Бенчмарки вроде Real-SWE как раз пытаются измерить AI на реальных задачах разработки, и их результаты стоит читать с оговорками, ведь методология и набор задач у таких тестов ограничены (см. разбор Real-SWE и слухов о смерти программистов).
Как использовать CLAUDE.md для постоянного контекста
Claude Code поддерживает файловую систему памяти через CLAUDE.md. Память даёт постоянный контекст между сессиями: стандарты проекта, личные предпочтения разработки, правила для конкретных директорий, а также версионирование вместе с проектом. Это описано в руководстве по памяти Claude Code.
Практическая польза для такого PoC - зафиксировать в CLAUDE.md требования к RLS, идемпотентности и retry, чтобы AI учитывал их при генерации кода. Это снижает число ошибок, но не заменяет архитектурное мышление: правила пишет инженер, а модель лишь следует им.
Когда вайбкодинг оправдан, а когда нет
Вайбкодинг разумен для PoC и MVP, где важна скорость и допустимы упрощения. Для продакшена с платежами, персональными данными и высокими требованиями к надёжности одного AI мало: нужен дополнительный инженерный контроль. Риски известны: дырявые политики RLS, двойные списания, потеря данных при сбоях LLM. AI не несёт ответственности за результат, поэтому проверка и проектирование остаются на человеке.
Инструменты для AI-разработки быстро развиваются, и их полезно оценивать по методологии, а не по хайпу. Как это делают на практике, включая сравнение обвязок для кодинг-агентов по стоимости и качеству, показывает разбор оценки агентов от Databricks.
Практический вывод для своих проектов: используйте вайбкодинг для MVP, но с первого дня закладывайте решения по безопасности и деньгам - RLS, идемпотентность, retry, лимиты. Заведите CLAUDE.md с правилами проекта, держите код в Git, планируйте observability сразу, а не после первого инцидента. Подход работает не только для MirrorVote, но и для других AI-пет-проектов на Supabase и OpenRouter.