Задача
Клиент продаёт бытовую технику в нескольких магазинах. Запрос на подбор полезен, только если он полный: размеры, тип установки и подключения, цвет, примерный бюджет. Дальше он должен быстро попасть к менеджеру нужного магазина, вернуться к покупателю конкретным предложением и не потеряться в переписке. Это запрос на подбор, а не покупка: оплаты и резерва нет.
Главная проблема — не чат, а структура и ответственность. Свободное сообщение нельзя сравнить, направить и учесть, а заявку без одного ответственного либо обрабатывают дважды, либо не обрабатывает никто.
Объём первой версии
- Вошло
- Пошаговый опрос для каждой категории техники, который задаётся конфигурацией. Одна открытая заявка на покупателя. Маршрутизация по магазину и одна кнопка «Взять». Предложения с моделями, ценами и альтернативами. Статусы для покупателя. Роли и админ-панель в Telegram. Дашборд владельца только для чтения.
- Не вошло
- Оплата и резерв, интеграция со складом и CRM, AI-функции. Ценность — в надёжном процессе, а не в автоматизации ради автоматизации.
Что сделано
- ОпросПокупатель выбирает магазин и категорию и отвечает на вопросы по одному: размеры, тип установки и подключения, цвет, бюджет. Любой вопрос можно пропустить.
- ЗаявкаПеред отправкой покупатель видит черновик и может поправить или удалить позиции. Новая заявка заменяет прежнюю открытую.
- МаршрутизацияЗаявку с кнопкой «Взять» получают все менеджеры выбранного магазина; владельцем становится первый нажавший. Если менеджеров в магазине нет, её получают супервайзеры, затем администраторы.
- ПредложениеМенеджер добавляет модель и цену по каждой позиции, может предложить альтернативы или отметить отсутствие. Отправленное предложение не редактируется: исправление отправляется новой версией.
- ДиалогВ мини-приложении покупатель выбирает варианты и подтверждает. Его сообщения боту привязываются к заявке, а менеджер отвечает из мини-приложения.
Владелец бизнеса управляет людьми, ролями, магазинами и рассылками в админ-панели Telegram, а на веб-дашборде видит заявки по статусам, сравнение магазинов и среднее время до взятия заявки.
Моя роль
- Сделано мной
- Весь продукт для клиента: процесс и модель данных, архитектура, бэкенд, бот и мини-приложение, маршрутизация, уведомления, диалог покупателя и менеджера, дашборд, тесты и развёртывание.
- Со стороны клиента
- Сам бизнес: магазины, сотрудники, ассортимент и параметры, важные для каждой категории. Разрешение показать проект в портфолио.
Ключевые решения
- Маршрутизация по магазину и атомарное «Взять»
- Заявка уходит всем менеджерам магазина, владельцем становится первый взявший. Взятие — одно условное обновление в базе, поэтому одну заявку не могут взять двое.
- Версии предложений
- Отправленное предложение не меняется, исправление — новая версия: покупатель и менеджер всегда обсуждают одно и то же, а история остаётся понятной.
- SQLite и outbox вместо лишней инфраструктуры
- Чтобы состояние переживало перезапуск, а уведомления не терялись, не понадобились ни Redis, ни отдельный сервер базы данных. Хватило SQLite и очереди исходящих уведомлений (outbox) внутри процесса: в базу пишет только бот, дашборд её только читает.
- Простые отзываемые сессии мини-приложения
- Подписанные данные запуска Telegram проверяются один раз, дальше работает непрозрачная сессионная cookie, на сервере хранится только её хеш; смена роли или магазина её отзывает. От JWT и refresh-токенов я отказался.
Проверка
- Около 300 тестов бэкенда и более 100 тестов мини-приложения.
- Каждый релиз собирается изолированно, проходит независимое ревью, проверяется в браузере на ширинах 320–430 px в светлой и тёмной теме на синтетических данных и ещё раз после развёртывания.
- Внутреннее ревью ранней версии нашло несколько проблем с правами доступа и одновременной обработкой заявок; их исправили до следующего этапа — мини-приложения.
- План отката готовится до каждого релиза; старые резервные копии базы для обычного отката не используются.
Статус
Работает у клиента. Разработка — с февраля 2026 года; веб-дашборд появился в апреле, роли и магазины — в августе, мини-приложение — в конце августа, диалог покупателя и менеджера — в сентябре 2026. Бот открыт для всех, мини-приложением и дашбордом пользуются покупатели и сотрудники клиента. Публичных бизнес-показателей у проекта нет.
Технологии
- Бот и API
- Python, aiogram 3, aiohttp; один процесс обслуживает бота и API мини-приложения
- Мини-приложение
- React 18, TypeScript, Vite; тесты на Vitest и Testing Library
- Данные
- SQLite с аддитивными миграциями; надёжный outbox уведомлений
- Дашборд
- Streamlit, только чтение, за аутентификацией
- Авторизация
- Данные запуска Telegram с проверкой HMAC, отзываемые сессионные cookie
- Инфраструктура
- Docker Compose; статика мини-приложения за nginx