CRM · SFE · Фармацевтика
W-CRM — CRM для медицинских представителей
Полевая CRM, устойчивая к потере связи. Специализированная CRM для медпредставителей и фармкомпаний: клиенты, визиты, задачи, продажи и эффективность сотрудников.

Смотреть кейс
Что живёт внутри системы
- Отрасль
- Фармацевтика
- Статус
- В продакшене
- Ролей в системе
- 6
- Прав доступа
- 263
- Экранов PWA
- 45
- Типов визитов
- 9
Задача
Фармкомпании вели учёт визитов медпредставителей в таблицах: без маршрутов, контроля и прозрачной аналитики по врачам и аптекам.
Решение
Разработали W-CRM: единая база врачей и аптек с историей взаимодействий, планирование маршрутов, визитов и задач, учёт продаж, мобильное приложение для полевой работы с геопривязкой и дашборды эффективности сотрудников для руководителей.
Сценарий визита
Один визит: от подготовки до отчёта
Каждый шаг полевой работы оцифрован: у представителя есть цель, скрипт и история точки, а руководитель получает данные в момент завершения визита.
01
Подготовка
SMART-цели по точке, скрипты по продуктам и история прошлых визитов собраны в одном окне подготовки.


02
На точке
Старт подтверждается координатами: приложение сверяет позицию представителя с радиусом точки, отметить визит вне точки невозможно.

03
Презентация врачу
CLM-библиотека открывается прямо в визите, а система считает время на каждом слайде и строит аналитику эффективности презентаций.


04
Завершение
Аудит выкладки, промо-материалы и ответы анкеты фиксируются при завершении и сразу попадают в отчёты руководителя.

Offline-first
Связь пропала. Работа продолжается
Связь в точках бывает нестабильной, но визит должен продолжаться. Каждое действие записывается в локальную очередь на устройстве и уходит на сервер одним батчем при восстановлении сети. Попробуйте:
Сеть: онлайн
Выключите сеть, сделайте пару действий и включите обратно
Визит · Аптека Неман 70
г. Бишкек, ул. Айбек-Ата
Outbox · локальная очередь
Очередь пуста. Выполните действия слева
Сервер · /api/sync/push
Ждёт батч из очереди
01
Outbox в IndexedDB
Действия визита сохраняются локально через Dexie и переживают даже перезапуск приложения.
02
Честный детект офлайна
Статус сети определяется не по navigator.onLine, а по фактической ошибке запроса и публичному /api/ping: случай «сеть есть, сервер недоступен» также распознаётся как офлайн.
03
Один батч, порядок FIFO
При появлении сети очередь уходит одним запросом POST /api/sync/push и применяется атомарно по каждому действию.
04
Идемпотентный протокол
Каждый запрос несёт X-Idempotency-Key: повторная отправка после обрыва не создаёт дублей и не ломает статусы визита.
Офлайн-режим в реальном интерфейсе


GPS-контроль
Каждый визит подтверждён координатами
Гео-валидация не пускает старт вне радиуса точки, а телематика Wialon сверяет маршруты автомобилей с реальными визитами и находит нарушения по поездкам.
Аптека Неман 70
радиус 100 м
Радиус точки
Попытка стартовать вне радиуса блокируется на уровне API ответом OutOfRadiusException.
Телематика Wialon
Треки корпоративных автомобилей сопоставляются с визитами, анализатор находит нарушения по каждой поездке.
GPS-отчёты
Руководитель выгружает GPS-нарушения за любой период одним отчётом.

Аналитика
Руководитель видит всё поле
Семь разделов аналитики поверх полевых данных: план и покрытие, тренды, LTV точек и контактов, качество визитов, эффективность презентаций и прогноз.
План и покрытие
Выполнение плана, накопительный прогресс и покрытие базы объектов и контактов.

Активность по часам
Тепловая карта недели показывает, когда команда реально находится в поле.

Представители
Сравнение сотрудников: тренды-спарклайны, выполнение и доля GPS-подтверждений.

Профиль сотрудника
Визиты, объекты, контакты и длительность работы конкретного представителя.

13 асинхронных выгрузок
Excel-отчёты собираются в очереди и приходят уведомлением: визиты, табель, GPS, отсутствия, промо-матрица и другие.

Система в цифрах
прав доступа
моделей данных
экранов PWA
хендлеров действий
Excel-выгрузок
типов визитов
Под капотом
Как это устроено внутри
Одно API на все действия
PolymorphicFormRequest и фабрика из 36 хендлеров: PUT /visits/{id} с полем action вместо россыпи кастомных роутов.
Real-time на Bun.js
Отдельный WebSocket-сервер на Bun.js рядом с PHP-монолитом мгновенно раздаёт уведомления команде.
Поиск на Meilisearch
Полнотекстовый поиск по врачам, аптекам и продуктам через Laravel Scout с кэширующими сервисами.
Ядро как пакет
Домен вынесен в Composer-библиотеку wires-core: модули Finance, Warehouse и HR уже заведены в системе.
Результат
Руководство получило прозрачную картину полевой работы, а количество результативных визитов выросло.
Следующий проект
Trade Assistant — интеллектуальный анализ рынка