The Premise
This case study is based on a B2B Marketplace project which provides a web platform for buyers and sellers of a specialized service in the manufacturing sector to interact and proceed with their dealings in an easy manner. It was designed to cater to 3 kinds of stakeholders including customers, suppliers and the application's own team, the last being via an integrated CRM. Our work with the organization was centered around executing the plans and decisions taken by the product's core team regarding new features, code refactoring(cleanup, restructuring for extended maintainability) and bug fixing in production environments.
Challenges we faced
The biggest challenge was posed by the sheer size of the software, in addition to the fact that it needed niche understanding of the sector it was built to serve. Since there was no complete or detailed documentation about the project setup, it took us some time to set it up and wrap our heads around the codebase. Understanding the lay of the land took us a few meetings with the client, where we understood the architecture and the design philosophy for different components. Another problem was, the project was distributed across repositories and so setting it up was a labourious and time-consuming task.
Stack
The poject was a data-heavy, full-stack web application built with the following technologies:
- Frontend: React, Typescript
- Backend: Django
- Data: Sqlite, ERP system
- Devops: Dev Containers, Docker
- Testing : Vitest, Playwright, unittest
- Version Control: Git
Essentia's Team
The services needed by the client was strictly related to web development in nature, there was no business consulting involved. Essentia's team consisted of myself and two SDE1s. A majority of my contributions were mainly to the backend, where I provided consultation on modules' architecture, refactored large segments of existing features while creating new ones too and wrote unit and integration tests. My counterparts worked mainly on the frontend while occasionaly taking care of hot-fixes on the backend. Most of their tasks focused on refactoring exisitng components by breaking them down into reusable ones, writing unit and E2E tests and fixing bugs.
Priority-based deliverables
-
Streamlined setup There was no streamlined process to setup the webapp earlier, end-to-end. We accomplished this by using Dev containers.
-
Implement DRY principle everywhere The immediate need of the project as determined by the core team, was to get rid of code repetitions, that is because, until then it had been vibe-coded by the previous vendor without paying attention to efficiently designing the components, thus leading to their sizes getting bloated out of proportions. This also included breaking down components into reusable smaller ones, which was easier said then done, because of their complex nature. Components were neither completely decoupled nor did they have fixed relationships with each other. Therefore, we always had to make a tradeoff between thw following:
- having multiple components with similar structure(potentially bloated size)
- a large number of small components that could be reused across parent components but added extra complexity to the overall structure
-
New features, fixes & hot-fxes While cleaning up code was the more immediate need, new features were also being designed by the core team and they were added into the issue log according to their importance towards consumers.
-
Write tests We followed different approaches while writing tests for the backend and frontend. The backend had tests to begin with, so we wrote tests with every PR and this was also reflected in the time estimation for the task. But on the frontend, fixing features and refactoring code had a greater priority, so testing was created into individual tasks later on. There were different kind of components, some could be covered by unit tests alone, while others were too large and complex to be covered by unit tests, so we needed to write E2E tests for them.
Development Process
It was divided into the following steps:
- Decision: Developmental decisions were taken by the core team, where I was ocassionally asked to pitch in.
- Delegation: After deciding on the tasks and documenting them, they were delegated to us by creating issues in a project management software.
- Time Estimation: We would go through the task description and quote the time we would take to complete the task.
- Delivery: The final step was to implement changes, create a Pull Request(PR) on Github, leave a description and justification for the changes and a link to the PR under the issue.