A production-grade, multi-vendor B2B e-commerce platform for the elevator spare parts and lift-systems industry. Connects installers, customers, traders/suppliers, and platform admins through a sophisticated marketplace with smart order routing, project (RFQ) workflows, tamper-proof financial ledgers, and a built-in CMS.
Live: montralifts.com · API: api.montralifts.com · Admin: admin.montralifts.com · Trader: trader.montralifts.com
1. Project at a Glance
| Item | Detail |
|---|---|
| Domain | B2B Marketplace — Elevator Spare Parts & Lift Systems |
| Market | Egypt (EGP, Arabic + English, RTL/LTR) |
| Architecture | Monorepo: 1 backend API + 4 independent Next.js apps + MySQL |
| Backend | NestJS 10, Prisma 5, MySQL 8, JWT, Swagger |
| Frontend | Next.js 16 (App Router), React 19, TypeScript, TailwindCSS 4, Zustand, React Hook Form + Zod, shadcn/ui, Framer Motion, Recharts |
| Infra | Docker Compose, Nginx reverse proxy, Let's Encrypt SSL, GitHub Actions CI/CD, VPS |
| 3rd-Party | Paymob (payments, HMAC-validated webhooks), Cloudinary (media), WhatsApp deep-links |
| Scale | 50 Prisma models · 30+ backend modules · 100+ REST endpoints · 4 separate frontends |
| Status | Production, ~98% complete, actively maintained |
2. System Architecture
┌─────────────────────────────────────────────────────────────────┐
│ FRONTEND APPLICATIONS │
├──────────────┬───────────────┬────────────────┬─────────────────┤
│ Landing │ Client │ Trader │ Admin │
│ :3000 │ :3001 │ :3002 │ :3003 │
│ Public site, │ Marketplace, │ Supplier │ Operations, │
│ CMS-driven │ projects/RFQ, │ dashboard, │ CMS, finance, │
│ blog/SEO │ cart, returns │ fulfillment │ trader payouts │
└──────┬───────┴───────┬───────┴────────┬───────┴─────────┬───────┘
│ │ │ │
└───────────────┴────────┬───────┴─────────────────┘
│ HTTPS / REST + JWT
▼
┌─────────────────────────────────────────────────────────────────┐
│ BACKEND API (NestJS) :4422 │
│ Auth · Items · SupplierListings · Orders · SubOrders · │
│ Projects/RFQ · Pricing Engine · Commissions · Returns · │
│ Payments (Paymob) · DeliveryNotes · CMS · Stock · Excel · │
│ Notifications · Activity Logs · Support · Sections (shipping) │
└────────────────────────────────┬────────────────────────────────┘
│ Prisma ORM
▼
┌─────────────────────────────────────────────────────────────────┐
│ MySQL 8.0 — 50 Models │
└─────────────────────────────────────────────────────────────────┘
3. The Four Frontends
3.1 Landing Site (frontend-landing, port 3000)
Marketing & SEO surface for the brand.
- Bilingual (AR/EN) with full RTL/LTR support
- CMS-driven content: services, lift types, portfolio, blog, clients, hero
- Animated hero & sections (Framer Motion)
- Blog with dynamic
[slug]routes - Conversion CTAs to the marketplace and trader signup
Routes: /, /landing, /blog, /blog/[slug]
3.2 Client Marketplace (frontend-client, port 3001)
Where customers and installers shop and run projects.
- Catalog browsing with categories, search, filters, sliders (price/brand)
- Item detail pages with multi-supplier pricing, specs, gallery
- Wishlist / favorites
- Cart + checkout with shipping address management
- Paymob payment flow (card/wallet) and cash-on-delivery
- Deposit logic for large orders (15–20% gating)
- Order tracking, sub-order timeline, invoices
- Returns & exchanges workflow (request, track, history)
- Projects (RFQ) module: create installation projects, configure BOM, receive supplier offers, accept/reject, convert to a project-order
- User profile, addresses, order history
- Support / ticketing
- Bilingual UI with language switcher
Routes: /, /categories, /items/[id], /cart, /checkout,
/favorites, /orders/[id], /projects, /projects/new, /projects/[id],
/project-orders/[id], /returns, /returns/new, /returns/[id],
/profile, /payment, /invoice, /support, /login, /register
3.3 Trader Dashboard (frontend-trader, port 3002)
Where suppliers run their business on the platform.
- KPI dashboard (earnings, orders, stock alerts, ratings)
- Listings management: create/edit per-item listings with min/max price, stock, reserved stock, lead time, reliability score
- Excel import/export of listings (bulk operations)
- Pending assignments queue (accept / reject sub-orders)
- Sub-order fulfillment: accept → ship → deliver → confirm cash
- Supplier orders views: accepted / history
- Project orders flow for RFQ-won projects
- Returns review & approval
- Balance & commission ledger view
- Analytics (per-trader): revenue, conversion, top items, trends
- Trader settings, service sections (shipping zones), profile, verification
- Bilingual UI (AR/EN)
Routes: /dashboard, /dashboard/listings, /dashboard/pending-assignments,
/dashboard/sub-orders/[id], /dashboard/supplier-orders/{accepted,history},
/dashboard/projects, /dashboard/project-orders/[id], /dashboard/returns,
/dashboard/balance, /dashboard/analytics, /dashboard/settings,
/dashboard/support
3.4 Admin Panel (frontend-admin, port 3003)
Operational backbone of the platform.
- Items catalog (master items used by all suppliers)
- Categories (hierarchical)
- Traders management & verification
- Users management (customers + traders)
- Orders (all orders + manual overrides)
- Projects & BOM Patterns (reusable bills-of-materials)
- Returns management + returns analytics
- Stock overview across all suppliers
- Sections (geographic shipping zones + distance matrix)
- Commissions & commission ledger
- Financial / traders (payouts, balances)
- Invoices
- Analytics (platform-wide, revenue tracking)
- Banners (marketplace hero/promo banners)
- CMS for the landing site:
- Services
- Lift Types
- Portfolio Projects
- Blog
- Clients (logos / testimonials)
- Hero section
- Marketplace settings
- System settings, activity logs, notifications, support tickets
Routes: /dashboard/{items, categories, traders, users, orders, projects, bom-patterns, returns, stock, sections, commissions, financial, invoices, analytics, banners, settings, activity, notifications, support} plus
/cms/{services, lift-types, portfolio, blog, clients, hero, settings}
4. Backend (NestJS)
30+ feature modules, organized by domain:
| Module | Responsibility |
|---|---|
auth | JWT + Passport login, customer/trader registration, role guards |
users | User CRUD, profile, address book |
traders | Trader profile, verification, sections (shipping zones) |
items | Admin-owned master catalog (specs, images, category, brand) |
categories | Hierarchical category tree (parent/children) |
client-items | Public read API exposing items + cheapest supplier price |
supplier-listings | Trader listings (price ranges, stock, lead time, reliability) |
orders | Customer orders, order items, totals, deposit logic |
sub-orders | Per-trader splits of a master order, with full lifecycle |
projects | RFQ projects, BOM patterns, supplier offers, project orders |
pricing-engine | Supplier scoring & multi-strategy assignment algorithm |
commissions | Platform fee accrual, invoicing, trader ledger, cron jobs |
payments | Paymob iframe creation + HMAC-validated webhook + COD |
delivery-notes | Vendor delivery confirmation that triggers commission |
returns | Customer returns/exchanges, trader review, refund flow |
cms | Services / lift-types / portfolio / blog / clients / hero / settings |
banners | Marketplace promotional banners |
sections | Geographic sections + distance matrix for shipping calc |
shipping | Shipping cost calculation per section/trader |
stock | Stock + reservation tracking, low-stock alerts |
excel | Generic Excel import/export utilities |
upload | Cloudinary integration for media |
favorites | Wishlist |
reviews | Product & trader ratings |
notifications | In-app notifications |
activity-logs | Audit trail of important user actions |
support | Support tickets |
admin | Platform-wide stats & admin overrides |
internal | Margin analytics & supplier-selection introspection |
health | /health checks for Docker/Nginx probes |
services | Domain service utilities shared across modules |
Cross-cutting: Swagger/OpenAPI docs, class-validator DTOs, throttling
(@nestjs/throttler), scheduled jobs (@nestjs/schedule), Helmet, compression,
CORS, centralized error handling.
5. Database (Prisma · MySQL)
50 models across these domains:
- Identity:
User,TraderProfile,Address - Catalog:
Category,Item,SupplierListing,PricingRule,Banner - Orders:
Order,OrderItem,SubOrder,SubOrderItem,OrderAssignment,SubOrderAssignment,DeliveryNote - Projects / RFQ:
Project,BomPattern,BomPatternItem,ProjectSpecification,BillOfMaterialItem,SupplierOffer,SupplierOfferItem,ProjectOrder,ProjectOrderItem - Money:
Invoice,CommissionRecord,CommissionInvoice,TraderLedger,CommissionLedgerEntry - Customer Experience:
Review,Favorite,ReturnRequest,ReturnRequestItem,SupportTicket,Notification,ActivityLog - Geo / Shipping:
Country,Section,TraderSection,SectionDistance - CMS:
Service,LiftType,PortfolioProject,BlogPost,Client,CompanySetting,HeroSection,MarketplaceSetting,FAQ - Config:
SystemSetting
All money flows are checksummed (SHA-256) and append-only.
6. Signature Features (the "wow" of the project)
6.1 Smart Multi-Strategy Order Assignment
When a customer order has N items, the platform splits it into SubOrders per trader using one of three strategies:
| Strategy | How it picks | Result | Best for |
|---|---|---|---|
| Best Per Item | Highest supplierScore per item | Many SubOrders, best quality/price | Premium orders |
| Most Availability | Trader covering most items, weighted 60% items + 40% quality | Fewer SubOrders, faster | Speed-critical |
| Hybrid (default) | 1st SubOrder = Most Availability, rest = Best Per Item | 3–4 SubOrders, balanced | Most orders |
Rejection handling is recursive: when a trader rejects, the system re-runs assignment on the remaining unassigned items while excluding the rejecting trader.
6.2 Projects / RFQ Workflow (Installer-Grade)
Installers configure full elevator projects (buildings × floors × elevators, door type, machine type, control type, cabin, origin preference) — either from scratch or from a saved BOM Pattern. The BOM is broken into categorized items (DOOR / MACHINE / CONTROLLER / RAIL / CABLE / ACCESSORY), suppliers submit multi-item offers with full pricing, and the installer accepts one offer that becomes a ProjectOrder assigned to the winning trader.
6.3 Tamper-Proof Financial Ledger
Every money event is a ledger entry with:
balanceBefore/balanceAfter- SHA-256
checksumlinking entry → previous entry transactionReffor forensics- Append-only — integrity verifiable end-to-end
Entry types: PAYMENT_RECEIVED, DEPOSIT_PAID, COMMISSION_DEDUCTED,
TRADER_PAYOUT, REFUND.
6.4 Deposit Engine for Large Orders
Risk-based deposit gating before fulfillment:
| Order value | New user | Trusted user (>6 mo) |
|---|---|---|
| < 20k EGP | None | None |
| 20k – 100k | 15% | None |
| > 100k | 20% | 20% |
6.5 Commission System
- Configurable per-trader rates (default 2.5%, custom override for VIPs)
- Platform fee =
min(subtotal × 3%, 1000 EGP)capped per order - Commission is accrued on delivery confirmation, invoiced on a schedule (cron), and reconciled via the trader ledger
- Statuses:
ACCRUED → INVOICED → PAID(plusWAIVEDand invoiceDRAFT/ISSUED/PAID/OVERDUE/CANCELLED)
6.6 Delivery Notes
Formal delivery confirmation is its own document — AUTO, VENDOR_CLICK,
CLIENT_ACK, or ADMIN_OVERRIDE. Only a confirmed delivery note triggers
commission accrual, keeping money flows aligned with physical fulfillment.
6.7 Returns & Exchanges
First-class workflow with two types:
- EXCHANGE (default — defective item replaced; a new exchange order is created)
- REFUND_ONLY (for shipping errors)
Status machine: REQUESTED → UNDER_REVIEW → APPROVED/REJECTED → PROCESSING → COMPLETED/CANCELLED.
6.8 Section-Based Shipping
Geographic Sections with a distance matrix between them; each trader declares which sections they serve and their primary pickup section, allowing realistic shipping cost calculation per sub-order.
6.9 Full Bilingual / RTL System
Every customer-facing surface (landing, client, trader) and the catalog itself (item names, descriptions, CMS content) is bilingual Arabic + English with proper RTL and a language switcher.
6.10 CMS for the Marketing Site
The landing page is fully editable by admins — services, lift types, portfolio projects, blog posts, client logos, hero, FAQs, marketplace settings — all with SEO fields, ordering, slugs, image management, and publish toggles.
6.11 Excel Import / Export
Traders can bulk-manage their listings via Excel round-trip; admins can export reports.
6.12 Paymob Integration
Card + wallet payments with iframe redirect, HMAC SHA-512 signature validation on webhooks, idempotency keys to prevent double-charge, transaction-wrapped DB updates.
7. Security
- JWT (Bearer) with role guards:
ADMIN | TRADER | CUSTOMER - bcrypt password hashing
- Prisma parameterized queries (no SQL injection surface)
- Helmet security headers, CORS allowlist, throttling
- class-validator DTOs at every controller
- Paymob HMAC validation + idempotency
- SHA-256 ledger checksums for financial integrity
- HTTPS everywhere (Let's Encrypt, auto-renewing)
8. DevOps & Tooling
- Local dev:
docker-compose.dev.ymlwith hot-reload across all 5 services; one-shot./start-dev-env.sh - Production:
docker-compose.ymlon a VPS, Nginx reverse-proxy in front, four sub-domains (montralifts.com,api.,admin.,trader.) - CI/CD: GitHub Actions auto-deploys on push to
master - Health checks:
/api/v1/health(backend) +/_healthz(Next.js apps) - DB tooling: Prisma migrations, seed scripts (
prisma:seed,prisma:seed:clean), Prisma Studio - Testing: Jest unit + e2e on backend,
fast-checkproperty-based tests for critical algorithms (assignment / pricing)
9. Tech Stack Summary
Backend: NestJS 10 · TypeScript · Prisma 5 · MySQL 8 · JWT + Passport · class-validator · Swagger · Helmet · Throttler · @nestjs/schedule · Multer · Cloudinary · Paymob · xlsx · Axios
Frontend (all 4 apps): Next.js 16 (App Router) · React 19 · TypeScript · TailwindCSS 4 · shadcn/ui · Radix primitives · Zustand · React Hook Form + Zod · SWR / Axios · Framer Motion · Recharts · Lucide · sonner / react-hot-toast
Infra: Docker · Docker Compose · Nginx · Let's Encrypt · GitHub Actions · VPS
10. Numbers
| Metric | Count |
|---|---|
| Frontend applications | 4 |
| Backend feature modules | 30+ |
| REST endpoints | 100+ |
| Prisma models | 50 |
| User roles | 3 (Customer, Trader, Admin) |
| Order-assignment strategies | 3 |
| Languages supported | 2 (AR + EN, RTL/LTR) |
| Payment methods | Card, Mobile Wallet, Bank Transfer, COD |
| Production sub-domains | 4 |
11. My Role / What I Built
End-to-end ownership: product architecture, database design, backend (NestJS, Prisma, Paymob integration, smart assignment engine, commission & ledger system, RFQ workflow, returns), all four Next.js frontends (marketplace UX, trader operations, admin tooling, marketing site CMS), i18n (AR/EN + RTL), Docker/Nginx deployment, and CI/CD.
Built for the Egyptian elevator industry · Production-ready · 2026