LLD Hub
lldcommand-patternobserver

How to Design an Inventory Management System | LLD Guide

Design a warehouse inventory system with stock reservation, audit trail, multi-warehouse transfers, and auto reorder. Asked at Amazon, Flipkart SDE interviews.

18 April 2025·8 min read

Practice this problem

Inventory Management System — get AI-scored feedback on your solution

Solve it →

The Inventory Management System is a common LLD problem at Amazon, Flipkart, and e-commerce companies. It tests the Command pattern for auditable operations, Observer for reorder triggers, and careful handling of stock reservation to prevent overselling.

Core Entities

  • Product — SKU, name, category
  • Warehouse — location, stock per product
  • Stock — warehouse + product + available + reserved quantities
  • Reservation — temporary hold on stock for an order
  • AuditLog — immutable record of every stock change
  • ReorderConfig — threshold and reorder quantity per product

Stock Reservation Flow

class StockService {
  // Step 1: Reserve on order placement
  reserve(productId: string, warehouseId: string, qty: number, orderId: string): Reservation {
    const stock = this.stockRepo.get(productId, warehouseId);
    if (stock.available < qty) throw new Error("Insufficient stock");
    stock.available -= qty;
    stock.reserved += qty;
    const reservation = new Reservation(orderId, productId, qty, Date.now() + 30*60*1000);
    this.reservationRepo.save(reservation);
    this.auditLog.record("RESERVE", productId, qty, orderId);
    return reservation;
  }

  // Step 2a: Commit when order confirmed
  commit(reservationId: string) {
    const res = this.reservationRepo.get(reservationId);
    const stock = this.stockRepo.get(res.productId, res.warehouseId);
    stock.reserved -= res.qty; // Reservation → actual deduction
    this.auditLog.record("COMMIT", res.productId, res.qty, res.orderId);
    this.checkReorder(stock);
  }

  // Step 2b: Release when order cancelled
  release(reservationId: string) {
    const res = this.reservationRepo.get(reservationId);
    const stock = this.stockRepo.get(res.productId, res.warehouseId);
    stock.available += res.qty;
    stock.reserved -= res.qty;
    this.auditLog.record("RELEASE", res.productId, res.qty, res.orderId);
  }
}

Observer for Auto-Reorder

private checkReorder(stock: Stock) {
  const config = this.reorderConfig.get(stock.productId);
  if (config && stock.available <= config.reorderThreshold) {
    const qty = config.maxStock - stock.available;
    this.eventBus.publish(new LowStockEvent(stock.productId, stock.warehouseId, qty));
  }
}

class ProcurementService implements EventHandler<LowStockEvent> {
  handle(event: LowStockEvent) {
    this.purchaseOrderService.createOrder(event.productId, event.qty);
    this.notifyTeam(`Low stock alert: ${event.productId}`);
  }
}

Command Pattern for Operations

interface InventoryCommand { execute(): void; undo(): void; }
class ReserveCommand implements InventoryCommand {
  execute() { this.stockService.reserve(this.productId, this.warehouseId, this.qty, this.orderId); }
  undo()    { this.stockService.release(this.reservationId); }
}

Ready to practice?

Submit your solution and get AI-scored feedback on OOP, SOLID principles, design patterns, and code quality.

Solve Inventory Management System