Проект целиком

Дашборд и Telegram-алерты поверх RetailCRM

Некоммерческий проект, код открыт

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

Задача

  • Собрать рабочую цепочку от источника заказов до руководителя, а не отдельный экран с графиками.
  • Дашборд должен читать данные из одного места, а не опрашивать CRM при каждом открытии: иначе скорость страницы зависит от чужого сервиса, а лимиты его API становятся проблемой пользователя.
  • Уведомление о крупном заказе должно приходить само, без того чтобы кто-то заходил в систему и смотрел.

Как устроена цепочка

Четыре звена, у каждого одна ответственность. Данные идут в одну сторону, и это главное свойство системы: любую точку можно проверить отдельно, зная, что приходит на вход.

  1. Источник заказов

    Пятьдесят заказов из файла импортируются в RetailCRM — так система получает реальный upstream вместо выдуманных данных внутри себя.

  2. RetailCRM

    Остаётся единственным источником заказов. Сюда система только смотрит: своей копии истины у неё нет.

  3. Supabase

    База, в которую заказы синхронизируются. Для дашборда и уведомлений это единственный источник данных — они не ходят в CRM напрямую.

  4. Дашборд и уведомления

    Интерфейс на Next.js читает базу. Отдельный процесс проверяет заказы и отправляет уведомление в Telegram, если сумма превысила порог.

Правила, которые система не нарушает

Это не пожелания к коду, а условия, при которых он остаётся предсказуемым. Каждое из них закрывает конкретный способ всё сломать.

  • RetailCRM — источник заказов, и только он. Второй источник означал бы спор о том, чья цифра верная.
  • Дашборд и уведомления читают только базу и никогда не обращаются в CRM напрямую. Иначе скорость интерфейса и лимиты чужого API становятся проблемой пользователя.
  • Отправка уведомлений живёт только на сервере. Токен бота в браузере означал бы, что писать от его имени может кто угодно.
  • Порог уведомления — объявленное правило, а не число, спрятанное в середине кода: сумма заказа выше 50 000 KZT.

Что видно на дашборде

  • Ключевые показатели по заказам и выручке
  • Динамику по периодам
  • Разбивку по статусам заказов
  • Разбивку по маркетинговым источникам
  • Разбивку по способу оформления
  • Таблицу заказов и детализацию каждого

Что оказалось нетривиальным

Самая полезная часть любого проекта — не то, что получилось с первого раза. Это реальные места, где живая интеграция повела себя не так, как описано в документации.

  • Живой API вернул не ту форму данных, которую ждал код

    Классическая история интеграции: на бумаге контракт один, в реальном ответе — другой. Адаптер пришлось приводить к тому, что сервис отдаёт на самом деле, а не к тому, что он обещает.

  • Повторный импорт оказался не обновлением, а вторым заходом

    Импорт вёл себя как первичная заливка и отклонял дубликаты по внешнему идентификатору, вместо того чтобы обновлять уже загруженное. Разница видна только когда данные заливаешь второй раз — и именно тогда она дорого стоит.

  • Валюта сменилась на ходу

    Сначала аккаунт сохранял суммы в рублях, потом контракт был приведён к тенге. Для системы, где есть порог уведомления, смена валюты — это не косметика, а изменение смысла числа, по которому принимается решение.

  • Одно поле смешивало две разные сущности

    Источник заказа содержал вперемешку рекламную метку и способ оформления. Пока они лежат в одном поле, аналитика по источникам невозможна: непонятно, что именно считаешь. Поле было разделено на два, а исторические данные заполнены заново.

Чем это проверяется

У каждого модуля рядом лежит свой тест — не один общий прогон в конце, а проверка на уровне того куска, который может сломаться.

  • Тесты на чтение и подготовку данных дашборда
  • Тесты на импорт и синхронизацию с RetailCRM
  • Тесты на отправку уведомлений
  • Тесты на работу с базой и на конфигурацию окружения
  • Отдельная проверка того, что документация не разошлась с кодом

Что важно знать, глядя на этот проект

  • Это тестовое задание, а не работа для клиента. Именно поэтому его можно показывать целиком, вместе с кодом: клиентские системы обычно закрыты.
  • Данные на скриншотах синтетические — пятьдесят заказов из файла, а не чья-то реальная выручка.
  • Живой стенд сейчас отключён хостингом. Смотреть стоит код и разбор, а не демо.

С чего начать

Опишите задачу — отвечу, что с ней можно сделать

Не нужно техническое задание и не нужно заранее понимать решение. Достаточно рассказать, что происходит сейчас и что хочется изменить.

Что полезно написать сразу

  1. Чем занимается бизнес — одной строкой
  2. Какой процесс отнимает время или какой продукт хочется запустить
  3. Что уже используете: CRM, таблицы, сервисы, сайт

Разбор бесплатный. Если задача не моя — скажу прямо.

garguliyadavid@gmail.com