DinoLab: adapting an interactive learning platform for a global audience
Uchi.ru offers educational products for children from 6 to 17 years old in various formats: digital services for self-study, online classes with tutors, offline classes. The platform is incredibly popular and is one of the ten most visited EdTech websites in the world (according to SimilarWeb).
Since 2014, the platform has been developing products for international markets. Uchi.ru has launched gamified online courses for children in Brazil, the USA, Canada, China, South Africa, and other countries around the world. In early November 2020, a service for teaching mathematics and programming, DinoLab, was launched in India.
Previously, they had to introduce local changes into international versions of Uchi.ru products. Each launch in a new country required the development of a completely separate copy, which had to be individually and manually edited if something went wrong.
So the client decided to move to a more suitable architecture, where it would be more convenient to manage changes in all versions at once. They approached Evrone for development, as we already had experience with gamified online platform development.
At the beginning of October 2020, we completed the new online platform for interactive education, DinoLab, and at the beginning of 2021, switched to a systematic product development role.
We started working with Uchi.ru in the summer of 2020. For two months, we supported the existing base of international productions, fixed bugs, developed minor features, and strengthened the team. During this period, with Leonid Bashlykov, head of the International Development Department of Uchi.ru, we started discussing extending the e-learning platform and rebuilding the product for the Indian market.
The client wanted to release a scalable, flexible MVP in three months, with no technical debt. But the main question was whether to develop it as a monolith, as two separate applications, or just take an existing system and put it in order. In the end, together with Uchi.ru, we decided to launch a technical experiment — to do everything on the basis of Ruby microservices.
With the global online education market hotter than ever, the deadlines were tight, and there were many nuances, especially technical ones. We held a lot of negotiations with the technical team of Uchi.ru to ensure that the results of work on the international version could be used in the Russian version of the product. At the same time, using the same concept, Uchi.ru was launching a mobile app for high schools and used the developments on microservices for the backend.
Microservices architecture for an E-learning platform
We developed a microservices architecture in Ruby, using specific frameworks, such as Rails and Roda, as well as Karafka (a Ruby framework for working with Kafka). In addition, we developed several backend services, for example, an authentication and authorization service. We also implemented a premium subscription management service, billing service, and trigger mailing service.
Now the platform has a classic microservices architecture, where services communicate with each other through a message broker, in asynchronous mode. We have written about 12 microservices, and everything is covered with autotests.
Adapting an interactive learning platform
We also had to adapt some ready-made Uchi.ru applications, in order to integrate them into the international version. Basically, we did this through the use of iFrames, which we integrated into the main SPA. So we had to learn how to communicate and sync the main application with other pieces in iFrames.
We spent quite a lot of time differentiating the existing code of third-party applications from ones that will be exclusively used in the international version of Dinolab, and we also redesigned the existing components, depending on the mode (Russian version/international version).
As a result of our work adapting the interactive learning platform for the international version, 80% of the courses work inside DinoLab, through the task player in iFrames. The remaining percentage is redirected to third-party applications, with a subsequent return to Dinolab.
Frontend development for EdTech application
Another challenge that we faced was implementing a complex logic of various redirects to the desired part of the application, using special links, regardless of user authorization. For example, the teacher receives a generated link to an assignment that they created, then they need to be able to send that link, in different forms, to the parents and students. In addition, there are a lot of various validations to denote completion and availability of the task.
We created a rather non-standard model, in which the parent is 90% equal to the child (in terms of capabilities) but at the same time, without leaving the application, they can switch between children, viewing their statistics and giving (if it is more convenient for them) tasks to a specific child, without bothering with logins/passwords for each child.
Our former colleague from Uchi.ru introduced an approach in which we split the application into domains, and not, as is usual, into pages/services/storages. As a result, it became much easier to navigate the project code in search of both business logic and components related to the domain of interest (for example, the domain of authorization, dashboard, tasks, etc.).
One of the most interesting tasks was onboarding teachers, where we needed to use progress monitoring tools to calculate the current step of progress, prompt banners and modals as each stage is passed, and determine what should be done next. In connection with this task, it was necessary to allocate a special service for the frontend, which acts as a data storage between all user devices, ensuring that teachers are not asked to go through the onboarding process multiple times.
In the future, we plan to move to micro-frontends and add the ability to place an application on mobile devices through a special API, which should improve device access and make it easier for users to interact with the application.
Payment solutions for edtech
For the international version, we also had to develop payment solutions for edtech payments. Since Uchi.ru already had a service for managing taxes and prices, we decided to use it as a source of truth about the products and the user's shopping cart. So all we had to do was develop a service for the interaction of our microservices system with the payment system.
At first, we used PayU. The <order> object was collected from the user's cart and sent, via Kafka, to the payment service, where the price, information on the user, and details about the products were collected and sent to the payment system, via the API. However, we then had to wait for a successful response and “tell” (through Kafka) all our services that payment #XXX was successful. We also had difficulties integrating the services of trigger mailings (notifications to the user that the payment was successful) and subscription management (included premium access to content for users).
Ultimately, we were not satisfied with the quality of Paymentsos, and we switched to another provider, Cashfree. Due to the flexibility and scalability of the project, it was easy to make the switch, and only one service had to be changed. Now the service is stable, copes with the loads, and supports multiple payment methods.
- React.js - the main frontend framework.
- Redux - the library we used to create the application data store. It allows us to write extremely fast, high-quality code, making everything compact, simple, and maintainable.
- Redux-Toolkit - used to simplify repetitive and verbose code.
- RTK-Query - greatly simplifies communication with backend APIs and storing API data in Redux.
- Typescript - helps to introduce typing into the code, protecting the code from a number of errors, even before compilation.
- Jest + react-testing-library - provides unit testing of both business logic and visual components of the application.
- Fullscreen API - a browser API that offers more convenient problem solving on devices with small screens.
- React-Table - custom table with student progress statistics.
- React-Datepicker - custom date picker.
We also used Sentry, which allows us to catch client application errors in production and provides a useful stack trace for reproduction and fixing, and ClickStream, which uses frontend analytics to determine the success of the work done.
At the start, one of the client's requests was that we help organize the processes and build up the in-house team's capabilities, so the project would not be forever tied to Evrone’s project manager.
We wrote a lot of documentation. We compiled descriptions of basic things related to how we agreed to work, as well as descriptions of processes. We described who is responsible for what, what tools are used, and what procedures are there to make it easier to onboard new team members. We described how to work with Jira and how to complete assessments and code reviews. Now we have a detailed feature knowledge base.
When we first started working on this project, we needed to create a new product that worked according to the same scenarios as the original, but on microservices instead of a monolith. Our approach to building a microservices architecture for an e-learning platform was experimental, but we succeeded, and now many other Uchi.ru products are incorporating microservices, including those developed by our team.
We will continue to help Uchi.ru with DinoLab, adding new content courses for the hundreds of thousands of current active users. Our focus, going forward, will be on optimizing performance, which will ultimately affect user satisfaction. Our future plans also include improving the work of the traffic-generating service and improving the conversation rate of visitors into active users.
We love working on breakthrough products and being a part of a team of superheroes who solve big problems facing the world today. So if you want to develop a distance education platform, or you need help migrating an EdTech platform from monolithic to a microservices architecture, feel free to contact us to see how we can help.