Last update 05/04/2024
In this article, we share how we're running our online stores for all countries in a micro-service based architecture.

- Offline & Marketplaces - Serving as a catalyst for the growth of our sales channels beyond our direct-to-consumer (D2C) business. This domain extends to partnerships in wholesale, various marketplaces, and the establishment of new Emma physical stores.
- Operations Core - A dynamic and integral hub that seamlessly links critical aspects of our operations, encompassing transportation, stock, and product catalog management, as well as order management and fulfilment.
- Finance Technology - The foundational support powering scalable, flexible, resilient, and reliable processes within our finance and accounting realm.
- Online Store - A digital platform where customers can explore our product catalog and conveniently purchase their preferred items online.

Figure 1. Serve static page sequence diagram
Even though we serve static sites to our end user, there is a part of the site that is still dynamic. Adding items to cart and placing an order is done through API Calls sent from the frontend to our API Gateway which validates the request and forwards it to CRM (Content Relationship Management) Service and Checkout Service. Checkout Service then forwards the request to Promotion Service and Payment Service to validate any discounts that might have been part of the order and to create a payment based on the payment method that the customer has chosen.

Figure 2. Place an order sequence diagram
Static Site Generation
As previously noted, we provide our customers with a static site. This entails that all the files presented on the browser are created on the server, then transferred to storage from where they are served, rather than being generated at runtime.
We employ two methods for file generation: at specific intervals through a cron job and whenever there is a change in content or product information using an event-based architecture. Both approaches are overseen by the generator service, employing an event consumer for messages and a Node.js cron job. Both the consumer and cron job internally invoke the same component to initiate the generation process. Now, let us explore the architecture of each method based on the diagram below.

Figure 3. Cron Job with worker and scheduler
As depicted in the diagram above, both the cron job and event-based mechanisms are interconnected. During scheduled intervals, the scheduler publishes messages for each country in the queue, assigning specific priority levels. Subsequently, the worker consumes these messages and invokes the generator component to initiate the generation process. In the comprehensive architecture diagram below, for event-based changes in content and product information, the respective services also publish messages in the queue with a higher priority level, effectively overriding the scheduled event.
The generator component programmatically triggers our Nuxt application to generate the site. The Nuxt application is seamlessly linked to all the essential services, ensuring the retrieval of necessary data for the site generation process.
It is worth mentioning that for all the components in the Site Generation block we use a monorepo architecture and they are all deployed together as one service.

Figure 4. Full architecture diagram
Conclusion
We trust that this article provides insight into the intricacies of our daily operations at Emma, shedding light on how we strategize and implement substantial initiatives like the one discussed, ensuring alignment with the latest technological advancements and meeting business demands.
As we are aware, nothing remains static, particularly in the swiftly evolving tech landscape. This is why the architecture described here will inevitably evolve – it must adapt, or it risks stagnation without proper maintenance. Consequently, we anticipate further developments to accommodate technological shifts and meet evolving business needs in the future. Stay tuned for more updates.









