Files
vaishnavi-ecommerce-backend/Inventory.md
2026-03-10 12:43:27 +05:30

7.2 KiB

📦 Complete Inventory Management System - Implementation Guide

What You Get

Auto Stock Reduction - Stock reduces when order delivered Low Stock Alerts - Dashboard shows products needing restock
Real Top Sellers - Based on actual sales, not fake data Inventory Logs - Track every stock change Stock Status - OUT_OF_STOCK, CRITICAL, LOW, IN_STOCK


🚀 Setup (5 Steps)

Step 1: Update Prisma Schema

Add this to your schema.prisma:

model InventoryLog {
  id        String   @id @default(cuid())
  
  productId   String
  productName String
  
  type            InventoryLogType
  quantityChange  Int
  previousStock   Int
  newStock        Int
  
  orderId     String?
  adjustedBy  String?
  notes       String?
  
  createdAt DateTime @default(now())
  
  @@index([productId])
  @@index([orderId])
  @@index([type])
  @@map("inventory_logs")
}

enum InventoryLogType {
  SOLD
  RESTOCK
  ADJUSTMENT
  RETURN
  DAMAGED
}

Step 2: Run Migration

npx prisma migrate dev --name add_inventory_logs

Step 3: Add Inventory Service

Create src/services/inventoryService.js with the provided code.

Step 4: Update Order Controller

Replace your order controller with the version that includes auto stock reduction.

Step 5: Update Dashboard Controller

Replace dashboard controller to show real top sellers + low stock alerts.


📊 Dashboard API Response

{
  "data": {
    "totalUsers": 150,
    "totalOrders": 450,
    "totalProducts": 89,
    "totalRevenue": 125000,
    
    "inventory": {
      "totalProducts": 89,
      "outOfStock": 5,
      "criticalStock": 8,
      "lowStock": 12,
      "inStock": 64
    },
    
    "topProducts": [
      {
        "_id": "prod123",
        "name": "Rare Rabbit",
        "basePrice": 2500,
        "totalSold": 45,
        "totalOrders": 32,
        "revenue": 112500,
        "stock": 12,
        "stockStatus": "LOW",
        "displayImage": "https://..."
      }
    ],
    
    "lowStockProducts": [
      {
        "_id": "prod456",
        "name": "Product Name",
        "stock": 3,
        "status": "CRITICAL",
        "basePrice": 1500,
        "displayImage": "https://..."
      }
    ]
  }
}

⚙️ How Auto Stock Reduction Works

When Admin Updates Order to DELIVERED:

1. Admin: PUT /api/admin/orders/:id/status
   Body: { "status": "DELIVERED" }

2. Order Controller:
   ✅ Updates order status
   ✅ Creates status history
   ✅ Calls reduceStockOnDelivery()

3. Inventory Service:
   ✅ Gets order items
   ✅ For each item:
      - Get product from MongoDB
      - Calculate: newStock = currentStock - quantity
      - Update product.stock in MongoDB
      - Create inventory log in PostgreSQL
   
4. Response:
   {
     "success": true,
     "message": "Order status updated",
     "stockReduction": [
       {
         "productName": "Rare Rabbit",
         "reduced": 1,
         "previousStock": 15,
         "newStock": 14
       }
     ]
   }

📋 Inventory Log Example

Every stock change creates a log:

{
  "id": "log123",
  "productId": "prod456",
  "productName": "Rare Rabbit",
  "type": "SOLD",
  "quantityChange": -1,
  "previousStock": 15,
  "newStock": 14,
  "orderId": "order789",
  "notes": "Order ORD1234567 delivered",
  "createdAt": "2026-02-11T14:30:00.000Z"
}

🎯 Stock Status Logic

stock === 0      OUT_OF_STOCK (Red)
stock <= 5       CRITICAL (Orange)
stock <= 10      LOW (Yellow)
stock > 10       IN_STOCK (Green)

📊 Top Selling Products Logic

OLD (Wrong):

// ❌ Used purchaseCount from MongoDB (never updated)
Product.find().sort({ purchaseCount: -1 })

NEW (Correct):

// ✅ Query actual order data from PostgreSQL
SELECT productId, SUM(quantity), COUNT(*)
FROM order_items
GROUP BY productId
ORDER BY SUM(quantity) DESC

// ✅ Join with MongoDB for product details
// ✅ Add stock info
// ✅ Calculate revenue

🎨 Frontend Display

Dashboard - Top Sellers

{topProducts.map(product => (
  <div key={product._id} className="flex items-center gap-4 p-4 bg-white rounded-lg shadow">
    <img src={product.displayImage} className="w-16 h-16 rounded" />
    <div className="flex-1">
      <h3 className="font-bold">{product.name}</h3>
      <div className="flex items-center gap-4 text-sm text-gray-600">
        <span>Sold: {product.totalSold}</span>
        <span>Revenue: {product.revenue.toLocaleString()}</span>
        <span className={`px-2 py-1 rounded text-xs ${
          product.stockStatus === 'OUT_OF_STOCK' ? 'bg-red-100 text-red-800' :
          product.stockStatus === 'CRITICAL' ? 'bg-orange-100 text-orange-800' :
          product.stockStatus === 'LOW' ? 'bg-yellow-100 text-yellow-800' :
          'bg-green-100 text-green-800'
        }`}>
          {product.stock} in stock
        </span>
      </div>
    </div>
  </div>
))}

Dashboard - Low Stock Alerts

{lowStockProducts.length > 0 && (
  <div className="bg-orange-50 border border-orange-200 rounded-lg p-6">
    <h3 className="text-lg font-bold text-orange-900 mb-4">
      ⚠️ Low Stock Alert ({lowStockProducts.length})
    </h3>
    <div className="space-y-3">
      {lowStockProducts.map(product => (
        <div key={product._id} className="flex items-center justify-between p-3 bg-white rounded">
          <div className="flex items-center gap-3">
            <img src={product.displayImage} className="w-12 h-12 rounded" />
            <div>
              <p className="font-semibold">{product.name}</p>
              <p className="text-sm text-gray-600">
                {product.stock === 0 ? 'Out of Stock' : `Only ${product.stock} left`}
              </p>
            </div>
          </div>
          <button className="px-4 py-2 bg-orange-600 text-white rounded">
            Restock
          </button>
        </div>
      ))}
    </div>
  </div>
)}

🔧 Manual Stock Adjustment (Future)

// POST /api/admin/inventory/adjust
{
  "productId": "prod123",
  "quantity": 50,
  "type": "ADD",      // ADD, REMOVE, SET
  "notes": "Received new shipment"
}

📈 Benefits

  1. Accurate Inventory - Always know real stock levels
  2. Prevent Overselling - Stock reduces on delivery
  3. Early Warnings - Low stock alerts
  4. Better Planning - See what's selling
  5. Full Audit Trail - Every change logged
  6. Automated - No manual work needed

Testing Checklist

  • Prisma migration ran successfully
  • Place test order
  • Mark order as DELIVERED
  • Check product stock reduced
  • Check inventory log created
  • Dashboard shows correct stock
  • Low stock products appear
  • Top sellers show real data

🎯 What Happens

Before (Old System):

Order Delivered → Nothing happens
Stock: Always same (never changes)
Top Products: Fake/old data
Dashboard: No inventory info

After (New System):

Order Delivered → Auto stock reduction
Stock: Real-time accurate
Top Products: Based on actual sales
Dashboard: Full inventory overview
Alerts: Low stock warnings
Logs: Complete audit trail

Your inventory system is now production-ready! 📦