Мини-CRM для заявок агентства
Тестовое задание. Ниже набросок продукта, разбор того, как он сделан, и ссылки на рабочую версию и код (github.com/Abasov11/mini-crm-leads).
В CRM уже лежат 10 демо-заявок с вымышленными контактами, чтобы были видны теги, статусы и история. Ваши заявки появятся сверху.
Вход для проверки: логин demo, пароль demo2026. Демо-доступ может все, кроме удаления и смены подключенного аккаунта, чтобы случайный посетитель не стер данные. Подключенный Telegram-аккаунт: @SalatMalatt, ему можно написать в личку.
Как проверить за 3 минуты
- Войдите в CRM и оставьте вкладку открытой.
- Напишите боту @minicrm_agency_leads_bot и ответьте на три вопроса. Заявка появится в списке сама, без перезагрузки страницы.
- Напишите что угодно в личку @SalatMalatt. Это тоже станет лидом с источником «Личка TG». Второе сообщение допишется в историю того же лида. Если вы есть у этого аккаунта в контактах, сообщение лидом не станет: так задумано, контакты считаются своими людьми.
- Откройте лида и поставьте тег. Клик по тегу в панели фильтров (на телефоне это лента над списком) покажет всех лидов с ним.
- Кнопка «+ Лид» заводит лида вручную, теги можно указать сразу.
- В настройках есть ссылка «Получать уведомления». Откройте ее в Telegram, и каждая новая заявка будет приходить вам сообщением с кнопкой «Открыть в CRM». Отключить: /stop.
1. Набросок продукта
Какую проблему решаем
В небольшом агентстве заявки приходят в бот, в личный Telegram менеджера и по звонку. Через неделю уже никто не помнит, кому ответили, а кто потерялся в переписке. Посчитать, сколько пришло заявок на сайты и сколько на рекламу, тоже нельзя.
Для кого
Агентство на 1-5 человек, у которого основной канал общения с клиентами - Telegram. Большая CRM им пока тяжела, таблица неудобна: туда все переносят руками.
Как работает
Бот-анкета ─────────────┐ Личка Telegram-аккаунта ─┼──> CRM: список лидов ──> теги, статус, история Ручное добавление ───────┘ (обновляется сама)
- Бот задает три вопроса: имя, контакт, задача. Имя подставляется кнопкой из профиля, контакт - кнопкой «поделиться номером» или ником. Если человек сразу написал задачу без /start, бот ее сохранит и спросит только недостающее. Перед отправкой показывает сводку. Кнопка «поделиться номером» принимает только свой номер: пересланную чужую карточку бот не возьмет.
- Подключенный аккаунт. Менеджер подключает свой Telegram по QR-коду в настройках, как еще одно устройство. Новые личные сообщения становятся лидами. Сообщения от людей из контактов по умолчанию не считаются лидами: это коллеги и знакомые. Боты и служебные уведомления Telegram тоже пропускаются.
- Склейка. Если человек пишет пятью сообщениями подряд, это один лид с историей, а не пять. Новый лид появится, когда прошлый закрыт статусом «Сделка» или «Отказ».
- Теги агентство заводит само («сайт», «срочно», «B2B»), они создаются прямо в карточке. Откуда пришел лид, система пишет отдельно, тегом это не делается: источник ставит она сама, и случайно снять его нельзя.
- Статусы: новый, в работе, сделка, отказ. Это минимум, без которого список через месяц превращается в свалку.
- Уведомления. Заявка, которую никто не увидел, ничем не лучше потерянной. Поэтому менеджер подписывается на бота по ссылке из настроек, и каждая новая заявка из любого канала приходит ему в Telegram с кнопкой «Открыть в CRM».
Что входит в MVP
Все четыре пункта задания, включая подключение обычного Telegram. Еще в MVP есть уведомления менеджеру в Telegram, фильтры (тег, источник, статус и поиск складываются), карточка с правкой на месте, живое обновление списка, вход по паролю, мобильная версия и темная тема.
Что сознательно оставлено за скобками
- Ответ клиенту из CRM. Пока есть кнопка «Написать в Telegram», которая открывает чат.
- Воронка и канбан, несколько менеджеров с назначением лидов.
- WhatsApp, Instagram, формы с сайта.
- Импорт и экспорт, отчеты.
Все это нужно, но без этого уже видно, работает ли основной путь: заявка пришла, не потерялась, разложена по тегам.


2. Разбор: как делал
Работал в Claude Code на своем сервере. У меня в нем настроены постоянные правила: сначала проект и критерии готовности, потом код, перед словом «готово» живая проверка, в конце независимая приемка вторым агентом. Поэтому большая часть моего времени ушла на постановку и проверку, а код и тесты писались по плану.
Порядок
| Этап | Что делал | Чем проверял |
|---|---|---|
| Проект | До кода расписал архитектуру, модель данных, логику каждого канала, дизайн и 10 критериев готовности. Документ лежит в репозитории, DESIGN.md. | Сверил план с каждым пунктом задания |
| Дизайн | Взял плоский стиль из подборки скилла ui-ux-pro-max. Палитру заменил на нейтральную с одним акцентом: для рабочего инструмента так спокойнее. | Скриншоты на 1440 и 375 px и в темной теме |
| Ядро | Данные, бот-анкета, прием сообщений из лички со склейкой и фильтрами, веб-интерфейс с живым обновлением. | Модульные и веб-тесты |
| Telegram | Бота создал через @BotFather, аккаунт подключил отдельной сессией по QR, тем же способом, что доступен в настройках CRM. | Живые сообщения боту и в личку |
| Выкладка | nginx, сертификат Let's Encrypt, systemd. Данные и подключение переживают перезапуск. | Перезапуск посреди анкеты |
| Приемка | Отдал результат второму агенту без своего отчета, исправил то, что он нашел. | См. ниже |
Какие ИИ-инструменты и для чего
- Claude Code (Claude Opus): проект, код, тесты, выкладка на сервер.
- Скилл ui-ux-pro-max: подбор стиля, шрифта и правил доступности для интерфейса.
- Второй агент на Claude Sonnet: независимая приемка. Он получает только задание и ссылку, без отчета о сделанном, иначе проверит только предъявленное.
- Playwright: браузерные сценарии и скриншоты, pytest: 26 тестов.
Как проверял качество
- Тесты на логику: склейку сообщений, теги, фильтры, роли, защиту форм, хранение анкеты.
- Живые проверки на рабочем адресе. Настоящие сообщения боту и в личку подключенного аккаунта. Браузерный сценарий: тег, фильтр, ручной лид, появление лида в соседней вкладке. Вход по QR через интерфейс. Уведомление менеджеру. Перезапуск сервиса посреди анкеты.
- Независимая приемка нашла 11 пунктов, блокеров среди них не было. После нее анкета хранится в базе и переживает перезапуск, команды вроде /help не становятся заявкой, у бота появился лимит заявок, демо-доступ больше не может удалять данные.
Промпты
Постановка задачи у меня короткая, потому что порядок работы задан постоянными правилами. Ниже фрагмент правил и промпт приемки.


3. Что сделал бы за следующую неделю
- Ответ клиенту прямо из карточки: через бота или через подключенный аккаунт, ответ сохраняется в историю.
- Кнопки «Взять в работу» и «Поставить тег» прямо в уведомлении, чтобы не открывать CRM.
- Несколько менеджеров: у каждого свой подключенный аккаунт, лид назначается на того, кому написали.
- Подсказка тегов моделью по тексту заявки. Решение остается за человеком.
- Форма для сайта и вебхук, чтобы заявки с лендинга шли в тот же список.
- Канбан по статусам и простой отчет: сколько заявок по тегам и источникам за неделю.