Добавить в корзинуПозвонить
Найти в Дзене
Vibecode Wiki

Как запустить сервис самому: всё что дают на курсах по вайбкодингу — в одной статье

Инструмент Зачем Стоимость Claude Code Агент, пишет и запускает код Pro $20/мес (токены отдельно) или Max $100/мес Codex CLI Альтернативный агент от OpenAI ChatGPT Plus/Pro/Team включён VS Code Редактор, где хранится проект бесплатно Supabase База данных и авторизация бесплатно до лимита VPS Сервер для деплоя от $6/мес OpenRouter API для AI-функций в сервисе от $10 пополнение GitHub Хранение кода и деплой бесплатно Claude Code и Codex — взаимозаменяемы. Логика работы та же, различаются только команды установки и название файла с инструкциями (CLAUDE.md или AGENTS.md). Далее в тексте будет указано где они расходятся. Claude Code: npm install -g @anthropic-ai/claude-code claude # запустится браузерная авторизация Codex CLI: npm install -g @openai/codex # именно @openai/codex, не просто codex codex auth # браузерная авторизация через ChatGPT Важно: пакет без @openai/ — это несвязанный проект 2012 года. Он установится без ошибок но ничего полезного не сделает. После установ
Оглавление

Что нужно

Инструмент Зачем Стоимость Claude Code Агент, пишет и запускает код Pro $20/мес (токены отдельно) или Max $100/мес Codex CLI Альтернативный агент от OpenAI ChatGPT Plus/Pro/Team включён VS Code Редактор, где хранится проект бесплатно Supabase База данных и авторизация бесплатно до лимита VPS Сервер для деплоя от $6/мес OpenRouter API для AI-функций в сервисе от $10 пополнение GitHub Хранение кода и деплой бесплатно

Claude Code и Codex — взаимозаменяемы. Логика работы та же, различаются только команды установки и название файла с инструкциями (CLAUDE.md или AGENTS.md). Далее в тексте будет указано где они расходятся.

Блок 1. Инструменты

Установить агента

Claude Code:

npm install -g @anthropic-ai/claude-code

claude # запустится браузерная авторизация

Codex CLI:

npm install -g @openai/codex # именно @openai/codex, не просто codex

codex auth # браузерная авторизация через ChatGPT

Важно: пакет без @openai/ — это несвязанный проект 2012 года. Он установится без ошибок но ничего полезного не сделает.

После установки запустите агента в любой папке:

claude # для Claude Code

codex # для Codex

Агент видит все файлы в текущей папке, может их создавать, редактировать и запускать команды в терминале.

Как работает связка VS Code + агент

VS Code — редактор. Там хранится код и видно что происходит. Агент запускается в встроенном терминале (Ctrl+ на Windows/Linux, Cmd+ на Mac).

Рабочий цикл выглядит так:

  1. Открыли папку проекта в VS Code
  2. Открыли терминал, запустили claude или codex
  3. Написали задачу текстом
  4. Агент предложил изменения — вы проверили и подтвердили
  5. Открыли браузер на localhost:3000 — проверили результат
  6. Написали следующую задачу

По умолчанию Claude Code спрашивает разрешение перед каждым изменением файла. Codex работает аналогично. Если хочется чтобы агент работал без постоянных подтверждений — в Claude Code это флаг --dangerously-skip-permissions, в Codex — режим --full-auto. Для обучения лучше оставить подтверждения включёнными — так лучше понимаешь что происходит.

Блок 2. Спека и флоу

Спека — это текстовый файл с описанием сервиса. Главный урок вайбкодинга: чем точнее описана задача, тем меньше итераций нужно. Не «сделай форму заявок», а полное описание кто пользуется, что делает и что происходит в каждом состоянии.

Попросите агента помочь написать спеку в диалоге:

Я хочу сделать форму для сбора заявок с простой админкой.

Задавай мне вопросы по одному, я буду отвечать.

По ходу записывай всё в файл SPEC.md.

Когда соберёшь достаточно информации — покажи итоговый файл.

Агент будет уточнять детали. Отвечайте конкретно. В конце у вас будет файл — основа для всей дальнейшей работы.

Что должно быть в спеке

Вот шаблон который работает. Это не формальный документ — просто ответы на конкретные вопросы:

# SPEC.md

## Что это

Форма для приёма заявок на консультацию.

Гость заполняет форму → заявка сохраняется →

владелец видит все заявки в закрытой админке.

## Пользователи

- Гость — заполняет форму, не регистрируется

- Админ — логинится, видит все заявки, меняет статус

## Флоу гостя

1. Открывает страницу → видит форму

2. Вводит имя, email, текст запроса → нажимает «Отправить»

3. Видит экран благодарности: «Свяжемся в течение дня»

## Флоу админа

1. Открывает /admin → редиректит на /admin/login если не залогинен

2. Вводит email и пароль → попадает в список заявок

3. Видит заявки: имя, email, текст, дата, статус (новая / в работе / закрыта)

4. Нажимает на заявку → может изменить статус

## Экраны и состояния

### Форма (/):

- Состояние: обычное — форма заполнена частично или пуста

- Состояние: отправка — кнопка неактивна, показывает «Отправляю...»

- Состояние: ошибка валидации — подсветить незаполненные поля, текст ошибки

- Состояние: ошибка сервера — «Что-то пошло не так, попробуйте позже»

- Состояние: успех — скрыть форму, показать сообщение

### Список заявок (/admin):

- Состояние: загрузка — скелетон строк

- Состояние: пусто — «Заявок пока нет»

- Состояние: список — таблица с сортировкой по дате (новые сверху)

## Что НЕ входит в первую версию

- Уведомления на email при новой заявке

- Поиск и фильтрация заявок

- Несколько админов

- Удаление заявок

## Стек

Next.js App Router, TypeScript, Tailwind CSS, Supabase

Раздел «Что НЕ входит» — один из важнейших. Без него агент начинает добавлять функции которые не просили, а вы теряете время на их проверку.

Описание состояний экранов — сила дизайнера

Обычный разработчик напишет в промпте «сделай форму» и не подумает про empty state, ошибку валидации и состояние загрузки. Дизайнер думает именно так — экранами и состояниями. Это ваше преимущество.

Чем подробнее описаны состояния в спеке — тем меньше будет правок после. Агент реализует ровно то что написано.

Блок 3. Интерфейс

Создать проект

Попросите агента:

Создай новый Next.js-проект в папке request-form.

Стек: TypeScript strict mode, Tailwind CSS, App Router.

После создания запусти dev-сервер и убедись что localhost:3000 открывается.

Или сами:

npx create-next-app@latest request-form --typescript --tailwind --app

cd request-form

npm run dev

Создать файл с инструкциями для агента

Это аналог брифа — агент читает его в начале каждой сессии. Для Claude Code это CLAUDE.md, для Codex — AGENTS.md. Структура одинаковая:

# AGENTS.md (или CLAUDE.md)

## Контекст

Читай SPEC.md перед началом любой задачи.

Если что-то не описано в SPEC.md — спроси, не придумывай.

## Стек

- Next.js App Router, TypeScript strict mode

- Tailwind CSS — никаких произвольных hex-значений, только классы Tailwind

- Supabase — auth и база данных через @supabase/ssr

## Правила

- Каждый экран в отдельном компоненте

- Все состояния из SPEC.md обязательны: загрузка, ошибка, пусто

- После изменений запусти npm run build — убедись что TypeScript не ругается

- Не добавляй фичи которых нет в SPEC.md

## Структура

src/

app/ — роуты

components/ — компоненты

lib/ — утилиты, supabase-клиент

Собирать интерфейс по одному экрану

Не давайте задачу «собери весь интерфейс сразу». Лучше по одному экрану — так проще проверить каждый результат.

Задача на форму:

Прочитай SPEC.md.

Создай главную страницу src/app/page.tsx с формой заявки.

Поля: Имя (обязательное), Email (обязательное, валидация формата),

Текст запроса (обязательное, минимум 10 символов).

Кнопка «Отправить».

Состояния кнопки: обычное / «Отправляю...» с disabled во время запроса.

Состояния формы: пустая → валидация → успех (скрыть форму, показать текст)

→ ошибка сервера (toast или текст под кнопкой).

Пока используй console.log вместо реального запроса — реальный добавим позже.

Адаптивно: мобильный и десктоп.

После того как форма выглядит правильно — проверяйте конкретно. Не «что-то не так», а точное описание:

Кнопка «Отправить» на мобильном слишком мелкая — менее 44px высотой.

Сообщение об ошибке валидации появляется только после нажатия кнопки,

а нужно при потере фокуса (onBlur) на каждом поле.

Задача на страницу успеха:

После отправки формы скрой её и покажи блок с текстом:

«Спасибо! Свяжемся с вами в течение дня.»

И ссылку «Отправить ещё одну заявку» которая возвращает форму.

Задача на админку:

Создай страницу src/app/admin/page.tsx.

Таблица заявок: колонки — Имя, Email, Дата, Статус, Действие.

Статус: три варианта — «Новая», «В работе», «Закрыта».

Сортировка: новые сверху.

Состояния: загрузка (скелетон на 5 строк), пусто («Заявок пока нет»), список.

Пока используй моковые данные — массив из 3 объектов.

Реальные данные подключим когда настроим Supabase.

Блок 4. Деплой — сразу, не в конце

Деплоить нужно как только есть первый рабочий экран. Не ждите пока всё готово. Ранний деплой показывает реальное поведение на сервере и помогает поймать проблемы которые не видны локально.

Vercel — одна команда

npm install -g vercel

vercel

Vercel спросит несколько вопросов и задеплоит. Бесплатно для личных проектов. Каждый push в GitHub — автоматически новая версия.

VPS — агент делает сам

Купите VPS: DigitalOcean от $6/мес, Timeweb от 200 руб/мес, Selectel. Нужен Ubuntu 22/24.

Задача для агента:

Задеплой этот Next.js-проект на мой VPS.

IP: [адрес]

Пользователь: root

Пароль: [пароль]

Что нужно сделать:

— Установить Node.js 20, nginx, PM2

— Запушить проект в новый GitHub-репозиторий [ссылка]

— Склонировать на сервер, запустить npm install и npm run build

— Запустить через PM2 на порту 3000

— Настроить nginx как reverse proxy: все запросы → localhost:3000

— Выписать SSL-сертификат через Let's Encrypt для домена [домен]

— PM2 в автозапуске при перезагрузке сервера

После каждого шага сообщай результат.

Агент выполнит всё последовательно. Если на каком-то шаге упадёт ошибка — опишет её и предложит решение.

Блок 5. База данных и авторизация

Подключить Supabase

Зарегистрируйтесь на supabase.com, создайте новый проект. В настройках (Settings → API) скопируйте Project URL и anon key.

Задача агенту:

Подключи Supabase к проекту.

Project URL: [вставить]

Anon key: [вставить]

Нужно:

1. Установить @supabase/ssr и @supabase/supabase-js

2. Создать src/lib/supabase/client.ts — браузерный клиент

3. Создать src/lib/supabase/server.ts — серверный клиент для App Router

4. Добавить переменные в .env.local:

NEXT_PUBLIC_SUPABASE_URL=...

NEXT_PUBLIC_SUPABASE_ANON_KEY=...

5. Убедиться что .env.local есть в .gitignore

Создать таблицы

Создай SQL-миграцию для таблицы requests в Supabase.

Поля:

- id: uuid, primary key, default gen_random_uuid()

- name: text, not null

- email: text, not null

- message: text, not null

- status: text, not null, default 'new',

check (status in ('new', 'in_progress', 'closed'))

- created_at: timestamptz, default now()

Включи Row Level Security (RLS):

- Вставка (insert): разрешить всем (анонимным тоже)

- Чтение (select): только авторизованным пользователям

- Обновление (update): только авторизованным

Дай мне готовый SQL для выполнения в Supabase Dashboard → SQL Editor.

Скопируйте SQL, откройте Supabase Dashboard → SQL Editor → New query → вставьте и запустите.

Подключить авторизацию в админку

Добавь авторизацию для раздела /admin через Supabase Auth.

Нужно:

1. Страница /admin/login:

— Форма: email + пароль

— Кнопки «Войти» и «Зарегистрироваться»

— При ошибке: показать текст ошибки под формой

— При успехе: редирект на /admin

2. Middleware (middleware.ts в корне):

— Любой запрос на /admin/* — проверить сессию

— Если нет сессии — редирект на /admin/login

3. Кнопка «Выйти» на странице /admin

— При нажатии: signOut → редирект на /admin/login

После этого создайте тестового пользователя в Supabase Dashboard → Authentication → Users → Add user.

Заменить моковые данные на реальные

Форма → реальная отправка:

Форма на главной странице сейчас делает console.log.

Замени на реальную отправку в Supabase.

Используй Server Action (файл src/app/actions.ts):

— Принимает: name, email, message

— Валидирует: все поля обязательные, email — валидный формат

— Вставляет в таблицу requests

— Возвращает: { success: true } или { error: 'текст ошибки' }

В форме: при ошибке — показать текст пользователю,

при успехе — переключить в состояние успеха.

Админка → реальные данные:

Страница /admin сейчас показывает моковые данные.

Замени на загрузку из Supabase.

Список заявок — серверный компонент, запрос через серверный клиент.

Сортировка: created_at DESC.

Изменение статуса — Client Component с Server Action:

— Выпадающий список: Новая / В работе / Закрыта

— При изменении: обновляет запись в базе,

перезагружает данные через revalidatePath('/admin')

Блок 6. AI-функции и интеграции

OpenRouter — один API для всех моделей

OpenRouter даёт доступ к Claude, GPT, Gemini и десяткам других моделей через единый API. Удобен для AI-функций в сервисе: не нужно заводить несколько подписок.

Зарегистрируйтесь на openrouter.ai, пополните баланс, скопируйте ключ.

Добавь в .env.local:

OPENROUTER_API_KEY=sk-or-...

Создай src/lib/openrouter.ts:

async function generateReply(

customerName: string,

customerMessage: string

): Promise

Функция отправляет запрос к OpenRouter.

Модель: anthropic/claude-sonnet-4

Системный промпт: «Ты помощник по работе с клиентами.

Пиши вежливо, по-русски, кратко — 2-3 предложения.»

Пользовательский промпт: «Напиши черновик ответа клиенту [имя],

который написал: [сообщение]»

При ошибке запроса — вернуть null, не бросать исключение.

Добавить в админку:

В таблицу заявок добавь кнопку «Черновик ответа» рядом с каждой заявкой.

При нажатии:

— Кнопка показывает спиннер

— Вызывает generateReply с именем и текстом заявки

— Показывает результат в модальном окне с кнопками «Скопировать» и «Закрыть»

— Кнопка «Скопировать» копирует текст в буфер, меняет текст на «Скопировано ✓» на 2 секунды

Telegram-уведомления о новых заявках

Создайте бота через @BotFather в Telegram, получите токен. Узнайте свой chat ID через @userinfobot.

При успешной вставке заявки в Supabase отправляй уведомление в Telegram.

В Server Action после INSERT добавь:

fetch('https://api.telegram.org/bot[токен]/sendMessage', {

method: 'POST',

headers: { 'Content-Type': 'application/json' },

body: JSON.stringify({

chat_id: '[chat_id]',

text: `Новая заявка от ${name}\nEmail: ${email}\n\n${message}`

})

})

Запрос асинхронный — не await, не блокирует ответ пользователю.

Ошибка отправки не влияет на сохранение заявки.

Блок 7. Тесты

Тесты нужны чтобы знать — новое изменение не сломало то что уже работает. Особенно важно когда проект растёт.

Unit-тесты через Vitest

Установи Vitest и напиши тесты для основных функций.

Что тестировать:

1. Валидация формы (src/lib/validate.ts — создай если нет):

— Пустое имя → ошибка 'Введите имя'

— Невалидный email → ошибка 'Введите корректный email'

— Сообщение короче 10 символов → ошибка 'Слишком короткое сообщение'

— Все поля заполнены корректно → возвращает null (нет ошибок)

2. generateReply из openrouter.ts:

— Замокай fetch

— Успешный ответ → возвращает строку

— Ошибка сети → возвращает null, не бросает исключение

После написания запусти npx vitest run — все тесты должны пройти.

E2E-тест через Playwright

Установи @playwright/test и напиши e2e тест:

1. Открыть главную страницу

2. Заполнить форму: имя «Тест», email «test@example.com»,

сообщение «Тестовое сообщение для проверки»

3. Нажать «Отправить»

4. Проверить что появился текст «Спасибо»

5. Проверить что форма больше не видна

Тест должен использовать тестовую базу (задай через env SUPABASE_URL_TEST)

или мокать Server Action.

Pre-commit хук — тесты перед каждым коммитом

Настрой pre-commit хук через husky и lint-staged:

Перед каждым коммитом:

1. npx vitest run — unit-тесты

2. npm run build — проверка TypeScript и сборки

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

Блок 8. Портфолио и кейс

Что показывать

Сервис в продакшене — это уже кейс. Но для портфолио важно показать мышление, а не только результат.

Структура кейса для вайбкодинга:

## Задача

Что хотел сделать и зачем — одним абзацем.

## Как описывал задачу

Покажите первую и финальную версию промпта на одну фичу.

Что уточнялось, от чего отказались и почему.

## Что было нетривиально

Один-два момента где агент не справился с первого раза.

Что именно не так и как переформулировали задачу.

## Результат

Ссылка на живой сервис.

Скриншот или короткое видео.

Разница между сильным кейсом и слабым — в разделе «как описывал задачу». Два похожих по результату сервиса, но один показывает процесс мышления — и это тот который запомнят.

Типичные проблемы

Агент ходит по кругу с одной ошибкой. Не давайте ему больше итераций с той же формулировкой. Откройте новую сессию, опишите только конкретную ошибку: текст из консоли, файл, строку. Без контекста всего проекта.

После изменений сломалось что работало. Запустите npx vitest run. Если тестов нет — попросите агента написать тест на сломавшееся место, потом починить его.

Агент добавляет фичи которые не просили. В AGENTS.md/CLAUDE.md добавьте явное правило: «Не добавляй ничего чего нет в SPEC.md. Если считаешь нужным — спроси прежде чем делать».

Суpabase выдаёт ошибку Row Level Security. Значит политика RLS не разрешает операцию для текущего пользователя. Опишите агенту: что за операция, авторизован ли пользователь, и текст ошибки. Агент поправит политику.

Контекст теряется между сессиями. SPEC.md и AGENTS.md/CLAUDE.md решают это. В начале новой сессии: «Прочитай SPEC.md и AGENTS.md. Кратко — что уже сделано, что осталось».

Итог

Артефакт Где лежит Описание сервиса SPEC.md Правила для агента AGENTS.md или CLAUDE.md Интерфейс src/app/ и src/components/ База данных и авторизация Supabase AI-функции src/lib/openrouter.ts Тесты Vitest + Playwright Сервис в продакшене VPS или Vercel

Главное изменение после первого запущенного сервиса: перестаёшь думать «нужен разработчик» и начинаешь думать «нужна спека».

Источник и полная версия: VibeCode Wiki