Response body — /projects/distributed-erp-platform
Multi-Tenant Distributed ERP Platform
A distributed ERP system designed for multi-store environments with per-tenant databases and centralized synchronization.
Response metadata
The problem
"One database for every store meant one bad query could tank everyone's performance — and every store needed to keep working when the network didn't."
The hard part
Building a sync protocol that handles offline stores rejoining without data collisions — solved via event-sourced reconciliation with deterministic conflict resolution and per-tenant boundaries.
Overview
This project involved designing and building a distributed ERP platform intended for multi-store businesses. Each store operated independently with its own database, while selected data was synchronized to a centralized cloud database for reporting, administration, and oversight.
The system was built to function reliably even when individual stores experienced connectivity issues, while still maintaining eventual consistency across the platform.
Problem
Traditional ERP systems often assume constant connectivity and a centralized database. In real-world retail environments, this assumption does not always hold true.
The core challenges were:
- Supporting multiple stores with isolated data ownership
- Enabling centralized visibility without introducing tight coupling
- Handling unreliable network conditions
- Managing role-based access across tenants and a super-admin layer
Constraints
- Each store required data isolation for operational safety
- Central administration needed a unified view of business metrics
- Network reliability could not be guaranteed at all locations
- The system had to scale as new stores were added
- Operational overhead needed to remain manageable
Solution
The platform was designed as a multi-tenant distributed system with the following principles:
- Each store maintained its own PostgreSQL database
- A central cloud database aggregated synchronized data
- Asynchronous communication was used to decouple stores from the central system
- A role-based access control model governed all interactions
RabbitMQ was used as the backbone for data synchronization, allowing stores to publish events that were eventually consumed and persisted in the central database.
Architecture
- Backend: Node.js with TypeScript
- Databases:
- Per-store PostgreSQL databases
- Central PostgreSQL database hosted on AWS RDS
- Messaging: RabbitMQ for asynchronous event-based synchronization
- Cloud: AWS for hosting and infrastructure management
Each store emitted domain events tagged with a storeId. These events were consumed by centralized services responsible for validation, transformation, and persistence.
This architecture ensured:
- Loose coupling between stores and central services
- Fault tolerance during network interruptions
- Horizontal scalability as stores were added
Trade-offs
- Eventual consistency was chosen over strong consistency to improve resilience
- Asynchronous processing increased system complexity
- Additional operational effort was required to monitor message queues
- Debugging distributed workflows required better observability tooling
These trade-offs were acceptable given the reliability and scalability benefits.
Learnings
- Designing for failure early simplifies long-term system stability
- Event-driven systems require strong conventions and monitoring
- Clear tenant boundaries reduce both technical and organizational risk
- Simpler data models outperform overly complex abstractions in distributed systems
This project significantly shaped how I approach system design and distributed architectures.
Future Improvements
- Improved observability for synchronization pipelines
- Schema evolution strategies for backward compatibility
- Automated reconciliation for edge-case inconsistencies