AAMLabs (now Forge Labs) · Full-stack engineer

Pedeja Delivery

Multi-tenant delivery SaaS — 7-microservice NestJS backend with React 19 backoffice and Expo mobile, sharing typed schemas across surfaces.

Client
AAMLabs (now Forge Labs)
Role
Full-stack engineer
Period
2024 – 2025

The problem

A delivery SaaS that had to serve restaurants, drivers, and end customers without becoming a monolith that ships every Friday at 2am. The owners wanted independent scaling per surface — order traffic spikes at lunch, delivery tracking is steady, payment is bursty around end-of-day reconciliation — and a clean separation between business domains so the team could ship features without stepping on each other.

Architecture

Seven NestJS 11 services, each owning its own data and contract, sharing patterns but never databases:

   pedeja-delivery-{auth, user, catalog, order, payment, notification, delivery}-api
   ───────────────────────────────────────────────────────────────────────────────
   auth         sessions · refresh · token rotation
   user         profiles · addresses · roles
   catalog      restaurants · menus · items · pricing
   order        placement · lifecycle state machine
   payment      providers · settlements · refunds
   notification email · push · in-app dispatch
   delivery     rider assignment · ETA · proof of delivery

Each service exposes a versioned REST API documented with Swagger. Inter-service communication is HTTP for synchronous reads and Redis-backed queues for asynchronous side effects (notifications, settlement, ETA updates). Auth is centralized — a single JWT crosses every service, validated per-request.

Web backoffice

React 19 + Vite 7 with TanStack Router (file-based routing, automatic code splitting) and TanStack Query v5 for server state. UI primitives are shadcn/ui over Radix, styled with custom Tailwind v4 tokens. Forms run on React Hook Form + Zod with schemas mirroring the API contracts. Client state lives in Zustand stores (auth, UI, theme).

For local dev I wired MSW mocks against every service so the backoffice can boot and exercise the full UI without any backend running.

Mobile

The customer-facing app is Expo / React Native, sharing the domain types via a generated client so a change to an order schema in the backend propagates type-safely to both surfaces.

Outcome

Each service deploys independently. Adding a new payment method touches one service and zero others. Scaling lunch rush means scaling order and payment only — the rest stays at baseline. The web backoffice ships features at its own cadence, decoupled from the mobile release train.

Numbers

  • 7

    Microservices

  • Web + Mobile

    Surfaces

Stack

  • NestJS 11
  • Prisma 6
  • PostgreSQL
  • Redis
  • React 19
  • Vite 7
  • TanStack Router
  • TanStack Query v5
  • Tailwind 4
  • shadcn/ui
  • Zustand
  • React Hook Form
  • Zod
  • Expo
  • React Native
  • MSW