Как спроектировать собственную CRM: архитектура и модель данных
Продвинутое4 минРедакция Innovialabs
Коротко
Устойчивая собственная CRM держится на небольшом наборе базовых сущностей, воронках, описанных данными, а не кодом, правах на уровне записей, неизменяемой истории действий и отдельном слое интеграций на событиях.
Короткий ответ
Собственная CRM, которая проживет долго, строится на пяти решениях:
- Небольшая стабильная модель данных: контакты, компании, сделки, активности, пользователи.
- Воронки и статусы хранятся как данные, чтобы руководитель менял их без релиза.
- Права доступа продуманы с первого дня, вплоть до уровня записи.
- Неизменяемая история действий фиксирует каждое изменение и касание.
- Слой интеграций отделен от ядра и работает через события.
Если эти решения приняты правильно, новые функции становятся настройкой, а не переписыванием.
Базовые сущности
Начните с сущностей, которые есть в любом процессе продаж:
| Сущность | Что хранит | Ключевые связи |
|---|---|---|
| Контакт | Человек: имя, телефоны, email, мессенджеры | Связан с одной или несколькими компаниями |
| Компания | Юрлицо или клиентский аккаунт | Имеет контакты и сделки |
| Сделка (лид, заказ) | Возможность продажи с суммой и этапом | Контакт, компания, воронка, ответственный |
| Активность | Звонок, сообщение, встреча, задача, заметка | Привязана к любой записи |
| Пользователь и отдел | Сотрудники и структура | Владеют записями, входят в отделы |
| Товарная позиция | Что продано, количество, цена | Принадлежит сделке |
Практические правила:
- Храните телефоны и email в нормализованном виде в отдельной таблице. От этого зависят поиск дублей и распознавание входящих звонков.
- Разделяйте лид и сделку, только если процесс действительно разный. Многим бизнесам хватает одной сущности и ранней стадии «квалификация».
- Используйте мягкое удаление. Данные о продажах часто нужны позже — для споров и аналитики.
Воронки и статусы
Захардкоженные статусы ломаются первыми, когда меняется бизнес. Опишите их данными:
pipelines— воронки продаж (розница, опт, партнеры).stages— упорядоченные этапы внутри воронки, у каждого тип: открыт, успешно или провал.stage_transitions— необязательные правила, какие переходы разрешены.- Обязательные поля по этапам: например, сумма обязательна до этапа «Счет выставлен».
- Причины отказа — справочник, а не свободный текст, иначе их не проанализировать.
Записывайте каждую смену этапа с временем. Конверсия воронки и время на этапе считаются по этому журналу, а не по текущему статусу.
Права доступа
Стройте доступ в три слоя:
- Роли определяют действия: просмотр, создание, редактирование, удаление, экспорт.
- Область видимости определяет записи: свои, своего отдела, всей компании.
- Правила на уровне полей скрывают чувствительные данные, например маржу или закупочную цену.
Проверяйте права на бэкенде в каждом запросе, а не только в интерфейсе. Логируйте экспорт и массовые операции: это самый частый путь утечки данных.
История действий
Лента событий — первое, что открывает менеджер. Сделайте ее надежной:
- Таблица событий только на добавление: кто, что, с какой записью, когда, старое и новое значение.
- Одна лента на запись, объединяющая звонки, сообщения, письма, задачи и изменения полей.
- Сохраняйте и события интеграций: оплата получена, заказ отгружен, сообщение доставлено.
Эта таблица растет быстрее всех, поэтому сразу продумайте индексы по записи и дате и политику архивирования.
Слой интеграций
Телефония, мессенджеры, формы сайта, платежные шлюзы, 1С и маркетплейсы не должны напрямую писать в таблицы ядра.
- Входящие адаптеры превращают внешние данные во внутренние команды вроде «создать лид» или «добавить активность».
- Исходящие события (сделка выиграна, этап изменен) идут через очередь в вебхуки и коннекторы.
- Храните внешние ID в таблице соответствий, чтобы не плодить дубли и иметь возможность пересинхронизации.
- Делайте обработчики идемпотентными и с повторами: внешние системы присылают дубли и бывают недоступны.
Расширяемость
Бизнес попросит поля и сущности, которые сейчас невозможно предсказать. Варианты:
- Пользовательские поля через таблицу типизированных описаний и JSON-колонку для значений. Просто и гибко; индексируйте поля, по которым фильтруете.
- Пользовательские сущности — только при реальной потребности, они усложняют все вокруг.
- Правила автоматизации (триггер, условие, действие), чтобы рутина не требовала разработчиков.
- Публичный API с теми же проверками прав, что и в интерфейсе.
Типичные ошибки
- Копировать весь список функций коробочной CRM вместо своего реального процесса.
- Статусы как enum в коде.
- Проверка прав только на фронтенде.
- Интеграции, пишущие прямо в таблицы ядра.
- Нет плана работы с дублями контактов и компаний.