ПроАптека
Один из самых интегрированных сайтов, который когда-либо разрабатывала наша студия
ПроАптека
Один из самых интегрированных сайтов, который когда-либо разрабатывала наша студия
В 2016 году Группа компаний «ПРОТЕК» создала маркетинговое объединение «ПроАптека». В него вошли более 5000 независимых аптек. Новому объединению требовался маркетплейс.
Задача
Разработать маркетплейс для федерального профессионального союза независимых аптек.
Маркетплейсы — одно из наиболее сложных направлений как для разработчика, так и для заказчика. Когда один и тот же товар можно купить у разных ритейлеров (при этом цена на товар у каждого ритейлера — своя), без сложных интеграций не обойтись. А если заказчик — еще и крупнейший фармдистрибьютор России со своими:
- складскими комплексами по всей стране,
- уникальными сервисами,
- программами лояльности,
- инновационными решениями для ведения бизнеса,
очевидно, что таких интеграций будет много. «ПроАптека» стала одним из самых интегрированных сайтов, который когда-либо разрабатывала наша студия. SCRUM подход позволил нам за 4 месяца выпустить первоначальную версию сайта с минимальным функционалом по интеграциям и далее дорабатывать его итерационно.
Интеграции
Казалось бы, что сложного в этой детальной странице товара? Лаконичная и предельно удобная для пользователя — можно посмотреть, в каких аптеках товар есть в наличии, сравнить цены, выбрать аптеку, где препарат стоит дешевле всего, или аптеку рядом с домом, и оформить заказ.
Но чтобы отобразилась эта страница, данные импортируются из нескольких интегрированных сервисов. Вот как это выглядит изнутри:
Система учета товаров и остатков — первая интеграция. В этой системе хранится информация о номенклатуре и остатках всех аптек, которые входят в объединение «ПроАптека» (а их, напомним, более 5000). Но номенклатура содержит недостаточно данных для каталога: наименование, производитель, страна, МНН (международное непатентованное наименование). Изображений препаратов и их описаний в ней нет.
Система-источник изображений и описаний — вторая интеграция. Это отдельная система, разработанная ещё до «ПроАптеки». Из неё загружаются изображения товаров и их описания.
Система по обработке заказов — третья интеграция. Заказы, которые оформляются на сайте, отправляются в эту систему, и из неё — в нужную аптеку. В аптеке заказ обрабатывают, меняют ему статус, и новые данные снова поступают в эту систему, а потом и в «ПроАптеку».
Маркетинговая площадка — четвертая интеграция. Группа компаний «ПРОТЕК» разработала программу лояльности «Моё здоровье». Чтобы стать участником программы, нужно зарегистрироваться в аптеке или на сайте, получить карту, копить бонусы и в дальнейшем ими расплачиваться. В личных кабинетах пользователей на сайте отображается количество накопленных ими бонусов.
Внешние маркетплейсы — да, на самом деле, есть еще и пятая интеграция, и шестая, и n-ная. Это другие маркетплейсы, с каждым из которых сайт отдельно интегрируется. То есть, информация о товарах, которые представлены в «ПроАптеке», поступает еще и на другие маркетплейсы. Они размещают эту информацию на своей стороне и, в случае, заказа, передают данные в «ПроАптеку».
Система-источник изображений и описаний — вторая интеграция. Это отдельная система, разработанная ещё до «ПроАптеки». Из неё загружаются изображения товаров и их описания.
Система по обработке заказов — третья интеграция. Заказы, которые оформляются на сайте, отправляются в эту систему, и из неё — в нужную аптеку. В аптеке заказ обрабатывают, меняют ему статус, и новые данные снова поступают в эту систему, а потом и в «ПроАптеку».
Маркетинговая площадка — четвертая интеграция. Группа компаний «ПРОТЕК» разработала программу лояльности «Моё здоровье». Чтобы стать участником программы, нужно зарегистрироваться в аптеке или на сайте, получить карту, копить бонусы и в дальнейшем ими расплачиваться. В личных кабинетах пользователей на сайте отображается количество накопленных ими бонусов.
Внешние маркетплейсы — да, на самом деле, есть еще и пятая интеграция, и шестая, и n-ная. Это другие маркетплейсы, с каждым из которых сайт отдельно интегрируется. То есть, информация о товарах, которые представлены в «ПроАптеке», поступает еще и на другие маркетплейсы. Они размещают эту информацию на своей стороне и, в случае, заказа, передают данные в «ПроАптеку».
Интеграции не только отражают наши уже существующие бизнес-процессы, но и, наоборот, потребовали от нас создания новых структур. Так в процессе работы было создано хранилище данных, которое стало объединять часть уже существующих интеграций. Хранилище по мере необходимости дорабатывается для нужд сайта и партнеров ПроАптеки.
ПроАптека
Заказчик
А вот так выглядит первая версия полной интеграционной схемы, которая проектировалась в начале работы над проектом:
Все эти импорты и интеграции сложны в отладке. Например, если на товаре выводится не та цена, которую ожидает аптека, вариантов, где случился сбой — масса. И тут очень помогает вовлеченность и экспертность заказчика. Мы сделали расширенное логирование, которое помогает локализовать возможные проблемы. Заказчик, помимо того, что отлично разбирается в куче импортов и внешних систем, еще и с готовностью вникает в детали и большую часть вопросов решает самостоятельно.
Екатерина
Исполнительный директор и руководитель проекта
Всегда актуальные данные
Когда сайт агрегирует информацию из более чем 5000 аптек, задача № 1 — постоянно отслеживать корректность и актуальность данных. Для этого мы разработали несколько алгоритмов.
Нормализация цен
На один и тот же товар в разных аптеках разные цены. Все эти цены аптеки загружают в систему учета товаров и остатков, с которой интегрирована «ПроАптека». Как правило, цена указывается за упаковку, потому что упаковками отпускаются препараты. Но среди 5000 аптек часть аптек может прислать цену за 1 ампулу или блистер, а часть — за целую коробку. Мы разработали алгоритм, который вычисляет некорректные цены по правилу трех сигм. Все цены на товар условно раскладываются вот в такой график.
Нормализация цен
На один и тот же товар в разных аптеках разные цены. Все эти цены аптеки загружают в систему учета товаров и остатков, с которой интегрирована «ПроАптека». Как правило, цена указывается за упаковку, потому что упаковками отпускаются препараты. Но среди 5000 аптек часть аптек может прислать цену за 1 ампулу или блистер, а часть — за целую коробку. Мы разработали алгоритм, который вычисляет некорректные цены по правилу трех сигм. Все цены на товар условно раскладываются вот в такой график.
Наибольшая концентрация цен — в середине, это корректные цены. Цены, которые сильно занижены или сильно завышены — это левая и правая части графика. Цены, которые попадают в эти части графика, алгоритм считает ошибочными. Товары с такими ценами удаляются и в аптеки отправляется запрос на корректные цены.
Дублирующиеся товары
Заказчик может в любой момент выгрузить остаток товаров по аптекам и посмотреть, есть ли среди них товары, которые в наличии всего в 1−2 аптеках. Если есть, велика вероятность, что это какой-то случайный дубль. То есть, аптека указала другой артикул, но на самом деле, этот товар уже есть на сайте (он в других аптеках с одним артикулом, а в этой — с другим). Если это не уникальный редкий препарат, а именно дубль, заказчик связывается с аптекой, у товара меняются отдельные коды и таким образом идет борьба с дублирующейся информацией на сайте.
Распределение по разделам
Часть товаров, по которым импортируются разделы, сразу же распределяются в каталоге. Одни идут в «Обезболивающие, спазмолитики, анестетики», другие — в «Противогрибковые средства» и т. д. Но разделы импортируются не для всех товаров. Мы создали алгоритм, который распределяет товары по разделам на основе МНН. Потому что МНН в обязательном порядке указывается для всех товаров. Если алгоритм находит товар, у которого МНН, например, — эноксапарин натрия, и этот товар привязан к разделу «Болезни крови», то другой товар с таким же МНН, у которого нет привязки ни к какому разделу, автоматически отправляется тоже в «Болезни крови».
Дублирующиеся товары
Заказчик может в любой момент выгрузить остаток товаров по аптекам и посмотреть, есть ли среди них товары, которые в наличии всего в 1−2 аптеках. Если есть, велика вероятность, что это какой-то случайный дубль. То есть, аптека указала другой артикул, но на самом деле, этот товар уже есть на сайте (он в других аптеках с одним артикулом, а в этой — с другим). Если это не уникальный редкий препарат, а именно дубль, заказчик связывается с аптекой, у товара меняются отдельные коды и таким образом идет борьба с дублирующейся информацией на сайте.
Распределение по разделам
Часть товаров, по которым импортируются разделы, сразу же распределяются в каталоге. Одни идут в «Обезболивающие, спазмолитики, анестетики», другие — в «Противогрибковые средства» и т. д. Но разделы импортируются не для всех товаров. Мы создали алгоритм, который распределяет товары по разделам на основе МНН. Потому что МНН в обязательном порядке указывается для всех товаров. Если алгоритм находит товар, у которого МНН, например, — эноксапарин натрия, и этот товар привязан к разделу «Болезни крови», то другой товар с таким же МНН, у которого нет привязки ни к какому разделу, автоматически отправляется тоже в «Болезни крови».
Разработка
Так как на сервере сайта постоянно крутятся импорты и идёт значительный поток посетителей, мы выделили отдельный сервер под базу данных, а первый оставили под веб-сервер со всем кодом. Из интересного — несколько решений по оптимизации сайта.
Сервер очередей
Первый год номенклатура и остатки загружались из csv-файлов. В среднем, импорт одного набора файлов занимал около четырех часов, при том, что файлы импортировались в несколько потоков. Чтобы оптимизировать этот процесс, мы отказались от лишнего шага в виде выгрузки данных в файлы из удаленной базы заказчика и стали обращаться к ней напрямую. Для того, чтобы сохранить многопоточность обработки данных, был поднят сервер очередей RabbitMQ. Теперь, вместо пачки файлов, мы получаем набор данных в виде списка записей (в среднем, 2 млн строк). Этот список делится на пакеты по 1000—2000 записей, которые ставятся в очередь на обработку. RabbitMQ ищет свободных обработчиков и распределяет по ним пакеты. Те, в свою очередь, обрабатывают записи и загружают их в базу данных. Так нам удалось сократить импорт с 4 часов до 40 минут.
Сервер очередей
Первый год номенклатура и остатки загружались из csv-файлов. В среднем, импорт одного набора файлов занимал около четырех часов, при том, что файлы импортировались в несколько потоков. Чтобы оптимизировать этот процесс, мы отказались от лишнего шага в виде выгрузки данных в файлы из удаленной базы заказчика и стали обращаться к ней напрямую. Для того, чтобы сохранить многопоточность обработки данных, был поднят сервер очередей RabbitMQ. Теперь, вместо пачки файлов, мы получаем набор данных в виде списка записей (в среднем, 2 млн строк). Этот список делится на пакеты по 1000—2000 записей, которые ставятся в очередь на обработку. RabbitMQ ищет свободных обработчиков и распределяет по ним пакеты. Те, в свою очередь, обрабатывают записи и загружают их в базу данных. Так нам удалось сократить импорт с 4 часов до 40 минут.
Поиск
Битриксовый поиск не учитывает возможные опечатки. Когда приходится искать что-то, вроде «Клотримазол-Акрихин» или «Атенолол-ратиофарм», это становится проблемой. Чтобы её решить, подключили внешний обработчик поисковых запросов Sphinx. Теперь, когда пользователь вводит что-то в поисковой строке, Битрикс передает этот запрос Sphinx. Sphinx распознает ошибки и выдает Битриксу корректный результат.
Битриксовый поиск не учитывает возможные опечатки. Когда приходится искать что-то, вроде «Клотримазол-Акрихин» или «Атенолол-ратиофарм», это становится проблемой. Чтобы её решить, подключили внешний обработчик поисковых запросов Sphinx. Теперь, когда пользователь вводит что-то в поисковой строке, Битрикс передает этот запрос Sphinx. Sphinx распознает ошибки и выдает Битриксу корректный результат.
Кастомизация умного фильтра
Битриксовый умный фильтр автоматически отсеивает неактуальные параметры, в зависимости от того, какие значения уже выбраны. Например, если выбрать МНН «Азитромицин», а среди препаратов с таким МНН нет ни одного акционного, то фильтр уберет вообще значение «Скидки и акции». Для этого проделывается огромная работа, на которую уходит немало времени. В итоге, фильтрация может занимать до 30 секунд. Мы провели аудит и переработали фильтр, оставив там только необходимые параметры и убрав «умность», чтобы он работал быстро. Время фильтрации сократилось до 1 секунды.
Битриксовый умный фильтр автоматически отсеивает неактуальные параметры, в зависимости от того, какие значения уже выбраны. Например, если выбрать МНН «Азитромицин», а среди препаратов с таким МНН нет ни одного акционного, то фильтр уберет вообще значение «Скидки и акции». Для этого проделывается огромная работа, на которую уходит немало времени. В итоге, фильтрация может занимать до 30 секунд. Мы провели аудит и переработали фильтр, оставив там только необходимые параметры и убрав «умность», чтобы он работал быстро. Время фильтрации сократилось до 1 секунды.
Сейчас мы работаем с заказчиком по контуру нашей технической поддержки. Для нас формируются списки задач, мы определяем с заказчиком их приоритеты и сроки и дорабатываем спринтами.
Мы уже наблюдаем прирост пользователей на сайт ПроАптека и покупателей в аптеки. Собираем обратную связь. После этого проводим рефлексию проблемных мест и обдумываем решения по их избежанию. Задания для спринтов по проекту, прежде всего, обсуждаются внутри коллектива ПроАптеки, выявляется большинство проблемных мест в задачах, это ускоряет процесс аналитики на стороне Сибирикс. Если остаются вопросы — мы всегда открыты для коммуникации. Ключевым моментом здесь являются опыт и оперативность команды Сибирикс, которая полностью погружается в задачу.
ПроАптека
Заказчик
Итоговый проект