Pomai Ecosystem - The Real Challenges of Breaking Down a Monolith to Microservices`
Pomai Ecosystem: An Architectural Evolution
Pomai Ecosystem did not begin as a distributed system, nor was it originally designed around AI agents or microservices. Like many side projects that evolved into larger platforms, it started as a multi-module monolith, backed by Firebase.
This repository serves as a technical showcase of how a personal project evolved into an enterprise-ready ecosystem through deliberate architectural decisions.
π The Architectural Journey
1. From Monolith to Macro-services
Initially, the ecosystem thrived as a monolith due to rapid deployment velocity. However, as the product scaled, the "multi-module" structure became a bottleneck. I transitioned to a Macro-services architecture, consolidating highly coupled domains (like Task & Goal, HR & Payroll) to reduce network overhead, while keeping independent domains (Auth, Chat, AI Engine) as autonomous services.
2. The Migration: NoSQL to PostgreSQL
The most grueling challenge was migrating from Firestore to PostgreSQL. To maintain development velocity, I adopted Prisma ORM, which bridged the gap between Firestoreβs rapid-development feel and the robustness of a relational database.
3. Solving the "Port-Hell" with Kong Gateway
As the number of services grew, managing ports became impossible. I transitioned from a custom-coded gateway to Kong Gateway, utilizing its native JWT/OAuth2 plugins, Rate Limiting, and traffic management to secure the ecosystem. To ensure High Availability (HA), I implemented Nginx as a Round-Robin Load Balancer in front of a Kong cluster to prevent a single point of failure.
4. Reliable Distributed Data
To solve the "Dual-write problem" across microservices, I implemented the Transactional Outbox Pattern combined with Apache Kafka. This ensured eventual consistency, where every state change is captured reliably and consumed by downstream services (e.g., RAG Engine, Activity Logs) without breaking system integrity.
π Tech Stack Highlights
| Domain | Core Technology |
|---|---|
| Backend | Node.js, Prisma ORM, Strategy/Factory Patterns |
| Data Layer | PostgreSQL, Milvus, Elasticsearch |
| Messaging | Apache Kafka (Event-Driven) |
| Gateway | Kong Gateway + Nginx (Load Balancing) |
| DevOps | Docker, Portainer, Jenkins, Gitea |
| Monitoring | Prometheus, Grafana, cAdvisor |
| AI Engine | Llama.cpp (CPU-only RAG) |
π§ The "Monitoring" Leap: AI-Powered RCA
When logs hit the "million" mark, human inspection became impossible. I built an autonomous RAG Logging Pipeline that processes streams via Apache Flink, generates embeddings on the CPU using llama.cpp, and stores them in Qdrant. This allows me to perform Semantic Root Cause Analysis by simply asking the system: "Why did the payment service spike in latency?"
π Project Structure
To keep the monolith clean before the microservices split, I implemented strict domain boundaries using the Strategy Pattern.
pomai-ecosystem/
βββ gateway/ # Kong/Nginx HA cluster config
βββ services/
β βββ task_service/ # Core domain (Strategy + Factory)
β βββ ai_engine/ # CPU-only RAG & Vector search
β βββ ...
βββ strategies/ # π Core Design Pattern implementation
β βββ base.js # The abstract contract
β βββ factory.js # The Orchestrator
β βββ enterprise.js # Enterprise implementation
β βββ small.js # Small-business implementation
βββ jenkins/ # CI/CD Pipeline as Code
βββ README.md
π Deep Dive
This repository provides the blueprints for the architecture. For the full story behind the decisionsβthe "Why"βand the lessons learned from refactoring through months of development, please read my full case study blog:
π Read: Pomai Ecosystem: From a Multi-Module Monolith to a Microservices Architecture
βGood architecture is not about choosing the most advanced technology. It is about allowing the architecture to evolve naturally as the complexity of the product evolves.β