CRM, соединяющая два мира, не ломая ни одного

Клиент перерос свой инструмент управления проектами. Их основная SEO-платформа вела миграции, цепочки, журналы и аналитику — но в ней не было понятий клиентских отношений, стадий сделок и командных воркфлоу. Для этого они использовали сторонний таск-трекер, но он был оторван от операционных данных. Оператор сначала проверял технический статус в SEO-платформе, потом переключался в таск-трекер за клиентским контекстом, а затем вручную переносил цифры между ними. Запрос был — CRM, который живёт рядом с их платформой: та же экосистема, общие данные, но собственное пространство для управления отношениями.

Стек

  • Next.js 14
  • Socket.IO
  • Prisma
  • PostgreSQL

отдельное приложение и прокси

Сделали его отдельным приложением со своей кодовой базой и своей базой данных. Это было осознанное архитектурное решение. Схема базы основной SEO-платформы уже была сложной и тесно связанной — прикручивать к ней CRM-таблицы означало создавать кошмар поддержки. Вместо этого CRM ходит в основную платформу через прокси API-роуты. Когда оператор открывает карточку, CRM в реальном времени тянет связанную цепочку миграций, записи журнала, аналитические данные и ошибки вебмастера из основной платформы. Своя база CRM хранит доски, карточки, комментарии, стикеры и пользовательские настройки — всё, что специфично для CRM.

доска и виртуализация

Интерфейс доски — канбан с drag-and-drop на @dnd-kit. Карточки двигаются между колонками, колонки представляют стадии сделок, каждое перемещение моментально сохраняется. Добавили комментарии с тредами, цветные стикеры для быстрой визуальной категоризации и поиск, индексирующий заголовки карточек, описания и текст комментариев. Для досок с сотнями карточек сделали виртуализированный рендеринг через @tanstack/react-virtual — в DOM присутствуют только карточки в видимой области, что держит интерфейс отзывчивым даже при тысячах элементов. Архив позволяет операторам убирать завершённую работу, не теряя историю.

реалтайм на socket.io

Реалтайм-обновления через Socket.IO были обязательны: несколько операторов одновременно работают с одними и теми же досками, и устаревшее состояние ведёт к конфликтам. Когда один оператор передвигает карточку, все остальные на этой доске видят перемещение мгновенно. Комментарии появляются по мере публикации. Изменения стикеров расходятся без рефреша. Реализация потребовала sticky sessions на стороне деплоя: соединения Socket.IO должны держать аффинити с тем инстансом сервера, где живёт их состояние. Не менее важна обработка переподключений — сетевые провалы случаются часто, клиент теряет WebSocket-соединение примерно раз в несколько часов. Система ловит разрыв, кладёт пропущенные события в очередь и проигрывает их при переподключении, так что ничего не теряется.

миграция и мост с платформой

Самой нестандартной частью работы был импорт из YouGile. Прежние данные клиента по управлению проектами лежали в YouGile, и их нужно было перенести в новый CRM. Модели данных почти не пересекались: YouGile строится вокруг проектов и задач с подзадачами, а наш CRM использует доски с плоским списком карточек. Написали разовый скрипт миграции, который смаппил проекты YouGile в доски CRM, задачи — в карточки, подзадачи — в чек-листы внутри карточек, а комментарии — в комментарии. Вложения скачивались и заливались заново. Маппинг не был идеален — часть структурной информации потерялась в переводе, — но клиент принял компромиссы после ревью тестовой миграции самого маленького проекта.

Прокси-архитектура, связывающая CRM с основной платформой, добавила своей сложности. API-роуты CRM пробрасывают запросы в эндпоинты основной платформы, преобразуя ответы под то, что ожидает фронтенд CRM. Аутентификация проходит через обе системы: CRM выпускает свои JWT через jose, но валидирует их по записям пользователей в основной платформе. Если основная платформа лежит или медленная, CRM продолжает работать со своими данными — карточки, комментарии, управление досками работают независимо. Только наложенные данные (цепочки, миграции, аналитика) показывают состояние загрузки, пока основная платформа не ответит.

результаты

CRM даёт операторам единое рабочее пространство и для управления отношениями, и для технических операций. Дашбордные виды на Recharts выводят метрики, ради которых раньше нужно было переключаться между тремя инструментами — стоимость пайплайна сделок, доля завершённых миграций и health score клиентов теперь на одном экране.