Skip to content

AnuragDubey007/TrustBid

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

7 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

๐ŸŽฏ TrustBid - British Auction RFQ System

TrustBid Banner

Live Demo MongoDB Express.js React Node.js Socket.io

A real-time British Auction system with intelligent bid-time extensions and transparent supplier competition

Features โ€ข Architecture โ€ข Installation โ€ข API Docs โ€ข Demo


๐Ÿ“‹ Table of Contents

  1. Overview
  2. Key Features
  3. Live Demo
  4. High-Level Design (HLD)
  5. Database Schema Design
  6. Tech Stack
  7. Design Tradeoffs
  8. Installation & Setup
  9. API Documentation
  10. Advanced Implementation Details
  11. Business Logic & Auction Mechanics
  12. Demo Credentials
  13. Project Structure

๐ŸŽฏ Overview

TrustBid is a sophisticated RFQ (Request for Quotation) management system implementing British Auction mechanics to ensure fair and transparent supplier competition. The system prevents last-second bid sniping through intelligent automatic time extensions and provides real-time updates to all participants.

What is a British Auction?

A British Auction in the RFQ context is a competitive bidding process where:

  • โœ… Suppliers submit bids openly and can continuously lower prices
  • โœ… Bidding activity near auction close time triggers automatic extensions
  • โœ… A forced close time ensures auctions conclude within reasonable timeframes
  • โœ… Multiple extension triggers ensure fair competition

โœจ Key Features

๐ŸŽช Core Auction Features

  • Role-Based Access Control: Separate buyer and supplier workflows
  • Real-Time Bidding: Live bid updates using Socket.IO
  • Intelligent Time Extensions: Automatic auction extensions based on configurable triggers
  • Force Close Mechanism: Guaranteed auction conclusion time
  • Live Rankings: Real-time L1, L2, L3 supplier rankings
  • Activity Logging: Complete audit trail of all bids and extensions

๐Ÿ”ง Advanced Technical Features

  • Race Condition Prevention: MongoDB transactions for concurrent bid handling
  • Optimistic Updates: Real-time UI updates with server validation
  • Time Synchronization: Client-server time offset handling
  • Responsive Design: Mobile-first UI with dark/light themes
  • Form Validation: Comprehensive client and server-side validation

๐Ÿ›ก๏ธ Security Features

  • JWT-based authentication
  • Role-based authorization middleware
  • Password hashing with bcrypt
  • Protected API endpoints
  • Input sanitization and validation

Live Demo

๐Ÿ”— https://trust-bid-gamma.vercel.app


๐Ÿ—๏ธ High-Level Design (HLD)

System Architecture

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                          CLIENT TIER                                โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚  โ”‚                    React SPA (Vite)                          โ”‚  โ”‚
โ”‚  โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”‚  โ”‚
โ”‚  โ”‚  โ”‚   Auth     โ”‚  โ”‚  Auction   โ”‚  โ”‚   Real-time Sync    โ”‚    โ”‚  โ”‚
โ”‚  โ”‚  โ”‚   Views    โ”‚  โ”‚   Views    โ”‚  โ”‚   (Socket.IO)       โ”‚    โ”‚  โ”‚
โ”‚  โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ”‚  โ”‚
โ”‚  โ”‚         โ”‚               โ”‚                    โ”‚               โ”‚  โ”‚
โ”‚  โ”‚         โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜               โ”‚  โ”‚
โ”‚  โ”‚                         โ”‚                                    โ”‚  โ”‚
โ”‚  โ”‚                    useAuction Hook                           โ”‚  โ”‚
โ”‚  โ”‚                         โ”‚                                    โ”‚  โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                             โ”‚
                    HTTPS/WSS โ”‚
                             โ”‚
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                       API GATEWAY                                   โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚  โ”‚                    Express.js Server                         โ”‚  โ”‚
โ”‚  โ”‚                                                               โ”‚  โ”‚
โ”‚  โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚  โ”‚
โ”‚  โ”‚  โ”‚   Auth   โ”‚  โ”‚ Auction  โ”‚  โ”‚   Bid    โ”‚  โ”‚  Activity   โ”‚ โ”‚  โ”‚
โ”‚  โ”‚  โ”‚  Routes  โ”‚  โ”‚  Routes  โ”‚  โ”‚  Routes  โ”‚  โ”‚   Routes    โ”‚ โ”‚  โ”‚
โ”‚  โ”‚  โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚  โ”‚
โ”‚  โ”‚       โ”‚             โ”‚             โ”‚                โ”‚         โ”‚  โ”‚
โ”‚  โ”‚       โ”‚             โ”‚             โ”‚                โ”‚         โ”‚  โ”‚
โ”‚  โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚  โ”‚
โ”‚  โ”‚  โ”‚   Auth   โ”‚  โ”‚ Auction  โ”‚  โ”‚   Bid    โ”‚  โ”‚  Activity   โ”‚ โ”‚  โ”‚
โ”‚  โ”‚  โ”‚Controllerโ”‚  โ”‚Controllerโ”‚  โ”‚Controllerโ”‚  โ”‚ Controller  โ”‚ โ”‚  โ”‚
โ”‚  โ”‚  โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚  โ”‚
โ”‚  โ”‚       โ”‚             โ”‚             โ”‚                โ”‚         โ”‚  โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
โ”‚          โ”‚             โ”‚             โ”‚                โ”‚             โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚  โ”‚              Business Logic Layer                            โ”‚  โ”‚
โ”‚  โ”‚  โ€ข Extension Logic    โ€ข Validation Rules                     โ”‚  โ”‚
โ”‚  โ”‚  โ€ข Ranking System     โ€ข Time Calculations                    โ”‚  โ”‚
โ”‚  โ”‚  โ€ข Status Management  โ€ข Transaction Handling                 โ”‚  โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
โ”‚                             โ”‚                                       โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
โ”‚  โ”‚                  Middleware Layer                             โ”‚ โ”‚
โ”‚  โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”‚ โ”‚
โ”‚  โ”‚  โ”‚     JWT      โ”‚  โ”‚     CORS     โ”‚  โ”‚   Rate Limiting  โ”‚   โ”‚ โ”‚
โ”‚  โ”‚  โ”‚     Auth     โ”‚  โ”‚   Handler    โ”‚  โ”‚    (Future)      โ”‚   โ”‚ โ”‚
โ”‚  โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚ โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                             โ”‚
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                      DATA TIER                                      โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚  โ”‚                    MongoDB Atlas                             โ”‚  โ”‚
โ”‚  โ”‚                                                               โ”‚  โ”‚
โ”‚  โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚  โ”‚
โ”‚  โ”‚  โ”‚  Users  โ”‚  โ”‚ Auctions โ”‚  โ”‚ Bids โ”‚  โ”‚  ActivityLogs    โ”‚ โ”‚  โ”‚
โ”‚  โ”‚  โ”‚ (Auth)  โ”‚  โ”‚  (RFQs)  โ”‚  โ”‚      โ”‚  โ”‚  (Audit Trail)   โ”‚ โ”‚  โ”‚
โ”‚  โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚  โ”‚
โ”‚  โ”‚                                                               โ”‚  โ”‚
โ”‚  โ”‚  โ€ข Indexes for Performance                                   โ”‚  โ”‚
โ”‚  โ”‚  โ€ข Transaction Support (ACID)                                โ”‚  โ”‚
โ”‚  โ”‚  โ€ข Aggregation Pipelines                                     โ”‚  โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                  REAL-TIME COMMUNICATION                            โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚  โ”‚                    Socket.IO Server                          โ”‚  โ”‚
โ”‚  โ”‚                                                               โ”‚  โ”‚
โ”‚  โ”‚  Events:                                                      โ”‚  โ”‚
โ”‚  โ”‚    โ€ข joinAuction      โ†’ Client joins auction room            โ”‚  โ”‚
โ”‚  โ”‚    โ€ข newBid           โ†’ Broadcast new bid to all clients     โ”‚  โ”‚
โ”‚  โ”‚    โ€ข auctionExtended  โ†’ Broadcast time extension             โ”‚  โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Component Interaction Flow

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                                                    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Buyer   โ”‚                                                    โ”‚ Supplier โ”‚
โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”˜                                                    โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”˜
     โ”‚                                                               โ”‚
     โ”‚ 1. Create RFQ                                                 โ”‚
     โ”‚ POST /api/auctions                                            โ”‚
     โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                                โ”‚
     โ”‚                              โ”‚                                โ”‚
     โ”‚                         โ”Œโ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”                           โ”‚
     โ”‚                         โ”‚ Express โ”‚                           โ”‚
     โ”‚                         โ”‚ Server  โ”‚                           โ”‚
     โ”‚                         โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”˜                           โ”‚
     โ”‚                              โ”‚                                โ”‚
     โ”‚                         2. Validate                           โ”‚
     โ”‚                         โ€ข Time constraints                    โ”‚
     โ”‚                         โ€ข Auth check                          โ”‚
     โ”‚                         โ€ข Field validation                    โ”‚
     โ”‚                              โ”‚                                โ”‚
     โ”‚                         โ”Œโ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”                           โ”‚
     โ”‚                         โ”‚ MongoDB โ”‚                           โ”‚
     โ”‚                         โ”‚ Auction โ”‚                           โ”‚
     โ”‚                         โ”‚ Created โ”‚                           โ”‚
     โ”‚                         โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”˜                           โ”‚
     โ”‚                              โ”‚                                โ”‚
     โ”‚ 3. RFQ Created               โ”‚                                โ”‚
     โ”‚โ—„โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค                                โ”‚
     โ”‚                              โ”‚                                โ”‚
     โ”‚                              โ”‚                                โ”‚
     โ”‚                              โ”‚         4. View Auction        โ”‚
     โ”‚                              โ”‚         GET /api/auctions/:id  โ”‚
     โ”‚                              โ”‚โ—„โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
     โ”‚                              โ”‚                                โ”‚
     โ”‚                              โ”‚         5. Auction Details     โ”‚
     โ”‚                              โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บโ”‚
     โ”‚                              โ”‚                                โ”‚
     โ”‚                              โ”‚         6. Join Socket Room    โ”‚
     โ”‚                              โ”‚         socket.emit('joinAuction')
     โ”‚                              โ”‚โ—„โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
     โ”‚                              โ”‚                                โ”‚
     โ”‚                              โ”‚         7. Place Bid           โ”‚
     โ”‚                              โ”‚         POST /api/bids         โ”‚
     โ”‚                              โ”‚โ—„โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
     โ”‚                              โ”‚                                โ”‚
     โ”‚                         8. Start Transaction                  โ”‚
     โ”‚                         โ”Œโ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”                           โ”‚
     โ”‚                         โ”‚ MongoDB โ”‚                           โ”‚
     โ”‚                         โ”‚ Session โ”‚                           โ”‚
     โ”‚                         โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”˜                           โ”‚
     โ”‚                              โ”‚                                โ”‚
     โ”‚                         9. Validate Bid                       โ”‚
     โ”‚                         โ€ข Amount < current lowest             โ”‚
     โ”‚                         โ€ข Auction still active                โ”‚
     โ”‚                         โ€ข No duplicate amounts                โ”‚
     โ”‚                              โ”‚                                โ”‚
     โ”‚                         10. Check Extension                   โ”‚
     โ”‚                         โ€ข Within trigger window?              โ”‚
     โ”‚                         โ€ข Trigger type met?                   โ”‚
     โ”‚                              โ”‚                                โ”‚
     โ”‚                         11. Save Bid                          โ”‚
     โ”‚                         12. Update Rankings                   โ”‚
     โ”‚                         13. Create Activity Log               โ”‚
     โ”‚                              โ”‚                                โ”‚
     โ”‚                         14. Commit Transaction                โ”‚
     โ”‚                         โ”Œโ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”                           โ”‚
     โ”‚                         โ”‚ Socket  โ”‚                           โ”‚
     โ”‚                         โ”‚   IO    โ”‚                           โ”‚
     โ”‚                         โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”˜                           โ”‚
     โ”‚                              โ”‚                                โ”‚
     โ”‚ 15. Broadcast newBid         โ”‚         15. Receive newBid     โ”‚
     โ”‚โ—„โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บโ”‚
     โ”‚                              โ”‚                                โ”‚
     โ”‚ 16. Broadcast auctionExtendedโ”‚   16. Receive auctionExtended  โ”‚
     โ”‚โ—„โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บโ”‚
     โ”‚                              โ”‚                                โ”‚
     โ”‚ 17. UI Auto-Updates          โ”‚         17. UI Auto-Updates    โ”‚
     โ”‚                              โ”‚                                โ”‚

๐Ÿ’พ Database Schema Design

Collections Overview

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                         MongoDB Collections                         โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ USERS COLLECTION                                                     โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ _id          : ObjectId (PK)                                         โ”‚
โ”‚ name         : String (required)                                     โ”‚
โ”‚ email        : String (required, unique, indexed)                    โ”‚
โ”‚ password     : String (hashed with bcrypt)                           โ”‚
โ”‚ role         : String (enum: 'buyer', 'supplier')                    โ”‚
โ”‚ createdAt    : Date (auto)                                           โ”‚
โ”‚ updatedAt    : Date (auto)                                           โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ AUCTIONS COLLECTION                                                  โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ _id                : ObjectId (PK)                                   โ”‚
โ”‚ name               : String (required)                               โ”‚
โ”‚ createdBy          : ObjectId (FK โ†’ Users)                           โ”‚
โ”‚ bidStartTime       : Date (required)                                 โ”‚
โ”‚ bidCloseTime       : Date (required, mutable - extends)              โ”‚
โ”‚ forcedCloseTime    : Date (required, immutable)                      โ”‚
โ”‚ triggerWindow      : Number (minutes, required)                      โ”‚
โ”‚ extensionDuration  : Number (minutes, required)                      โ”‚
โ”‚ triggerType        : String (enum: 'ANY_BID', 'RANK_CHANGE',        โ”‚
โ”‚                              'L1_CHANGE')                            โ”‚
โ”‚ status             : String (computed: 'UPCOMING', 'ACTIVE',         โ”‚
โ”‚                              'CLOSED', 'FORCE_CLOSED')               โ”‚
โ”‚ currentLowestBid   : Number (updated on each valid bid)              โ”‚
โ”‚ pickupDate         : Date (optional)                                 โ”‚
โ”‚ createdAt          : Date (auto)                                     โ”‚
โ”‚ updatedAt          : Date (auto)                                     โ”‚
โ”‚                                                                       โ”‚
โ”‚ Indexes:                                                             โ”‚
โ”‚   โ€ข bidStartTime, bidCloseTime (range queries)                       โ”‚
โ”‚   โ€ข status (filtering)                                               โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ BIDS COLLECTION                                                      โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ _id                   : ObjectId (PK)                                โ”‚
โ”‚ auctionId             : ObjectId (FK โ†’ Auctions, indexed)            โ”‚
โ”‚ supplierId            : ObjectId (FK โ†’ Users, indexed)               โ”‚
โ”‚ freightCharges        : Number (required)                            โ”‚
โ”‚ originCharges         : Number (required)                            โ”‚
โ”‚ destinationCharges    : Number (required)                            โ”‚
โ”‚ amount                : Number (required, sum of above)              โ”‚
โ”‚ transitTime           : String (e.g., "14 days")                     โ”‚
โ”‚ quoteValidity         : String (e.g., "30 days")                     โ”‚
โ”‚ rank                  : Number (1=L1, 2=L2, 3=L3...)                 โ”‚
โ”‚ createdAt             : Date (auto)                                  โ”‚
โ”‚ updatedAt             : Date (auto)                                  โ”‚
โ”‚                                                                       โ”‚
โ”‚ Indexes:                                                             โ”‚
โ”‚   โ€ข Compound: { auctionId: 1, amount: 1 } (sorting & queries)        โ”‚
โ”‚   โ€ข { supplierId: 1, auctionId: 1 } (supplier bid history)          โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ ACTIVITY_LOGS COLLECTION                                             โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ _id          : ObjectId (PK)                                         โ”‚
โ”‚ auctionId    : ObjectId (FK โ†’ Auctions, indexed)                     โ”‚
โ”‚ type         : String (enum: 'BID', 'EXTENSION')                     โ”‚
โ”‚ message      : String (human-readable log)                           โ”‚
โ”‚ metadata     : Object (additional context)                           โ”‚
โ”‚              {                                                        โ”‚
โ”‚                supplierId: ObjectId (for BID type)                   โ”‚
โ”‚                amount: Number (for BID type)                         โ”‚
โ”‚                reason: String (for EXTENSION type)                   โ”‚
โ”‚                newCloseTime: Date (for EXTENSION type)               โ”‚
โ”‚              }                                                        โ”‚
โ”‚ createdAt    : Date (auto, indexed for sorting)                      โ”‚
โ”‚                                                                       โ”‚
โ”‚ Indexes:                                                             โ”‚
โ”‚   โ€ข { auctionId: 1, createdAt: -1 } (activity timeline)             โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Relationships & Constraints

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”           โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”           โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Users   โ”‚           โ”‚ Auctions  โ”‚           โ”‚ Bids โ”‚
โ”‚  (Auth)  โ”‚           โ”‚   (RFQs)  โ”‚           โ”‚      โ”‚
โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”˜           โ””โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”˜           โ””โ”€โ”€โ”€โ”ฌโ”€โ”€โ”˜
     โ”‚                       โ”‚                     โ”‚
     โ”‚ createdBy             โ”‚ auctionId           โ”‚
     โ”‚ 1:N                   โ”‚ 1:N                 โ”‚
     โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                     โ”‚
                                                   โ”‚
     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
     โ”‚ supplierId
     โ”‚ N:1
     โ”‚
โ”Œโ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Users   โ”‚
โ”‚(Supplier)โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Constraints:
1. Forced Close Time > Bid Close Time > Bid Start Time
2. Bid amount must be < current lowest bid (enforced via transaction)
3. Only buyers can create auctions
4. Only suppliers can place bids
5. No duplicate bid amounts allowed per auction
6. Auction extensions cannot exceed forced close time

๐Ÿ› ๏ธ Tech Stack

Backend

  • Runtime: Node.js (v18+)
  • Framework: Express.js (v5.2+)
  • Database: MongoDB (Atlas Cloud)
  • ODM: Mongoose (v9.5+)
  • Authentication: JWT + bcrypt
  • Real-time: Socket.IO (v4.8+)
  • Environment: dotenv

Frontend

  • Framework: React (v18.3+)
  • Build Tool: Vite
  • State Management: React Hooks (useState, useEffect, useCallback)
  • Routing: Client-side navigation
  • Real-time: Socket.IO Client
  • Icons: Lucide React
  • Styling: Custom CSS with CSS Variables (Dark/Light theme)

DevOps

  • Hosting:
    • Backend: Render
    • Frontend: Vercel
    • Database: MongoDB Atlas
  • Version Control: Git

โš–๏ธ Design Tradeoffs

  • Used MongoDB instead of SQL for flexible schema and faster iteration
  • Used Socket.IO instead of polling for real-time efficiency
  • Used computed auction status instead of storing to avoid stale data
  • Chose transactions to handle race conditions instead of locking mechanisms
  • Prioritized real-time UX over backend simplicity

๐Ÿ“ฆ Installation & Setup

Prerequisites

  • Node.js >= 18.0.0
  • MongoDB Atlas account (or local MongoDB)
  • npm or yarn

Backend Setup

  1. Clone the repository

    git clone <repository-url>
    cd backend
  2. Install dependencies

    npm install
  3. Configure environment variables

    Create .env file in the backend root:

    # MongoDB
    MONGO_URI=mongodb+srv://<username>:<password>@cluster.mongodb.net/trustbid?retryWrites=true&w=majority
    
    # JWT Secret (use a strong random string)
    JWT_SECRET=your_super_secret_jwt_key_here_min_32_chars
    
    # Server Port
    PORT=5000
    
    # Node Environment
    NODE_ENV=development
  4. Start the development server

    npm run dev

    The backend will run on http://localhost:5000

Frontend Setup

  1. Navigate to frontend directory

    cd frontend
  2. Install dependencies

    npm install
  3. Configure environment variables

    Create .env file in the frontend root:

    VITE_API_URL=http://localhost:5000/api

    For production:

    VITE_API_URL=https://your-backend-domain.com/api
  4. Start the development server

    npm run dev

    The frontend will run on http://localhost:5173

Production Build

Backend:

npm start

Frontend:

npm run build
npm run preview

๐Ÿ“ก API Documentation

Authentication Endpoints

Register User

POST /api/auth/register
Content-Type: application/json

{
  "name": "John Doe",
  "email": "john@example.com",
  "password": "securepass123",
  "role": "buyer"  // or "supplier"
}

Response 201:
{
  "message": "User registered",
  "userId": "6512abc..."
}

Login

POST /api/auth/login
Content-Type: application/json

{
  "email": "john@example.com",
  "password": "securepass123"
}

Response 200:
{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "user": {
    "id": "6512abc...",
    "name": "John Doe",
    "role": "buyer"
  }
}

Auction Endpoints

Create Auction (Buyer Only)

POST /api/auctions
Authorization: Bearer <token>
Content-Type: application/json

{
  "name": "Q4 Freight Tender",
  "bidStartTime": "2024-12-01T10:00:00Z",
  "bidCloseTime": "2024-12-01T18:00:00Z",
  "forcedCloseTime": "2024-12-01T20:00:00Z",
  "triggerWindow": 10,
  "extensionDuration": 5,
  "triggerType": "ANY_BID",  // or "RANK_CHANGE", "L1_CHANGE"
  "pickupDate": "2024-12-15T00:00:00Z"
}

Response 201:
{
  "_id": "6512abc...",
  "name": "Q4 Freight Tender",
  "status": "UPCOMING",
  "currentLowestBid": null,
  ...
}

Get All Auctions

GET /api/auctions
Authorization: Bearer <token>

Response 200:
[
  {
    "_id": "6512abc...",
    "name": "Q4 Freight Tender",
    "status": "ACTIVE",
    "currentLowestBid": 12500.50,
    "bidStartTime": "2024-12-01T10:00:00Z",
    "bidCloseTime": "2024-12-01T18:15:00Z",  // Extended
    "forcedCloseTime": "2024-12-01T20:00:00Z",
    ...
  }
]

Get Auction Details

GET /api/auctions/:id
Authorization: Bearer <token>

Response 200:
{
  "auction": {
    "_id": "6512abc...",
    "name": "Q4 Freight Tender",
    "status": "ACTIVE",
    ...
  },
  "bids": [
    {
      "_id": "bid123",
      "supplierId": {
        "name": "Maersk",
        "email": "maersk@example.com"
      },
      "amount": 12500.50,
      "rank": 1,
      "freightCharges": 10000,
      "originCharges": 1500,
      "destinationCharges": 1000.50,
      "transitTime": "14 days",
      "quoteValidity": "30 days",
      "createdAt": "2024-12-01T15:30:00Z"
    }
  ],
  "logs": [...]
}

Delete Auction (Buyer Only)

DELETE /api/auctions/:id
Authorization: Bearer <token>

Response 200:
{
  "message": "Auction deleted"
}

Bid Endpoints

Place Bid (Supplier Only)

POST /api/bids
Authorization: Bearer <token>
Content-Type: application/json

{
  "auctionId": "6512abc...",
  "freight": 10000,
  "origin": 1500,
  "dest": 1000,
  "transitTime": "14 days",
  "quoteValidity": "30 days"
}

Response 201:
{
  "message": "Bid placed successfully",
  "bid": {
    "_id": "bid123",
    "amount": 12500,
    "rank": 1,
    ...
  }
}

// If auction extended:
{
  "message": "Bid placed & Auction extended!",
  "bid": {...}
}

Activity Log Endpoints

Get Auction Logs

GET /api/activity/:auctionId
Authorization: Bearer <token>

Response 200:
[
  {
    "_id": "log123",
    "auctionId": "6512abc...",
    "type": "BID",
    "message": "Supplier Maersk placed bid โ‚น12500",
    "metadata": {
      "supplierId": "supplier123",
      "amount": 12500
    },
    "createdAt": "2024-12-01T15:30:00Z"
  },
  {
    "type": "EXTENSION",
    "message": "Auction extended due to ANY_BID",
    "metadata": {
      "reason": "ANY_BID",
      "newCloseTime": "2024-12-01T18:15:00Z"
    },
    ...
  }
]

WebSocket Events

Client โ†’ Server

// Join auction room for real-time updates
socket.emit('joinAuction', auctionId);

Server โ†’ Client

// New bid placed
socket.on('newBid', (data) => {
  // data: { auctionId, amount, supplierId }
});

// Auction time extended
socket.on('auctionExtended', (data) => {
  // data: { auctionId, newCloseTime, message }
});

๐Ÿ” Advanced Implementation Details

1. Race Condition Prevention with MongoDB Transactions

Problem: Multiple suppliers might submit bids simultaneously, potentially creating invalid states (e.g., two suppliers getting L1 rank).

Solution: MongoDB ACID transactions ensure atomic bid validation and submission.

// bidController.js - Transaction Implementation
const session = await mongoose.startSession();
session.startTransaction();

try {
  // ๐Ÿ”ฅ Re-validate inside transaction with session lock
  const lowestBid = await Bid.findOne({ auctionId })
    .sort({ amount: 1 })
    .session(session);  // Locks the document

  // Validate bid is still valid
  if (lowestBid && amount >= lowestBid.amount) {
    await session.abortTransaction();
    session.endSession();
    return res.status(400).json({
      message: "Bid must be lower than current lowest bid"
    });
  }

  // Create bid within transaction
  const created = await Bid.create([{
    auctionId,
    supplierId: req.user.id,
    amount,
    ...otherFields
  }], { session });

  // Update auction's current lowest bid
  if (auction.currentLowestBid === null || amount < auction.currentLowestBid) {
    auction.currentLowestBid = amount;
    await auction.save({ session });
  }

  // Commit all changes atomically
  await session.commitTransaction();
  session.endSession();
  
} catch (err) {
  await session.abortTransaction();
  session.endSession();
  throw err;
}

Key Benefits:

  • โœ… Atomicity: All operations succeed or all fail
  • โœ… Consistency: No invalid intermediate states
  • โœ… Isolation: Concurrent transactions don't interfere
  • โœ… Durability: Committed changes are permanent

2. Intelligent Extension Logic

Extension Trigger Types:

a) ANY_BID

Extends whenever any bid is received during trigger window.

if (auction.triggerType === "ANY_BID") {
  shouldExtend = true;
}

b) L1_CHANGE

Extends only when the lowest bidder (L1) changes.

if (auction.triggerType === "L1_CHANGE") {
  const oldLowest = auction.currentLowestBid;
  if (oldLowest === null || amount < oldLowest) {
    shouldExtend = true;
  }
}

c) RANK_CHANGE

Extends when any supplier's rank changes (most complex).

if (auction.triggerType === "RANK_CHANGE") {
  // Get best bid from each supplier (excluding current supplier)
  const otherSuppliersBest = await Bid.aggregate([
    {
      $match: {
        auctionId: auction._id,
        supplierId: { $ne: req.user.id }
      }
    },
    {
      $group: {
        _id: "$supplierId",
        minAmount: { $min: "$amount" }
      }
    }
  ]);

  // Check if new bid beats any existing supplier's best
  let didRankChange = false;
  for (let supplier of otherSuppliersBest) {
    if (amount < supplier.minAmount) {
      didRankChange = true;
      break;
    }
  }

  if (didRankChange) {
    shouldExtend = true;
  }
}

Extension Application:

if (shouldExtend) {
  let newCloseTime = new Date(
    bidCloseTime.getTime() + auction.extensionDuration * 60 * 1000
  );

  // Never exceed forced close time
  if (newCloseTime > new Date(auction.forcedCloseTime)) {
    newCloseTime = new Date(auction.forcedCloseTime);
  }

  auction.bidCloseTime = newCloseTime;

  // Log extension event
  await ActivityLog.create({
    auctionId,
    type: "EXTENSION",
    message: `Auction extended due to ${auction.triggerType}`,
    metadata: { reason: auction.triggerType, newCloseTime }
  });
}

3. Real-Time Synchronization

Socket.IO Implementation:

// Server-side broadcast
const io = req.app.get("io");

// Broadcast to all clients in auction room
io.to(auctionId).emit("newBid", {
  auctionId,
  amount,
  supplierId: req.user.id
});

if (shouldExtend) {
  io.to(auctionId).emit("auctionExtended", {
    auctionId,
    newCloseTime: auction.bidCloseTime,
    message: "Auction time extended due to activity!"
  });
}
// Client-side listeners
useEffect(() => {
  const handleNewBid = ({ auctionId }) => {
    fetchDetails(auctionId);  // Refresh bid list
    fetchAuctions();          // Update auction status
  };
  
  const handleExtension = ({ auctionId }) => {
    fetchDetails(auctionId);
    fetchAuctions();
    showToast("Auction extended!");
  };
  
  socket.on("newBid", handleNewBid);
  socket.on("auctionExtended", handleExtension);
  
  return () => {
    socket.off("newBid", handleNewBid);
    socket.off("auctionExtended", handleExtension);
  };
}, []);

4. Automatic Ranking System

Bulk Update for Performance:

// After successful bid placement
const allBids = await Bid.find({ auctionId }).sort({ amount: 1 });

// Prepare bulk operations
const bulkOps = allBids.map((b, i) => ({
  updateOne: {
    filter: { _id: b._id },
    update: { $set: { rank: i + 1 } }
  }
}));

// Execute all rank updates in single operation
if (bulkOps.length > 0) {
  await Bid.bulkWrite(bulkOps);
}

5. Comprehensive Validation

Time Validation (Server-side):

const now = new Date();
const start = new Date(bidStartTime);
const close = new Date(bidCloseTime);
const forced = new Date(forcedCloseTime);

// Start must be future
if (start < now) {
  return res.status(400).json({
    message: "Bid start cannot be in the past"
  });
}

// Close must be after start
if (close <= start) {
  return res.status(400).json({
    message: "Bid close must be after bid start"
  });
}

// Forced must be after close
if (forced <= close) {
  return res.status(400).json({
    message: "Forced close must be after bid close"
  });
}

Bid Amount Validation:

// Must be lower than supplier's previous bid
const lastBid = await Bid.findOne({
  auctionId,
  supplierId: req.user.id
}).sort({ createdAt: -1 });

if (lastBid && amount >= lastBid.amount) {
  return res.status(400).json({
    message: "New bid must be lower than your previous bid"
  });
}

// No duplicate amounts allowed
const tieBid = await Bid.findOne({ auctionId, amount });

if (tieBid) {
  return res.status(400).json({
    message: "A bid with this amount already exists. Please bid lower."
  });
}

6. Dynamic Status Calculation

Computed Status (never stored, always calculated):

function getAuctionStatus(auction) {
  const now = new Date();
  const start = new Date(auction.bidStartTime);
  const close = new Date(auction.bidCloseTime);
  const forced = new Date(auction.forcedCloseTime);

  if (now < start) return "UPCOMING";
  if (now >= forced) return "FORCE_CLOSED";
  if (now >= close) return "CLOSED";
  return "ACTIVE";
}

Benefits:

  • โœ… Always accurate (no stale data)
  • โœ… No background jobs needed
  • โœ… Works across time zones
  • โœ… Handles server/client time drift

๐Ÿ’ผ Business Logic & Auction Mechanics

Auction Lifecycle

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  UPCOMING   โ”‚  โ† Auction created, waiting for bidStartTime
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜
       โ”‚ bidStartTime reached
       โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚   ACTIVE    โ”‚  โ† Suppliers can place bids
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜    Extensions possible within trigger window
       โ”‚
       โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
       โ”‚ โ”‚ Extension Triggers (if applicable):      โ”‚
       โ”‚ โ”‚ โ€ข ANY_BID: Any bid in last X minutes     โ”‚
       โ”‚ โ”‚ โ€ข RANK_CHANGE: Any rank shift in last X  โ”‚
       โ”‚ โ”‚ โ€ข L1_CHANGE: L1 position change in last Xโ”‚
       โ”‚ โ”‚                                          โ”‚
       โ”‚ โ”‚ Extension: bidCloseTime += Y minutes     โ”‚
       โ”‚ โ”‚ (max: forcedCloseTime)                  โ”‚
       โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
       โ”‚
       โ”‚ bidCloseTime reached (no more extensions)
       โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚   CLOSED    โ”‚  โ† No more bids accepted
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜    Winner determined (L1 supplier)
       โ”‚
       โ”‚ forcedCloseTime reached
       โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚FORCE_CLOSED โ”‚  โ† Auction definitively ended
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Extension Example Scenario

Configuration:

  • Bid Close: 6:00 PM
  • Forced Close: 8:00 PM
  • Trigger Window (X): 10 minutes
  • Extension Duration (Y): 5 minutes
  • Trigger Type: L1_CHANGE

Timeline:

5:50 PM  โ”‚ [Trigger Window Begins]
         โ”‚
5:52 PM  โ”‚ Supplier A bids $12,000 โ†’ Becomes L1
         โ”‚ โœ“ Extension triggered (L1 changed)
         โ”‚ New close: 6:05 PM
         โ”‚
5:58 PM  โ”‚ Supplier B bids $11,800 โ†’ Becomes L1
         โ”‚ โœ“ Extension triggered (L1 changed)
         โ”‚ New close: 6:10 PM
         โ”‚
6:02 PM  โ”‚ [New Trigger Window: 6:00 PM - 6:10 PM]
         โ”‚
6:08 PM  โ”‚ Supplier C bids $11,500 โ†’ Becomes L1
         โ”‚ โœ“ Extension triggered (L1 changed)
         โ”‚ New close: 6:15 PM
         โ”‚
6:11 PM  โ”‚ Supplier A bids $11,200 โ†’ Becomes L1
         โ”‚ โœ“ Extension triggered (L1 changed)
         โ”‚ New close: 6:20 PM
         โ”‚
6:15 PM  โ”‚ [Trigger Window: 6:10 PM - 6:20 PM]
         โ”‚ No more bids in trigger window
         โ”‚
6:20 PM  โ”‚ โน Auction CLOSED
         โ”‚ Winner: Supplier A at $11,200
         โ”‚
8:00 PM  โ”‚ โน Forced Close Time (not reached because auction
         โ”‚    naturally closed at 6:20 PM)

Ranking System

L1, L2, L3 Badge Logic:

// Rankings are calculated after each bid
// Sorted by amount (lowest = L1)

Supplier A: $12,000 โ†’ Rank 2 (L2)
Supplier B: $11,500 โ†’ Rank 1 (L1) โญ
Supplier C: $13,200 โ†’ Rank 3 (L3)
Supplier D: $15,000 โ†’ Rank 4 (L4+)

Visual Representation:

  • L1 (Gold): Lowest bid, winning position
  • L2 (Silver): Second-lowest bid
  • L3 (Bronze): Third-lowest bid
  • L4+ (Gray): Other positions

๐Ÿ”‘ Demo Credentials

Buyer Account

Email: buyer@test.com
Password: buyer123

Capabilities:

  • โœ… Create new RFQ auctions
  • โœ… View all auctions and bids
  • โœ… Delete own auctions
  • โœ… Monitor real-time bidding activity
  • โŒ Cannot place bids

Supplier Account 1

Email: supplier1@test.com
Password: supplier123

Supplier Account 2

Email: supplier2@test.com
Password: supplier123

Capabilities:

  • โœ… View active auctions
  • โœ… Place competitive bids
  • โœ… See live rankings (L1, L2, L3)
  • โœ… Receive real-time extension notifications
  • โŒ Cannot create or delete auctions

๐Ÿ“ Project Structure

trustbid/
โ”‚
โ”œโ”€โ”€ backend/
โ”‚   โ”œโ”€โ”€ src/
โ”‚   โ”‚   โ”œโ”€โ”€ config/
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ db.js                    # MongoDB connection
โ”‚   โ”‚   โ”‚
โ”‚   โ”‚   โ”œโ”€โ”€ models/
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ User.js                  # User schema (buyer/supplier)
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ Auction.js               # Auction/RFQ schema
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ Bid.js                   # Bid schema with ranking
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ ActivityLog.js           # Activity log schema
โ”‚   โ”‚   โ”‚
โ”‚   โ”‚   โ”œโ”€โ”€ controllers/
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ authController.js        # Register, login
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ auctionController.js     # CRUD auctions, get details
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ bidController.js         # Place bid (with extensions)
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ activityController.js    # Get activity logs
โ”‚   โ”‚   โ”‚
โ”‚   โ”‚   โ”œโ”€โ”€ middlewares/
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ authMiddleware.js        # JWT auth & role authorization
โ”‚   โ”‚   โ”‚
โ”‚   โ”‚   โ”œโ”€โ”€ routes/
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ authRoutes.js            # /api/auth/*
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ auctionRoutes.js         # /api/auctions/*
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ bidRoutes.js             # /api/bids/*
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ activityRoutes.js        # /api/activity/*
โ”‚   โ”‚   โ”‚
โ”‚   โ”‚   โ””โ”€โ”€ utils/
โ”‚   โ”‚       โ””โ”€โ”€ getAuctionStatus.js      # Status calculation helper
โ”‚   โ”‚
โ”‚   โ”œโ”€โ”€ server.js                        # Express + Socket.IO setup
โ”‚   โ”œโ”€โ”€ package.json
โ”‚   โ””โ”€โ”€ .env                             # Environment variables
โ”‚
โ”œโ”€โ”€ frontend/
โ”‚   โ”œโ”€โ”€ src/
โ”‚   โ”‚   โ”œโ”€โ”€ components/
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ layout/
โ”‚   โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ Navbar.jsx           # Navigation bar
โ”‚   โ”‚   โ”‚   โ”‚
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ ui/
โ”‚   โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ Badge.jsx            # Status badges
โ”‚   โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ Toast.jsx            # Toast notifications
โ”‚   โ”‚   โ”‚   โ”‚
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ modals/
โ”‚   โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ BidModal.jsx         # Bid submission form
โ”‚   โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ DeleteModal.jsx      # Delete confirmation
โ”‚   โ”‚   โ”‚   โ”‚
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ views/
โ”‚   โ”‚   โ”‚       โ”œโ”€โ”€ AuthView.jsx         # Login/Register
โ”‚   โ”‚   โ”‚       โ”œโ”€โ”€ HeroView.jsx         # Landing page
โ”‚   โ”‚   โ”‚       โ”œโ”€โ”€ CreateView.jsx       # Create RFQ form
โ”‚   โ”‚   โ”‚       โ”œโ”€โ”€ ListingView.jsx      # Auction list
โ”‚   โ”‚   โ”‚       โ””โ”€โ”€ DetailView.jsx       # Auction details + live bids
โ”‚   โ”‚   โ”‚
โ”‚   โ”‚   โ”œโ”€โ”€ hooks/
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ useAuction.js            # Main data hook (API + Socket)
โ”‚   โ”‚   โ”‚
โ”‚   โ”‚   โ”œโ”€โ”€ utils/
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ helpers.js               # Format functions, status calc
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ socket.js                # Socket.IO client setup
โ”‚   โ”‚   โ”‚
โ”‚   โ”‚   โ”œโ”€โ”€ App.jsx                      # Main app component
โ”‚   โ”‚   โ”œโ”€โ”€ main.jsx                     # React entry point
โ”‚   โ”‚   โ””โ”€โ”€ index.css                    # Global styles + CSS variables
โ”‚   โ”‚
โ”‚   โ”œโ”€โ”€ package.json
โ”‚   โ””โ”€โ”€ .env                             # VITE_API_URL
โ”‚
โ””โ”€โ”€ README.md                            # This file

๐ŸŽ“ Key Learning Outcomes

Technical Skills Demonstrated

  1. Full-Stack Development

    • RESTful API design with Express.js
    • React hooks and modern state management
    • Real-time bidirectional communication
  2. Database Design

    • Schema modeling for complex relationships
    • Transaction handling for data integrity
    • Index optimization for query performance
  3. Real-Time Systems

    • WebSocket integration with Socket.IO
    • Event-driven architecture
    • Optimistic UI updates
  4. Security Best Practices

    • JWT authentication flow
    • Role-based access control (RBAC)
    • Password hashing with bcrypt
    • Input validation and sanitization
  5. Business Logic Implementation

    • Complex time-based calculations
    • Dynamic auction extensions
    • Concurrent request handling
    • Ranking algorithms
  6. UI/UX Design

    • Responsive design principles
    • Component-based architecture
    • Theme system with CSS variables
    • Accessibility considerations

๐Ÿ“„ License

This project is licensed under the MIT License.


๐Ÿ‘จโ€๐Ÿ’ป Developer

Anurag Dubey


๐Ÿ™ Acknowledgments

  • Go Comet for the assignment opportunity
  • MongoDB for the excellent database documentation
  • Socket.IO for real-time communication capabilities
  • React Team for the amazing frontend framework
  • Lucide Icons for the beautiful icon set

โญ Star this repository if you found it helpful!

Built with โค๏ธ for transparent and fair procurement processes

About

๐ŸŽฏReal-time British Auction RFQ system built with React, Node.js, Express, and MongoDB. Features live bidding via Socket.io, anti-sniping time extensions, and race condition prevention.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

โšก