Architecture - mukular/food-delivery-feastfast--architecture GitHub Wiki

Architecture Overview

1. System Summary

This project is a production-grade, multi-role food delivery platform designed to support:

  • Customers
  • Restaurant owners (sellers)
  • Delivery partners
  • Admin users

The system is built with a service-oriented architecture, real-time communication, caching, and scalable data access patterns.

It supports:

  • Geo-based restaurant discovery
  • Real-time order lifecycle
  • Live delivery tracking
  • Coupon & promotions system
  • Wallet, COD, and online payments
  • Role-based dashboards
  • Redis-backed sessions & caching
  • WebSocket-driven real-time updates

The architecture is designed to be horizontally scalable, fault-tolerant, and optimized for read-heavy workloads.


2. High-Level Architecture

[ Client Apps (Web) ]
        |
        v
[ Next.js / React Frontend ]
        |
        v
[ Express.js API Server ]
        |
        +-----------------------+
        |                       |
        v                       v
[ MongoDB Atlas ]         [ Redis ]
 (Primary DB)        (Cache + Sessions)
        |
        v
[ Razorpay API ]
 (Payments & Webhooks)

Key Components

Component Responsibility
Frontend (React / Next.js) UI, state management, SSR/CSR (future)
Express API Business logic, auth, order processing
MongoDB Primary transactional data store
Redis Caching, session store,
Socket.IO Real-time events & live tracking
Razorpay Online payments + webhooks

3. Frontend Architecture

Tech Stack

  • React (migratable to Next.js)
  • TanStack Query (data fetching + caching)
  • Redux Toolkit (global state)
  • Socket.IO client
  • Tailwind CSS
  • Role-based layouts

Key Design Decisions

a) Role-based Layouts

Separate layouts for:

  • Customer
  • Seller
  • Delivery partner
  • Admin

Each layout:

  • Manages role-specific sockets
  • Loads role-specific data
  • Controls access & navigation

b) Client-side Caching

TanStack Query is used for:

  • Menu pagination
  • Filters & search
  • Order lists
  • Restaurant discovery

This reduces backend load and improves perceived performance.

c) Real-Time UX

Socket.IO is used for:

  • Order status changes
  • Delivery tracking
  • Toast notifications

4. Backend Architecture (Express API)

Core Responsibilities

  • Authentication & session validation
  • Order orchestration
  • Coupon validation
  • Payment integration
  • Geo-based restaurant queries
  • Seller & delivery workflows
  • Admin moderation

Layered Structure

Routes  
  ↓  
Controllers  
  ↓  
Services / Business Logic  
  ↓  
Models (Mongoose)  
  ↓  
MongoDB  

This separation allows:

  • Easier testing
  • Clear business logic boundaries
  • Future migration to microservices if needed

5. Database Architecture (MongoDB)

MongoDB is used as the primary data store for:

  • Users
  • Shops
  • Items (menu)
  • Orders
  • ShopOrders (embedded)
  • Coupons
  • Delivery assignments
  • Wallet transactions

Key Modeling Patterns

a) Embedded Subdocuments

shopOrders are embedded inside Order documents.

Benefits:

  • Atomic updates
  • Faster order reads
  • Easier order lifecycle tracking

Trade-off:

  • Larger documents
  • More complex aggregations

This was chosen intentionally for read performance.


6. Redis Architecture

Redis is used for two major purposes:

a) Caching (Read-heavy APIs)

Cached endpoints:

  • Restaurant discovery
  • Menu items by shop
  • Filtered & paginated queries

Key strategies:

  • Lat/Lng rounding to reduce key explosion
  • Filter-based cache keys
  • Short TTL (e.g., 60 seconds)

Example key:

restaurants:28.61:77.23:search=pizza|rating=4|skip=0

b) Session Store

Redis stores:

  • User sessions
  • Multi-device session control
  • Forced logout support
  • Session expiry

This enables:

  • Centralized session invalidation
  • Better security than stateless JWT-only auth

7. Real-Time Architecture (Socket.IO)

Socket.IO is used for:

a) Order Lifecycle Events

Events:

  • confirmed
  • ready
  • out_for_delivery
  • delivered

Used for:

  • Toast notifications
  • Live UI updates
  • Delivery partner tracking

b) Live Delivery Tracking

Delivery partners:

  • Emit GPS coordinates
  • Server broadcasts to customer room

Customer sees live movement.

Room-based architecture:

  • room: customer:{userId}

8. Payments Architecture (Razorpay)

Payment Flow

Client  
  ↓  
Create Order (pending)
  ↓  
Update Coupon Usage    
  ↓  
Razorpay Order Created  
  ↓  
Client Pays  
  ↓  
Razorpay Webhook  
  ↓  
Verify Signature  
  ↓  
Mark Order Paid  

Design Decisions

  • Webhook-based payment confirmation
  • Idempotent webhook handling
  • Amount verification
  • Refund handling for cancelled orders

9. Coupon System Architecture

Coupons support:

  • Percentage discounts
  • Fixed amount discounts
  • Free item coupons
  • Per-user limits
  • Global usage limits
  • Category-based applicability
  • Excluded items

Key Challenges Handled

  • Race conditions
  • Usage limits
  • Webhook vs createOrder timing

Chosen Approach

For simplicity and safety, coupon usage is incremented in createOrder.

  • Avoids oversubscription complexity
  • Trades minor overuse risk for system simplicity
  • Documented trade-off intentionally

10. Geo & Distance Architecture

MongoDB $geoNear is used for:

  • Nearby restaurant discovery
  • Distance calculation
  • Delivery radius validation

Features:

  • Distance-based delivery fee
  • Out-of-range order rejection
  • Rounded lat/lng for caching

11. Time & Timezone Strategy

  • All timestamps stored in UTC
  • Server handles UTC
  • Frontend formats to local timezone
  • Shop opening hours handled with server-side normalization

This prevents:

  • Cross-timezone revenue bugs
  • Incorrect daily aggregations
  • Inconsistent analytics

12. Scalability & Future Improvements

Planned or supported:

  • Horizontal scaling of API servers
  • Redis cluster
  • Read replicas for MongoDB
  • Background workers (BullMQ)
  • CDN for images
  • Elasticsearch for search
  • Microservices split (orders, payments, notifications)

13. Key Engineering Trade-offs

Decision Trade-off
Embedded shopOrders Faster reads, harder aggregations
Cache per filter Higher memory, faster UX
Redis sessions Extra infra, better security
Coupon simplicity Possible rare overuse, simpler system
MongoDB over SQL Faster iteration, flexible schema

14. Why This Architecture Matters

This architecture demonstrates:

  • Real-world scaling concerns
  • Race condition handling
  • Caching strategies
  • Event-driven UI
  • Payment safety
  • Geo-based systems
  • Multi-role system design