- Service type:
- Agile development
- Product type:
- BPMS of the client company
Many companies in markets with slow growth prefer standard ways to compete, such as cutting operating costs, hiring more productive employees, and optimizing taxes. Our client was proficient in these ways and brave enough to believe in his market vision and invest in more innovative ways to grow his company.
In this case, we developed a BPMS for a marketing agency that systematized and optimized most of the company's processes. Our client's task is to provide his clients with quality leads on the CPA model. That means that his customers pay for the targeted actions by the user, for example, registration. To do that, he needs to buy traffic on sites like Google Ads, Microsoft Ads, or Facebook Ads. Interacting with such platforms, setting up analytics, and launching and monitoring mobile apps are just the tip of the iceberg of such a company's daily routine.
Where traffic is purchased
Needed for filtering poor quality traffic and analytics
They are targeted, which is the goal of the advertiser.
Management of all company processes
Required for operational control and financial reporting
The main goal of the product was to remove chores from the employees' work agenda to allow them to focus specifically on marketing tasks. Managing landing pages, building reports, managing payment accounts are important tasks for the business. The BPMS had to solve these tasks. Our product solved most of the routine tasks and became strategic for the client's company. Thus our collaboration has become a true partnership.
Before starting long-term cooperation, we offer a pilot iteration to our clients, during which we can get to know each other in practice and better prepare ourselves for the systematic work process. As part of the pilot, we study the domain of the future product, prepare a proposal for a cooperation agreement, and strengthen the team with the necessary expertise. In this process, we must show the actual level of our delivery without overstating or understating the client's expectations before signing the agreement. Therefore, it is essential to do something that will bring final value to the client in the pilot iteration and show each other's performance capabilities.
In this case, the pilot project was a module for collecting and displaying marketing statistics for an advertising platform. The client's problem was that his customers had several advertising accounts (AA) on this platform. Therefore, to obtain a monthly report on the advertising performance, it was necessary to enter each advertising room separately, upload statistics, and combine them into one table. Another example is the reaction to ineffective launches of new creatives or audiences should be fast. It is necessary to immediately change or stop advertising campaigns if they do not show the desired results. We wrote the requirements for this module on a business level, coordinated them with the client, set a budget, and started working.
At the same time, we continued negotiations about system cooperation, getting to know the client's market, and studying the specifics of his company's tasks. Our client was focused on long-term cooperation. Therefore, a lot of factors had to be taken into account to plan the product architecture, such as:
If we chose an old tech stack, we would increase the risk that it would be too difficult to hire new developers in the future.
The wrong choice of architectural principles of the system can lead to the technical degradation of the product too quickly.
If you do not accurately define the strategic priorities, hypothesis testing will be more time-consuming, and you may have to release the raw product.
We completed the pilot iteration at the planned deadline. The next most important thing for us was a quality feedback exchange. Our client evaluated the results concretely and wholly based on facts. The most valuable evaluations from the client were:
|During the process, it turned out that advertising accounts can have different time zones and currencies. While in the test sample they was the same.||Data for each advertising account are displayed in its currency and time zone. The calculation of aggregate data is not implemented and is postponed to the next iteration.||We have clarified the requirements based on new objective circumstances, and have already implemented the functionality according to the new requirements. In particular, the main time zone has appeared in the system settings, and a currency switch has appeared on the statistics page. To do this, we additionally implemented integration with 3rd-party to obtain exchange rates to know the amount of expenses on the day they occurred.|
|Statistics should be easy to view at all levels from advertising account to advertisement. The client did not have an accurate vision of UX of entity navigation. It was decided that the entities "Advertisement account", "Campaign", "Ad Group" and "Advertisement" will be displayed as tabs. We also decided to implement the mechanics of "deepening into the entity", for example, when you click on the advertisement account, the user goes to the list of campaigns of the selected account.||The mechanics of "deepening" and clicks on tabs work. When you switch between tabs, the filters are reset.||Made a single back-end interface for all tabs, which reduced the time to add data in the future. We decided to use the tag mechanism in filtering, as well as combine the mechanics of filtering and deepening. Filtering is not reset after switching to another tab. Each filter is displayed as a badge, if you click on it — the filter is reset.|
|The number of columns was very large, it was impossible to avoid horizontal scrolling. At the same time, different users could have different tasks. For an efficient workflow, users may need different sets and sequences of columns.||We found the most suitable set of columns for all users and displayed it. An ordered set of columns is configured at the code level.||We have configured an ordered set of columns for each user at the database level. We also prepared two sets (for managers and employees), and appointed the appropriate sets to all users. This decision turned out to be correct, and we managed to manage the set of columns in the next iteration.|
Based on the test iteration results, we were convinced that our working approaches were close and the product goals were crystal clear. That is why we offered the client our version of the system cooperation agreement, the product architecture plan, and the formulation of strategic goals. The latter sounded as follows:
Below we give two subsystems as an example. We have developed dozens of similar modules and built a fairly large product.
One of the modules was integration with the Binom marketing tracker. It is a 3rd-party software that tracks conversions and other statistics on the landing pages and receives data about approved leads. The goal of the integration was to synchronize costs and revenues. Calibra must continuously receive revenue data contained in Binom and send cost data to Binom.
We decided with the client that it was necessary to synchronize the data with no more than a 1-minute delay. At first glance, it was impossible to achieve such a frequency on the Binom side. During the first test, we found out that we often get an error with status code 500 from Binom when sending data in two concurrent threads. We needed to send data to the API in at least five concurrent threads to get the desired speed and stability. To have a minimum reserve for the future, we needed 10-20 threads.
Binom is an on-premises software. So, after describing the problem in detail to the support team, we decided to study the product ourselves. As we found, the Binom interacts with a MySQL database in a way that does not allow simultaneous processing of multiple queries. They created database locks, which, in case of a large number of simultaneous calls, caused a database crash. Support confirmed our concerns. The product architecture did not allow multiple concurrent API clients. It seems we were the first customer of their product to have experienced this problem.
First, we decided to ensure we could not solve our task with a lower request rate. We found that we can reduce it by recording the datetime of the last synchronization for each statistical value. While the previous version of the solution always sent each value once a minute, now we will send it only if it has changed since the last update.
This optimization was insufficient, and we still could not achieve the desired synchronization speed. Since Binom cannot scale horizontally, the alternative was to scale vertically. So we took a powerful server optimized for MySQL performance, tested our solution, and ensured we passed our constraints.
That's how we called presets of automatic actions with ads when a specific situation occurs. The simplest case is if we get ROI less than 0% for a certain budget spend, then we have to turn off that ad. Execution of such scenarios is a significant part of the time of our client's company employees.
At the time of developing this functionality, we had already implemented enabling and disabling ads through Calibra's interfaces on most advertising platforms. What was left to do was to design and implement the action presets themselves and let Calibra users enable those presets for the actual ad campaigns. The main functions of this block looked like this:
The error cost in this module is exceptionally high. So it was unacceptable to make a mistake at the design level. Therefore, we spent a significant part of the time collecting and formalizing the requirements and prototyping the UI. The client's employees would use these interfaces daily, so they had to be thoroughly developed.
The module started to optimize costs in situations where employees could not do so. For example, advertising was losing its cost-effectiveness half an hour after the end of the workday. Previously, it would continue to spend the budget until the new workday began. Now we stop it instantly, optimizing the advertising budget. This solution also significantly reduced the time the client's employees spent on daily chores.
Long-term collaborations where we clearly understand the value we bring to the client are the most important for us. Building such products is only possible in an atmosphere of ultimate trust and mutual understanding. That is why we try to create such an atmosphere from the first days of cooperation. Today, our client sees himself not only as a marketing company but also as a technology company, and Calibra is now a strategically important technology for his company. We sincerely appreciate this collaboration and are confident in the product's continued success.