Most backends move rows around. REMA moves rows that map to physical equipment — meters, sensors, controllers, wiring, gateways — across more than 500 enterprise sites. That one difference changes everything about how you design it.
When the data you store is the source of truth for how a device behaves in the real world, a careless write isn't a bug ticket. It's a mis-configured controller on a live site.
The shape of the problem
The platform manages 25,000+ assets. Each has configuration that other configuration depends on. A gateway knows about its controllers; a controller knows about its sensors; a site knows about all of it. Change one value and you can quietly invalidate three others.
So I built the backend around three non-negotiables:
- Validation before persistence. Every configuration change runs through a validation layer that understands the relationships between assets — not just "is this field a valid integer," but "does this change conflict with something already deployed?"
- Conflict prevention, not conflict detection. It's not enough to notice a bad state after the fact. The system refuses writes that would produce one.
- Audit everything. Every configuration change is logged — who, what, when, before, after. On a platform touching real infrastructure, traceability isn't a feature you add later.
Why microservices, honestly
Not for résumé points. The configuration domain, the device-lifecycle domain, and the administrative domain change at different rates and have different blast radii. Splitting them let me reason about — and deploy — each one without holding the others hostage. The 50+ REST APIs behind REMA sit on top of that separation.
What I'd tell my earlier self
Spend the boring time on the validation layer first. The APIs are easy; the rules that keep production safe are the actual product. Everything downstream — the audit log, the conflict checks, the confidence to ship on a Friday — is built on getting that core right.