Production-grade ERP-WMS integration system showcasing clean architecture, event sourcing, and queue-based processing.
Fulfil (ERP) β Ecomflow β Mabang (WMS)
β β β
Orders Processing Fulfillment
Backend:
- Hono (Cloudflare Worker-compatible API)
- TypeScript (strict mode, zero comments)
- Drizzle ORM + PostgreSQL
- BullMQ + Redis (production-grade queues)
- Pino (structured logging)
- Prometheus metrics
- Zod validation
Frontend:
- React 18 + Vite
- TanStack Query (real-time updates)
- Tailwind CSS
- React Router
Architecture:
- Clean Architecture (entities, use cases, repositories, services)
- Event Sourcing (complete audit trail)
- SOLID principles
- Dependency Injection via interfaces
ecomflow-test/
βββ backend/
β βββ src/
β β βββ entities/ # Domain models
β β βββ repository/ # Data access (Drizzle)
β β βββ services/ # External integrations
β β βββ usecases/ # Business logic
β β βββ handlers/ # HTTP handlers
β β βββ router/ # Route registration
β β βββ queue/ # BullMQ processors
β β βββ middleware/ # Logging, metrics
β β βββ database/ # Drizzle schema + migrations
β β βββ types/ # TypeScript type definitions
β β βββ validation/ # Zod schemas
β βββ package.json
β βββ tsconfig.json
βββ frontend/
β βββ src/
β β βββ api/ # API client
β β βββ pages/ # React pages
β β βββ App.tsx
β β βββ main.tsx
β βββ package.json
β βββ vite.config.ts
β βββ tailwind.config.js
βββ docker-compose.yml # PostgreSQL + Redis
βββ dev-setup.sh # Automated setup script
- Node.js 20+
- pnpm 8+
- Docker Desktop (running)
Step 1: Install dependencies
pnpm installStep 2: Start backend (databases + API)
pnpm dev:backendThis automatically:
- β Checks Docker is running
- β Starts PostgreSQL and Redis containers
- β Waits for services to be ready
- β Runs database migrations
- β Starts the backend API
Step 3: Start frontend (in a new terminal)
pnpm dev:frontendAccess the app:
- Dashboard: http://localhost:5173
- API: http://localhost:3000
- API Docs: http://localhost:3000/doc
- API Health: http://localhost:3000/health
- Prometheus Metrics: http://localhost:3000/metrics
- Order Flow: Fulfil β Ecomflow β Mabang with full state tracking
- Idempotency: Duplicate order detection via ERP Order ID
- Retry Strategy: BullMQ with exponential backoff (3 attempts: 1s, 2s, 4s)
- Reconciliation: Automated sync checks every 5 minutes
- Monitoring: Prometheus metrics + structured logs
- Dashboard: Real-time order status, reconciliation view
- Event Sourcing: Complete audit trail of all state transitions
- Clean Architecture: Entities, use cases, repositories, dependency injection
- Queue-Based Processing: BullMQ for reliable job execution
- Dead Letter Queue: Failed orders with manual retry capability
- API Documentation: Swagger UI at
/docwith OpenAPI 3.0 spec - Metrics & Health: Prometheus counters + deep health checks
- Type Safety: End-to-end TypeScript with Zod validation
- Dynamic Order Generation: Create test orders with configurable failure scenarios
- Visual Timeline: Interactive event timeline with circles and connecting lines
- Manual Retry: One-click retry for failed orders with full audit trail
- Database Reset: Quick reset button for clean demo runs
- Responsive Tables: Optimized for presentation mode
- Auto-Refresh: Real-time updates every 2-5 seconds
POST /api/v1/fulfil/orders- Receive orders from Fulfil ERP
GET /api/v1/orders- List all orders with sync statusGET /api/v1/orders/:id- Order details + event timeline
GET /api/v1/failed-orders- List permanently failed ordersGET /api/v1/failed-orders/stats- Get failed orders countPOST /api/v1/failed-orders/:jobId/retry- Manually retry failed order
GET /api/v1/reconciliation- Latest reconciliation summaryGET /api/v1/reconciliation/history- Historical reconciliation reportsPOST /api/v1/reconciliation/run- Trigger manual reconciliation
POST /api/v1/seed/generate-orders- Generate test orders with failure scenariosPOST /api/v1/system/reset- Clear all data (database + queues)
GET /health- System health check (DB, Redis, queues)GET /metrics- Prometheus metrics (orders received/synced/failed)GET /doc- Interactive API documentation (Swagger UI)
-
fulfil-sync-queue: Process incoming Fulfil orders
- Validates order payload
- Creates internal order entity
- Stores events
- Queues for WMS sync
-
mabang-push-queue: Sync orders to Mabang WMS
- Transforms to Mabang format
- Handles API failures
- Implements retry logic
- Updates sync state
-
reconciliation-queue: Automated reconciliation
- Runs every 5 minutes
- Compares ERP vs WMS state
- Detects discrepancies
- Stores results
All state changes are stored as immutable events:
ORDER_RECEIVED_FROM_ERPORDER_VALIDATEDORDER_QUEUED_FOR_WMSORDER_SENT_TO_WMSORDER_ACKNOWLEDGED_BY_WMSORDER_FAILED_WMS_PUSHORDER_MANUAL_RETRYSYNC_PERMANENTLY_FAILEDSYNC_RETRY_SUCCESSWMS_STATUS_UPDATEDRECONCILIATION_DISCREPANCY_DETECTED
Benefits:
- Complete audit trail
- Time-travel debugging
- Easy reconciliation
- Replay capabilities
Use the dashboard home page or curl:
curl -X POST http://localhost:3000/api/v1/fulfil/orders \
-H "Content-Type: application/json" \
-d '{
"erpOrderId": "ORD-123",
"organizationId": "org-456",
"channelId": "shopify-store",
"deliveryAddress": {
"name": "John Doe",
"address1": "123 Main St",
"city": "Madrid",
"zip": "28001",
"countryCode": "ES",
"subdivisionCode": "M",
"phone": "+34612345678"
},
"lines": [{
"id": 1,
"product": {
"id": 100,
"name": "Test Product",
"code": "SKU-001",
"hsCode": "4202920000"
},
"quantity": 2,
"currency": "EUR",
"unitCustomsValue": 25.50
}]
}'- Watch orders page for sync state updates
- Check order detail for event timeline
- View metrics endpoint for counters
Click "Run Reconciliation" in the dashboard or:
curl -X POST http://localhost:3000/api/v1/reconciliation/runMetrics to Track:
ecomflow_orders_received_total- Order ingestion rateecomflow_orders_failed_total- Failure rate by reasonecomflow_sync_duration_seconds- Sync performanceecomflow_reconciliation_discrepancies- Sync health
Alert Thresholds:
- Failure rate > 5%
- Sync duration > 10s
- Discrepancies > 10
- Queue depth > 1000
- Horizontal Scaling: Stateless API + worker pods
- Queue Partitioning: Separate queues by organization
- Database: Read replicas for queries
- Caching: Redis for order status lookups
- Rate Limiting: Per-organization limits
- API key authentication for ERP webhooks
- Webhook signature verification
- Rate limiting per organization
- Input sanitization (already using Zod)
- Secrets management (environment variables)
- OpenTelemetry tracing
- Distributed tracing across services
- Error tracking (Sentry)
- Log aggregation (DataDog/ELK)
- Custom dashboards (Grafana)
pnpm dev:backend # Start backend (Docker + API)
pnpm dev:frontend # Start frontend only
pnpm build # Build all apps
pnpm typecheck # Type check all packages
pnpm db:generate # Generate Drizzle migrations
pnpm db:migrate # Run migrations
pnpm db:studio # Open Drizzle Studio
pnpm docker:up # Start PostgreSQL + Redis
pnpm docker:down # Stop containersMIT