admin/coding — Сергей Малюгин Сергей Малюгин
Оставить заявку
~/ блог/ как-я-делаю-crm-за-3-дня
// вайб-кодинг

Как я делаю CRM за 3 дня с помощью модели

CRM-CLIENTS-V2.MDX

Месяц назад клиент написал: «нужна CRM для отдела продаж, как Bitrix, но без Bitrix». Через 3 дня была рабочая первая версия. Через две недели — на проде. В этом посте — что и как.

TL;DR

  • Стек: Next.js 15 (App Router) · Postgres · Prisma · Tailwind · ws для real-time. Деплой — Railway.
  • Модель: Claude Sonnet через Cursor. Около 80% кода написала модель, 20% — я (бизнес-логика, краевые случаи).
  • День 1 — схема БД и базовый CRUD. День 2 — UI: канбан и карточки сделок. День 3 — интеграции (telephony API + Telegram-бот для уведомлений).
  • Что НЕ сэкономило время: настройка деплоя, отладка вебсокетов, валидация форм с серверной стороны.

Контекст

Заказчик — отдел продаж B2B-агентства из 12 человек. Использовали Excel, потом Trello, потом amoCRM. Bitrix24 пробовали — «слишком тяжело, никто не открывает». Запрос был очень конкретный: «канбан сделок, карточка клиента, история звонков, уведомления в Telegram, всё».

Бюджет — 180 000 ₽. Срок — две недели. Своих разработчиков нет.

«Bitrix у нас живёт 4 месяца, потом все возвращаются в Excel. Сделай так, чтобы НЕ возвращались.»

— владелец агентства, на первом созвоне

День 1 — схема и CRUD

Начал не с UI, а с моделей. Открыл Cursor, написал в чат:

prompt · day-1.txt
Спроектируй prisma-схему для лёгкой CRM:
- Lead (имя, телефон, источник, статус, ответственный)
- Deal (название, сумма, стадия, дата закрытия, lead_id, owner_id, теги[])
- Activity (тип: звонок/письмо/встреча, deal_id, описание, создано_кем, когда)
- User (роль: admin/sales, имя, email, телефон)

Все таймстампы. Soft delete где имеет смысл.
Индексы для частых выборок (по owner, по статусу).
Сразу с миграциями.

Модель выдала схему за минуту. Я прочитал, попросил поправить два места — tags сделать связью к отдельной таблице (заказчик хотел админку тегов) и добавить nextActionAt в Deal для напоминалок. Применил миграцию, запустил Prisma Studio — данные модельных лидов лежат корректно.

Дальше — API. Не делал REST вручную, попросил модель сразу сгенерировать tRPC-роутеры: leads.list, leads.create, leads.update, аналогично для deals. Параллельно — серверные actions для оптимистичного UI.

// мой главный приём

Я НИКОГДА не прошу «напиши CRUD». Я прошу: «напиши tRPC-роутер с такими-то методами, эндпойнты идемпотентные, пагинация курсорная (а не offset), сортировки — параметром». Чем конкретнее — тем меньше потом править.

К вечеру первого дня у меня был рабочий бэкенд + временная заглушка-страница со списком лидов. 8 часов работы.

День 2 — UI: канбан и карточки

Самая опасная часть. Канбан — это drag-and-drop, который модели обычно пишут с багами. Я не прошу написать канбан с нуля. Я говорю:

prompt · day-2.txt
Сделай канбан-доску сделок:
- библиотека: dnd-kit (документация ниже, я скинул)
- 5 колонок: New, Qualified, Proposal, Negotiation, Won
- карточка: название, сумма, аватар ответственного, дни в этой стадии
- при дропе — мутирует через tRPC deals.updateStage (он уже есть)
- оптимистичный UI: карточка переезжает мгновенно, потом подтверждаем
- мобилка: горизонтальный скролл, dnd через long-press

Документацию dnd-kit я приложил в чат вручную. Без этого модель напишет с устаревшим API. Это второй мой главный приём — не верь модели в части свежих библиотек.

К вечеру второго дня — рабочий канбан, карточки сделок открываются в боковой панели, история активности, форма «добавить активность». Я добавил пару полировочных штук руками: горячие клавиши, фокус-видимость, undo для случайного перетаскивания.

День 3 — интеграции

Тут я уже не лез в код напрямую. Описание задачи в чат, проверка, мердж:

  • Telephony — клиент использует Mango Office. Их API — REST с подписями. Модель написала клиент и обработчик входящих звонков (создаёт активность в карточке клиента) за полчаса.
  • Telegram-уведомления — бот, который пингует менеджера при новом лиде и при изменении стадии сделки на «Negotiation». Час работы, включая хостинг бота на Vercel Cron.
  • Импорт — Excel → CRM. Просто загрузка xlsx, маппинг колонок, ручная сверка. Полтора часа.

Что НЕ сэкономило время

Хочу быть честным — не всё прошло гладко.

1. Деплой и инфра

Railway упал в середине второго дня (у них была глобальная авария). Час я мигрировал на Fly.io. Модель тут не помогает — это операционная работа.

2. WebSocket / real-time

Канбан должен обновляться у всех менеджеров одновременно. Модель написала вариант на socket.io, я пять раз гонял её туда-сюда — то race condition при drop, то memory leak при долгом коннекте. В итоге переделал на ws + redux pattern, гораздо проще.

3. Серверная валидация

Zod-схемы модель пишет хорошо, но не угадывает бизнес-правила. «Сумма сделки не может быть отрицательной» — это очевидно. «Стадию Won может проставить только админ или owner» — это уже не очевидно, и я писал это руками после первого пользовательского теста.

Итог

время на MVP
3 дня
vs ~3 недели обычно
время на прод
14 дней
с правками после тестов
стоимость
180k ₽
в рамках сметы

CRM работает второй месяц. Менеджеры в Excel НЕ возвращаются — это лучшая метрика. Заказчик заказал второй проект — внутренний портал.

Что бы сделал иначе

  • Начал бы с шаблона (clone) рабочего проекта, а не с нуля. Сэкономило бы первый день полностью.
  • WebSocket сразу делал бы через библиотеку с готовыми патернами (Liveblocks, например), а не руками.
  • Тестовый аккаунт с реальными данными подключил бы в первый день, а не на пятый.

Эпилог

Vibe coding — это не «модель пишет за меня». Это «модель пишет рутину, я думаю про архитектуру и проверяю». Когда я перестаю проверять — получается мусор. Когда я не пишу промпты конкретно — получаю шаблонное решение. Все ускорения, о которых я говорил выше, требуют твоего внимания на 100%, просто внимание это другого качества.

Если у вас есть проект, который завис на этапе «нет времени написать самим» — напишите мне. Возможно, мы соберём первую версию за тот же отрезок.

// поделиться: tg vk copy link
// нужен похожий проект?

Прикинем, что получится у вас.

$ калькулятор ~ заявка