What is behind the cleanliness in your apartment, or Qlean preparation
Hi, Habr. Many have heard about our service, someone used it, and now we are ripe before telling about our internal IT-kitchen. We started in 2014 with an office-apartment on Arbat (with a meeting room in the kitchen), 300 clients and organizing everything with hands. All information was recorded in Excel, and the development did not smell. Over time, the number of customers increased, automation was required, and today Qlean is a mature company with more than 25 employees in the development department. Today, through our service, an average of about 1000 cleanings a day is done by 3000 connected performers. We are the third in the world after foreign Handy and Helpling in terms of cleaning volumes, and we work in Moscow, St. Petersburg and Yekaterinburg. In this post, we will conduct a tour of our service systems and announce further blog topics.
Technologies and how we implement them
We don’t get hung up on any programming language, but historically it turned out that the service was built on Ruby on Rails with coffeescript and other wonders. Now all that is left is api, and the rail - ActiveRecord and a set of standard gems. We don’t really run into TrailBlazer, which is now fashionable, and so on, as we try to write simple and understandable code that is easy to maintain. In addition to the main application, we have pure Ruby microservices, for example, for CRM, and a hiring system, several services on Go and a couple on Clojure. We try to share services according to DDD principles, that is, each service is responsible for a business process: hiring, paying for an order, appointing an artist, etc. We select the language based on a specific task and requirements. We have the whole frontend on React + Redux, and mobile applications have recently been completely rewritten to React.Native, which allows you to write less code and makes it possible to implement the same functionality on different platforms (both the site and mobile applications) by the same developers. We will talk about the profit and difficulties of translating native applications to React.Native.
In total, we have about 30 different services that live on more than 70 virtual machines, so the code layout is not the most trivial: we use Ansible, Docker and Nomad as an orchestra. When laying out, a huge number of tests (both unit and integration) are run, plus we check everything with the help of QA engineers, we use canary deploy for complex tasks, so we are not afraid to spread a lot and often. We have an average of 15 releases per week.
And in more detail?
The system consists of 3 large functional parts: work with clients, contractors and distribution of orders by contractors.
To communicate with customers, we have a website and a mobile application. Here, in principle, everything is approximately standard: marketing, marketing, and again marketing. For one big nuance: we are turned to analytics, so we track and analyze all the actions that the user performs. From all devices, events are sent to the Go microservice, which processes and stores information in a database. Since we love to measure everything, we have a very developed culture of experiments and A / B tests. We first test any hypothesis, and up to 5 different implementations can simultaneously be on the mechanics of the same functional, starting from some small things like a form for entering credit card data and ending with models of fines and subscriptions. Each experiment has its own dashboard in the analytics system (we use Periscope) and metrics by which we compare. There is always a control group and we make sure that the experiment is “clean”, that is, user groups are as identical as possible. We will talk about analytics and A / B tests separately.
Work with Cliners
Any service is built on performers. In our case, the performers come to the apartments of customers, so their quality and professionalism are very important. Before becoming our client, a person needs to go through several procedures: interview, security check, instruction and test for knowledge of regulations, issuance of inventory. Until recently, all these procedures took place completely offline, which imposed restrictions on the launch of the service in other regions: you need a warehouse, you need an office, you need a separate call center. Now we are experimenting with a fully automated recruitment and supply system. And if there were no problems with hiring, then there is still a long way to go with supply: we still do not know how to automatically control the inventory of the client. In any case, our main fears have not yet been realized: remote hiring system does not affect the quality of performers and service. Therefore, we will develop in this direction further.
Even after the cliner replenishes our ranks, all orders are not immediately available to it. We carefully carry it on orders, help and control the quality of work, and over time, all orders become available to him. To do this, we have an order visibility matrix, which essentially forms an individual list of available orders.
Distribution of orders
In general, our main challenge is connected with the distribution of orders. The main motivation of the client to work through the system is stable earnings and a guaranteed flow of orders. It seems that everything is simple: appointed cleaners to order and forward, let them wave a mop. In fact, it turns out that someone is ready to clean only on Wednesdays after lunch, someone does not like cats and balconies, and someone wants to clean only three-ruble bills in Butovo. Clients also have preferences, but of a different nature: we must minimize the number of different cleaners, ideally 2-3 clients should come for 10 orders, because few people like that his bedding touches 50 strangers a year. It turns out that the system must take into account all these preferences and select orders according to the best match. It would seem a classic assignment problembut, since the contractor may refuse the assigned order, which he did not like, the task becomes non-trivial. And if we consider that the client can suddenly transfer or cancel the order altogether, then we get very strict requirements on the speed of the algorithm. We use complex models that predict the probability of an order being canceled, the likelihood of the client getting to a specific order, and we automatically select the order for the client to which she will most likely agree on the history of her previous orders. Our next article will shed light on this topic.
In any case, after the appointment, a certain number of unassembled orders remains, they are disassembled by the cliners themselves through the application. Now we are testing a model with an auction and a dynamic price, depending on the number of refusals from a specific order. After manual collection, there is already a small number of unassembled orders. A day before the order, our call center manually calls the most suitable performers so that clients do not remain without a clinician. Sometimes it happens that we can’t find an artist at all (mainly due to late transfers), but we are working to minimize this parameter (now up to 5 orders per day are left without executors).
In fact, there are many more details of the system: own CRM, work with the warehouse, but for a short review article there is already so much information.
We will be happy to answer your questions.
The first cleaning promo code for Habr users: habr