Что стоит за чистотой в вашей квартире, или препарация Qlean
Привет, хабр. Многие слышали про наш сервис, кто-то пользовался, и вот мы созрели до того, чтобы рассказать про свою внутреннюю IT-кухню. Мы начинали в 2014 году с квартиры-офиса на Арбате (с переговоркой в кухне), 300 клиентов и организацией всего “руками”. Вся информация фиксировалась в экселе, а разработкой и не пахло. Со временем количество клиентов увеличивалось, потребовалась автоматизация, и сегодня Qlean — это зрелая компания, в которой отдел разработки насчитывает более 25 человек. Сегодня через наш сервис делается в среднем около 1000 уборок в день силами 3000 подключенных к системе исполнителей. Мы третьи в мире после зарубежных Handy и Helpling по объемам уборок, и работаем в Москве, Санкт-Петербурге и Екатеринбурге. В этом посте мы проведем экскурсию по системам нашего сервиса и проанонсируем дальнейшие темы блога.
Технологии и как мы их реализовываем
Мы не зацикливаемся на каком-то языке программирования, но исторически сложилось так, что сервис был построен на Ruby on Rails с coffeescript и прочими чудесами. Сейчас от всего этого осталось только api, а от рельс — ActiveRecord и набор стандартных гемов. Мы не сильно упарываемся в модные нынче TrailBlazer и прочее, так как стараемся писать простой и понятный код, который просто поддерживать. Помимо основного приложения у нас есть микросервисы на чистом Ruby, например, для CRM, и системы найма исполнителей, несколько сервисов на Go и парочка на Clojure. Сервисы стараемся делить по принципам DDD, то есть каждый сервис отвечает за какой-либо бизнес-процесс: найм, оплату заказа, назначение исполнителя и т.п. Язык выбираем исходя из конкретной задачи и требований. Весь фронтенд у нас на React+Redux, а мобильные приложения недавно полностью переписали на React.Native, что позволяет писать меньше кода и даёт возможность реализовывать один и тот же функционал на разных платформах (и сайт, и мобильные приложения) силами одних и тех же разработчиков. О профите и трудностях перевода нативных приложений на React.Native мы расскажем дополнительно.
Всего у нас около 30 различных сервисов, которые живут на более чем 70 виртуальных машинах, поэтому выкладка кода не самая тривиальная: мы используем Ansible, Docker и Nomad в качестве оркестратора. При выкладке прогоняется огромное количество тестов (как юнит, так и интеграционных), плюс мы всё проверяем силами QA инженеров, используем canary deploy для сложных задач, поэтому мы не боимся много и часто выкладывать. В неделю у нас в среднем 15 релизов.
А подробнее?
Система состоит из 3-х больших функциональных частей: работа с клиентами, исполнителями и распределением заказов по исполнителям.
Работа с клиентами
Для общения с клиентами у нас есть сайт и мобильное приложение. Тут в принципе всё примерно стандартно: маркетинг, маркетинг и ещё раз маркетинг. За одним большим нюансом: мы повёрнуты на аналитике, поэтому отслеживаем и анализируем все действия, что совершает пользователь. Со всех устройств эвенты поступают на микросервис на Go, который обрабатывает и складывает информацию в базу данных. Так как мы любим всё мерять, у нас сильно развита культура экспериментов и А/B тестов. Любую гипотезу мы сначала проверяем, и на механику одного и того же функционала может быть одновременно до 5 разных реализаций, начиная от каких-то мелких вещей вроде формы ввода данных кредитной карты и заканчивая моделями штрафов и подписок. У каждого эксперимента есть свой дашборд в системе аналитики (мы используем Periscope) и метрики, по которым мы сравниваем. Всегда есть контрольная группа и мы следим за тем, чтобы эксперимент был «чистым», то есть группы пользователей были максимально идентичными. Про аналитику и A/B тесты мы расскажем отдельно.
Работа с клинерами
Любой сервис строится на исполнителях. В нашем случае исполнители приходят в квартиры клиентов, так что их качество и профессионализм очень важны. Прежде чем стать нашим клинером, человеку надо пройти несколько процедур: собеседование, проверку службы безопасности, инструктаж и тест на знание регламентов, выдачу инвентаря. До недавнего времени все эти процедуры происходили полностью в оффлайне, что накладывало свои ограничения на запуск сервиса в других регионах: нужен склад, нужен офис, нужен отдельный колл-центр. Сейчас же мы экспериментируем с полностью автоматизированной системой найма и снабжения исполнителя. И если с наймом проблем не возникло, то со снабжением ещё предстоит долгий путь: мы пока не умеем автоматически контролировать инвентарь клинера. В любом случае основные наши страхи пока не оправдались: система удалённого найма не влияет на качество исполнителей и сервиса. Поэтому мы будем развиваться в этом направлении дальше.
Даже после того как клинер пополняет наши ряды, ему не сразу доступны все заказы. Мы аккуратно ведём его по заказам, помогаем и контролируем качество работы и со временем ему становятся доступны все заказы. Для этого у нас есть матрица видимости заказов, которая по сути формирует индивидуальный список доступных заказов.
Распределение заказов
Вообще, с распределением заказов связан наш основной челлендж. Основные мотивации клинера работать через систему — стабильный заработок и гарантированный поток заказов. Кажется, что всё просто: назначил клинеров на заказ и вперёд, пусть машут шваброй. На деле оказывается, что кто-то готов убираться только по средам после обеда, кто-то не любит кошек и балконы, а кто-то хочет убирать только трёшки в Бутово. Со стороны клиентов тоже есть предпочтения, но другого характера: мы должны минимизировать количество разных клинеров, в идеале за 10 заказов клиенту должно приезжать 2-3 клинера, ведь мало кому понравится, что его постельное бельё трогает 50 незнакомых людей в год. Получается, что система должна учитывать все эти предпочтения и подбирать заказы по наилучшему совпадению. Казалось бы, классическая задача о назначениях но, так как исполнитель может отказаться от назначенного заказа, который ему не понравился, задача становится нетривиальной. А если учесть, что клиент может внезапно вообще перенести или отменить заказ, то мы получаем очень жёсткие требования на быстродействие алгоритма. Мы используем сложные модели, предсказывающие вероятность отмены заказа, вероятность выхода клинера на конкретный заказ и автоматически подбираем клинеру заказ на который она скорее всего согласится по истории её предыдущих заказов. Наша следующая статья как раз прольёт свет на эту тему.
В любом случае, после назначения остаётся какое-то количество неразобранных заказов, они разбираются самими клинерами через приложение. Сейчас мы тестируем модель с аукционом и динамической ценой в зависимости от количества отказов от конкретного заказа. После ручного забора остаётся уже незначительное количество неразобранных заказов. За сутки до заказа наш колл-центр вручную прозванивает наиболее подходящих исполнителей, чтобы клиенты не остались без клинера. Иногда случается и такое, что мы не можем подобрать исполнителя вообще никак (в основном из-за поздних переносов), но мы работаем над минимизацией этого параметра (сейчас до 5 заказов в день остаются без исполнителей).
На самом деле существует ещё множество деталей системы: собственная CRM, работа со складом, но для короткой обзорной статьи уже и так много информации.
Будем рады ответить на ваши вопросы.
Промокод на первую уборку для пользователей хабра: habr
Github