Hey there! I’m Yacine Petitprez, the CTO at Ingedata, and I’m excited to kick off a series of articles where we’ll dive into the technical decisions that shape our work here at Ingedata.
At Ingedata, the development team is working on one of the most ambitious projects we’ve tackled in recent years: migrating our old ERP system, Rhymes, to a shiny new platform we’re calling Pulse. Rhymes has served us well over the past eight years, handling everything from HR and recruitment to the daily grind of project management. But as the company has evolved, so have our needs, and Rhymes just isn’t cutting it anymore.
Rhymes was built during a time when our company’s operations were simpler. But eight years is a long time in tech, and what worked back then now feels more like a series of workarounds than a robust system. We need an ERP that not only keeps track of time and metrics for our clients but also adapts to the variety of projects and data topologies we deal with today.
The main challenge? Flexibility. We need a system that’s customizable enough to fit any project’s needs without requiring us to build custom modules for every client. And it’s not just about flexibility; it’s about ease of use too. We can’t afford to spend weeks configuring each new project. It needs to be quick and painless, something our team can handle with minimal fuss.
Another big issue with Rhymes is its lack of interoperability. The system was never designed to interact with other tools or services, meaning we’ve had to do a lot of manual work to keep things running smoothly. That’s why with Pulse, we’re going all-in on an API-based approach. This will allow us to seamlessly integrate with third-party tools and make our workflows smoother and more efficient.
Our development team has been riding the Ruby on Rails train for years, and for good reason. When we built Rhymes, Rails was the obvious choice. It’s a framework that lets you move fast, thanks to its opinionated design and the vast ecosystem of gems (libraries) that cover just about every use case you can think of. But as we’ve learned the hard way, Rails also comes with some baggage.
One of the biggest issues we’ve faced is code maintainability. Rails makes it easy to get a project off the ground quickly, but if your team isn’t careful, the codebase can get messy fast. Without strict code reviews and validation processes, you end up with a mountain of tech debt that’s a nightmare to manage.
It’s true that a well-architected Rails application can be built without accumulating technical debt, but it often requires a team of highly skilled developers. The flexibility Rails offers, combined with its implicit behaviors, demands a deep understanding of the framework to avoid potential pitfalls. However, assembling a team with that level of expertise can be challenging and resource-intensive, making it less feasible in our situation.
Another challenge with Rails is how it handles business logic. The framework promotes the concept of “fat models and skinny controllers,” but this often results in models that are essentially just bloated extensions of your database records. Developers frequently end up embedding business logic directly into ORM classes instead of developing and maintaining true business models, which introduces a lot of hidden complexities and unintended side effects.
Take callbacks, for example. They might seem like a convenient way to keep your code DRY, but they can also cause a lot of headaches. Here’s a quick example to illustrate:
This might look harmless at first glance, but it can lead to some serious problems:
These issues, along with a few others, made us realize that while Rails has served us well, it’s time to move on. Our team simply can’t afford to keep fighting these battles, and the truth is, we need something more suited to our current needs.
As we embark on this migration journey, we’ve decided to step away from Rails and build Pulse using our custom framework, Verse. Why Verse? Because we wanted something that gives us more control and flexibility without the pitfalls we’ve encountered with Rails.
We built Verse because, despite our best efforts, we couldn’t find a suitable solution within the Ruby ecosystem that effectively supported an event-driven microservice architecture.
We needed something that would allow us to separate concerns in a way that Rails simply couldn’t handle, particularly in how it deals with modeling layers.
With Verse, we’ve moved to a three-tiered architecture that cleanly separates concerns between services and effects—something we’ll dive deeper into in a future post. We’ve also made Verse open-source, but we’re holding off on any major announcements until it stabilizes and we have solid documentation in place. For now, we’re still in the building phase, and things might break, but once we’re confident, we’ll be ready to share it with the world.
Over the next few weeks, we’ll be diving deeper into the technical choices we’ve made, including:
Stay tuned as we pull back the curtain on our tech stack and share the insights, wins, and lessons learned from our journey in building Pulse!
Proudly awarded as an official contributor to the reforestation project in Madagascar
(Bôndy - 2024)