Skip to main content

🏗️ System Architecture & Technology Stack

Project: Khanaa Food Delivery Platform
Lead Architect: Er. Monowar Hussain
Document Status: Finalized for Phase 1 (MVP)

Overview

Khanaa operates on a microservices-inspired architecture utilizing polyglot persistence (multiple database types). Because a food delivery platform requires handling high-volume financial transactions concurrently with high-frequency, real-time GPS tracking, a monolithic approach will fail at scale.

This architecture separates standard business logic from heavy logistics processing, ensuring the platform remains fast, reliable, and cost-effective as we scale from 500 to 50,000 users.


1. Client-Side Ecosystem (Frontends)

We maintain four distinct user interfaces. To maximize development speed while ensuring performance, we utilize a mix of cross-platform frameworks, native development, and web technologies.

1.1 Customer App & Vendor App

  • Technology: React Native
  • State Management: Zustand or Redux Toolkit
  • API Client: Axios / TanStack Query
  • Why: React Native allows us to maintain a single JavaScript/TypeScript codebase for both iOS and Android. It shares logical paradigms with our web dashboards, speeding up cross-team development.

1.2 Rider (Driver) App

  • Technology: Kotlin (Native Android)
  • UI Toolkit: Jetpack Compose
  • Location Handling: FusedLocationProviderClient + Android Foreground Services
  • Why: Battery Optimization. React Native consumes too much background memory for continuous GPS tracking. Kotlin gives us low-level access to Android's WakeLocks and Doze Mode, ensuring the rider's battery doesn't drain while tracking is active.

1.3 Super Admin & Vendor Web Dashboards

  • Technology: Next.js (React) via App Router
  • Styling: Tailwind CSS + shadcn/ui
  • Why: Next.js provides Server-Side Rendering (SSR), making massive data tables (like active orders or vendor payouts) load instantly without lagging the user's browser.

2. Backend Microservices

The backend is split into two specialized services to prevent heavy map computations from crashing the ordering system.

2.1 Core Business API (khanaa-api-core)

  • Technology: Node.js with NestJS Framework
  • Role: The brain of the platform.
  • Responsibilities: * User Authentication (JWT validation).
    • Order State Machine (Created -> Accepted -> Prepared -> Dispatched -> Delivered).
    • Payment routing and Razorpay webhooks.
    • Complex pricing logic and coupon validation (e.g., WELCOME50).
  • Why NestJS: It enforces strict TypeScript and a modular, Angular-like structure, preventing the codebase from becoming a messy "spaghetti" architecture as the team grows.

2.2 Logistics & Tracking Engine (khanaa-logistics-service)

  • Technology: Go (Golang) OR Node.js with Socket.io
  • Role: The real-time muscle.
  • Responsibilities:
    • Maintains thousands of persistent WebSocket connections.
    • Ingests rider GPS coordinates every 3-5 seconds.
    • Executes the expanding-radius Auto-Assignment Algorithm (1KM -> 2KM -> Broadcast) and 45-degree directional matching.
  • Why: Go handles raw concurrency and complex mathematical routing algorithms with drastically lower CPU and memory usage compared to standard Node.js scripts.

3. Polyglot Database Layer

A single database cannot efficiently handle both strict financial data and unstructured menu catalogs. We use three specific data stores.

3.1 Primary Transactional Database

  • Technology: PostgreSQL
  • Critical Extension: PostGIS
  • Usage: Stores strict, relational data where data integrity is paramount (User profiles, Order history, Wallets, Payout ledgers).
  • Why PostGIS: PostGIS is a spatial database extender. Instead of calculating distance on our Node.js server, we use PostGIS ST_Distance queries to instantly find riders within a 1km radius natively in the database.

3.2 Catalog & Document Database

  • Technology: MongoDB
  • Usage: Stores flexible, read-heavy documents (Restaurant Menus, Item Modifiers, Custom Diets, User Reviews & Ratings).
  • Why: Menus change constantly and have unpredictable nested structures (e.g., "Add extra cheese", "Make it spicy"). MongoDB's NoSQL document structure handles this perfectly without requiring complex table migrations.

3.3 In-Memory Cache & Message Broker

  • Technology: Redis
  • Usage: * Caching high-traffic queries (e.g., the homepage list of open restaurants).
    • Temporary storage for user Shopping Carts.
    • Pub/Sub message broker to communicate between the NestJS Core API and the Logistics Microservice.

4. Cloud Infrastructure & DevOps

  • Cloud Provider: AWS (Amazon Web Services)
  • Containerization: Docker (All backends and databases must run in containers to ensure parity between local development and production).
  • Hosting (Phase 1): AWS ECS (Elastic Container Service) or App Runner for simplified deployment.
  • Storage: AWS S3 (For storing user avatars, vendor FSSAI PDF documents, and restaurant menu images).

5. Third-Party Integrations

Do not reinvent the wheel. Use the following approved external services:

  • Payments & Payouts: Razorpay (Handles UPI, Cards, Wallets, and complex multi-party splits).
  • SMS & OTP: sendmymessage (DLT-compliant transactional SMS).
  • Mapping & Distance: Google Maps API (Maps SDK for mobile, Places API for autocomplete, Distance Matrix API for ETAs).
  • Authentication & Comms: Firebase (Google SSO, Firebase Cloud Messaging for Push Notifications).
  • Analytics & Crash Monitoring: * Firebase Crashlytics & Sentry (App crashes and API failures).
    • Mixpanel & Google Analytics (User behavior and drop-offs).
    • Microsoft Clarity (Heatmaps and UI blockages).

6. Crucial Architectural Rules for Developers

  1. Idempotency is Mandatory: All payment creation and order confirmation endpoints must be idempotent. If a customer's phone glitches and sends the "Pay Now" request three times in one second, the database must only process the order once. Use unique idempotency keys.
  2. Never Calculate Distance on the Server: Let PostGIS do the math. Node.js should only pass coordinates to the PostgreSQL database.
  3. Graceful Degradation: If MongoDB goes offline, the Node.js API must not crash. Catch the error, log it to Sentry, and return a clean error to the frontend (e.g., "Menus currently unavailable") while keeping the rest of the app functional.
  4. Protect the Battery: Kotlin developers must manage WakeLocks carefully. Only engage heavy foreground GPS polling when the rider has an active accepted order.