Enterprise Multi-Tenant ERP & Order Management System
Order Management System is a modular, production-deployed enterprise ERP suite engineered to unify complex commerce, inventory, customer relationships, and financial workflows. Built with a scalable Next.js monorepo architecture, the platform features complete multi-tenant database isolation, unified session authentication, and high-precision order fulfillment.
- Next.js
- React
- TypeScript
- Node.js
- MongoDB
- Redux
- Material UI
- PostgreSQL
- Inngest
- Auth.js
- Cron jobs
Private project, demo on request
This is client or employer work, so the source code is confidential and the live app sits behind a login. I can't share screenshots or credentials publicly, but I'm happy to walk you through it on a call: a live demo, the architecture and selected code.
Architecture

Modular monorepo
The platform is a monorepo. Each business area is its own app with its own deployment:
- Sales & Finance: sales orders, customers, customer payments, vendors, vendor bills and payments, reports, and tenant, role and user administration
- CRM: leads, opportunities, sales teams, quotations, and a public quote-acceptance portal with e-signature
- Inventory: warehouses, stock levels, transfers, adjustments, and an approval queue
- Messaging: WhatsApp Business messaging with templates, bulk and scheduled sends, and analytics
Cross-cutting code lives in shared workspace packages: authentication, database access, encryption, email, API client, UI components, theming and a workspace hub. Shared auth actions receive repositories and services through dependency injection. That keeps them from depending on any one app's data layer.
Multi-tenant data isolation
Identity database → users, roles, sessions, devices, tenants, module registry
Sales DB → orders, customers, payments, bills
CRM DB → leads, opportunities, quotations
Inventory DB → stock levels, movement ledger, transfers
Messaging DB → contacts, templates, scheduled messagesEach tenant gets a physically separate database for every module. A shared database layer keeps one pooled MongoDB client per process and opens tenant databases on demand, so adding tenants doesn't add connections. Separate tenant-lifecycle services handle subscription gating per module, trial expiry checked at login, and a full tenant purge across every module database.
Identity and module switching
All modules use the same shared identity database and one Auth configuration. Sessions are backed by a session record in the database, and refresh tokens are encrypted and rotated on a rolling basis.
Switching modules does not require a new login:
- The source module checks that the user is active, the role allows the switch, and the tenant's subscription includes the target module.
- It signs a short-lived token scoped to the target module.
- The target module checks the signature, expiry, token type, and its own module ID. It then creates a local session and opens the shared workspace hub.
Inventory ledger
Every stock change is first written as a signed entry in an append-only movement ledger (receive, issue, adjust, transfer out, transfer in). The same MongoDB transaction updates the stock-level snapshot, including the quantity on hand and the weighted average unit cost. A transfer writes its paired out and in movements atomically. Adjustments above a configurable value threshold go to an approval queue.
Background work
Durable, step-based jobs run on Inngest:
- Scheduled WhatsApp campaigns run at their scheduled time and retry with exponential backoff if a send fails.
- A daily cron checks Meta for template approval status and emails the result.
- Each app also runs health-check and retry functions on Inngest.
PDFs (orders, payments, bills, quotations) are rendered on the server. Attachments, logos and signatures are kept in cloud blob storage.
Key Implementation Highlights
Split the ERP into independently deployable modules built on shared workspace packages
ArchitectureIsolated each tenant in its own database per module, served from a single pooled client
Multi-tenancyBuilt single sign-on across modules with short-lived, module-scoped signed handoff tokens
SecurityEncrypted refresh tokens and rotated them atomically, with retries that don't log users out on transient DB errors
SecurityDetected new-device and IP-change logins and sent geolocated security-alert emails, with per-device session revocation
SecurityDesigned an append-only stock-movement ledger that updates stock levels and weighted average cost in the same transaction
Data integrityBuilt a public quote-acceptance portal signed, expiring links and online customer signatures
CRMIntegrated the Meta WhatsApp Cloud API with per-tenant encrypted credentials and template lifecycle tracking
IntegrationsMoved scheduled messaging, retries and daily template checks onto durable background step functions
BackendGenerated PDFs on the server for orders, payments, bills and quotations, and exported Excel spreadsheets
Documents
Interested in the technical details?
Let's Talk