DEV Community

Cover image for Custom ERP में Real-Time Inventory Synchronization: Node.js और TypeScript
WebVibez Softdev
WebVibez Softdev

Posted on Originally published at webvibez.com

Custom ERP में Real-Time Inventory Synchronization: Node.js और TypeScript

आज के आधुनिक omnichannel commerce में, inventory की विसंगतियों (discrepancies) के कारण व्यवसायों को सालाना अरबों का नुकसान होता है—खोई हुई बिक्री, प्रशासनिक ओवरहेड (administrative overhead), और ग्राहकों के टूटते भरोसे के रूप में। जब कई डिजिटल स्टोरफ्रंट, ऑफलाइन POS टर्मिनल और थर्ड-पार्टी लॉजिस्टिक्स (3PL) प्रदाता एक ही फिजिकल इन्वेंट्री (shared physical inventory) से स्टॉक लेते हैं, तो कुछ सेकंड का विलंब (latency) भी ओवर-एलोकेशन (over-allocation) या डबल-सेलिंग (double-selling) का कारण बन सकता है।

एक वास्तविक real time inventory synchronization erp कार्यक्षमता हासिल करना अब कोई वैकल्पिक अपग्रेड नहीं है; यह एक बुनियादी परिचालन आवश्यकता (operational requirement) बन चुका है। एंटरप्राइज़ इंजीनियरिंग लीडर्स के लिए, एक मजबूत सिंक्रोनाइज़ेशन पाइपलाइन बनाने के लिए पारंपरिक बैच प्रोसेसिंग (batch processing) से आगे बढ़कर एक आधुनिक, अत्यधिक समवर्ती (highly concurrent) और लचीले (resilient) event-driven architecture को अपनाने की आवश्यकता है।

यह आर्किटेक्चरल गाइड यह बताती है कि Node.js और TypeScript का उपयोग करके custom erp inventory management के लिए एक हाई-परफॉर्मेंस सिस्टम को कैसे डिज़ाइन और बिल्ड किया जाए, जिसमें रेस कंडीशंस (race conditions) को हल करने, डेटाबेस कंकुरेंसी (database concurrency) को ऑप्टिमाइज़ करने और सभी चैनलों पर सब-सेकंड अपडेट (sub-second updates) सुनिश्चित करने पर ध्यान केंद्रित किया गया है।


Inventory Synchronization में मुख्य आर्किटेक्चरल चुनौतियाँ

कोड की एक भी लाइन लिखने से पहले, सॉफ़्टवेयर आर्किटेक्ट्स को इन्वेंट्री मैनेजमेंट में निहित बुनियादी डिस्ट्रीब्यूटेड सिस्टम्स (distributed systems) की समस्याओं का समाधान करना चाहिए।

1. Database Concurrency और Race Conditions

जब दो ग्राहक एक ही समय में किसी हाई-डिमांड SKU की अंतिम यूनिट खरीदने का प्रयास करते हैं, तो एक क्लासिक "Read-Modify-Write" रेस कंडीशन उत्पन्न होती है। यदि दोनों एप्लिकेशन थ्रेड्स स्टॉक लेवल 1 रीड करते हैं, तो दोनों पेमेंट को ऑथराइज़ करने और स्टॉक को घटाकर 0 करने का प्रयास करेंगे, जिसके परिणामस्वरूप नेगेटिव इन्वेंट्री स्टेट (negative inventory state) या अनफुलफिल्ड ऑर्डर (unfulfilled order) की स्थिति बन जाएगी।

2. Network Latency और Third-Party API Limits

चेकआउट फ्लो के दौरान बाहरी मार्केटप्लेस (जैसे Amazon या Shopify) पर सीधे सिंक्रोनस रूप से इन्वेंट्री अपडेट सिंक करने से अस्वीकार्य लेटेंसी (latency) पैदा होती है। बाहरी APIs सख्त रेट लिमिट्स (rate limits) और बीच-बीच में डाउनटाइम के अधीन होते हैं, जिसके लिए एक डिकपल्ड (decoupled), एसिंक्रोनस कतार-आधारित (asynchronous queue-based) आर्किटेक्चर की आवश्यकता होती है।

3. Data Consistency Across Distributed Databases

अक्सर, ERP ट्रांजैक्शनल इंटीग्रिटी के लिए एक प्राइमरी रिलेशनल डेटाबेस (जैसे, PostgreSQL) का उपयोग करता है, जबकि तेज़ कैटलॉग रीड्स के लिए एक विशेष सर्च इंडेक्स (जैसे, Elasticsearch) या एक redis caching layer का उपयोग करता है। राइट परफॉर्मेंस (write performance) से समझौता किए बिना इन सिस्टम्स को सिंक में रखने के लिए एक एसिंक्रोनस आउटबॉक्स पैटर्न (outbox pattern) या चेंज डेटा कैप्चर (CDC) की आवश्यकता होती है।

इन बाधाओं को दूर करने के लिए, इंजीनियरिंग टीमें कस्टमाइज्ड सॉल्यूशंस की ओर रुख कर रही हैं। Custom Software Development के लिए एक विशेषज्ञ टीम के साथ साझेदारी यह सुनिश्चित करती है कि इन जटिल ट्रांजैक्शनल पाइपलाइनों को आपके अनूठे परिचालन वर्कफ़्लो के अनुसार इंजीनियर किया जाए।


Node.js और TypeScript के फायदे

सही टेक्नोलॉजी स्टैक का चयन आपके scalable inventory automation software की स्केलेबिलिटी और मेंटेनबिलिटी को निर्धारित करता है। एक typescript erp development guide के साथ संयुक्त nodejs inventory sync architecture कई महत्वपूर्ण इंजीनियरिंग लाभ प्रदान करता है:

  • Non-Blocking I/O: Node.js का इवेंट लूप हाई-ओवरहेड ओएस थ्रेड्स (OS threads) बनाए बिना हजारों समवर्ती (concurrent) I/O ऑपरेशन्स (जैसे डेटाबेस क्वेरी, कैश लुकअप और API रिक्वेस्ट) को संभालता है।
  • Type Safety in Complex Domains: TypeScript यह सुनिश्चित करता है कि इन्वेंट्री स्टेट्स, SKU फॉर्मेट्स और वेयरहाउस लोकेशन्स स्ट्रिक्टली टाइप्ड (strictly typed) हों, जिससे स्टॉक कैलकुलेशन के दौरान होने वाली महंगी रनटाइम गलतियों से बचा जा सके।
  • Rich Ecosystem: Node.js इकोसिस्टम मैसेज क्यूइंग (BullMQ, amqplib), डेटाबेस एब्स्ट्रैक्शन (Prisma, TypeORM), और कैशिंग (ioredis) के लिए मजबूत, प्रोडक्शन-रेडी लाइब्रेरी प्रदान करता है।

Architectural Blueprint: Event-Driven Inventory Sync

सब-सेकंड सिंक्रोनाइज़ेशन प्राप्त करने के लिए, आर्किटेक्चर को कोर ट्रांजैक्शनल डेटाबेस को बाहरी सिंक्रोनाइज़ेशन वर्कर्स से डिकपल (decouple) करना चाहिए। नीचे रियल-टाइम अपडेट के लिए डिज़ाइन की गई एक इवेंट-ड्रिवन टोपोलॉजी का हाई-लेवल ओवरव्यू दिया गया है:

[ Client Checkout ] 
       │
       ▼
[ API Gateway (Node.js/TS) ] ──(Acquires Redis Lock)──► [ Redis Cache (Stock Level) ]
       │                                                        │
       ▼ (Write)                                                ▼ (If Lock Acquired)
[ PostgreSQL DB (Primary) ] ───► [ Outbox Table ] ───► [ Message Broker (RabbitMQ/Kafka) ]
                                                                │
                                        ┌───────────────────────┴───────────────────────┐
                                        ▼                                               ▼
                          [ Shopify Sync Worker ]                          [ Amazon Sync Worker ]
Enter fullscreen mode Exit fullscreen mode

1. Redis Caching Layer और Distributed Locking

आपके प्राइमरी ट्रांजैक्शनल डेटाबेस पर कंकुरेंट डेटाबेस राइट्स के कारण होने वाले बॉटलनेक को रोकने के लिए, सभी तत्काल इन्वेंट्री चेक और डिक्रीमेंट्स एक redis caching layer के विरुद्ध किए जाते हैं।

Distributed locking (Redlock एल्गोरिदम के माध्यम से) का उपयोग करके, हम यह सुनिश्चित करते हैं कि केवल एक वर्कर ही एक समय में किसी विशिष्ट SKU के स्टॉक को संशोधित कर सके। एक बार जब तेज़ मेमोरी ऑपरेशन पूरा हो जाता है, तो परिवर्तन को एसिंक्रोनस रूप से प्राइमरी रिलेशनल डेटाबेस में लिख दिया जाता है।

2. Message Queues के साथ Event-Driven Architecture

बाहरी APIs पर सिंक्रोनस रूप से अपडेट भेजने के बजाय, कोर ERP एक मैसेज ब्रोकर (जैसे RabbitMQ या Apache Kafka) पर एक InventoryUpdated इवेंट पब्लिश करता है। स्वतंत्र कंज्यूमर माइक्रोसर्विसेज इन इवेंट्स को सब्सक्राइब करती हैं और चैनल-विशिष्ट API पेलोड, रिट्राइज़ (retries) और रेट-लिमिटिंग नियमों को संभालती हैं। यह डिकपल्ड दृष्टिकोण काफी हद तक वैसा ही है जैसा हम अपने गाइड Architecting a Custom Workflow Automation Engine for Scale में जटिल बैकग्राउंड टास्क को संभालने के लिए उपयोग करते हैं।


Synchronization Strategy Tradeoffs

आपके ERP, वेयरहाउस मैनेजमेंट सिस्टम (WMS), और फ्रंटएंड एप्लिकेशन्स के बीच सही कम्युनिकेशन प्रोटोकॉल का चयन करना एक महत्वपूर्ण डिज़ाइन निर्णय है।

रणनीति (Strategy) लेटेंसी (Latency) नेटवर्क ओवरहेड (Network Overhead) इम्प्लीमेंटेशन जटिलता (Complexity) सर्वश्रेष्ठ उपयोग का मामला (Best Use Case)
HTTP Polling उच्च (5s - 1m) उच्च (Constant headers) कम बिना वेबहुक सपोर्ट वाले लेगेसी वेयरहाउस इंटीग्रेशन।
WebSockets Stock Update अत्यधिक कम (<50ms) कम (Persistent TCP) मध्यम रियल-टाइम आंतरिक एडमिन डैशबोर्ड और सक्रिय B2B ग्राहक पोर्टल।
Event-Driven (Broker) बहुत कम (<100ms) न्यूनतम (Pub/Sub) उच्च आंतरिक माइक्रोसर्विस कम्युनिकेशन और बड़े पैमाने पर चैनल सिंकिंग।
Change Data Capture (CDC) कम (<500ms) न्यूनतम (DB Log parsing) अत्यधिक उच्च ट्रांजैक्शनल डेटाबेस लॉग से सीधे रीड-ओनली सर्च रेप्लिकास को सिंक करना।

Implementation: TypeScript Inventory Lock और Decrement

नीचे एक प्रोडक्शन-ग्रेड TypeScript इम्प्लीमेंटेशन दिया गया है जो दर्शाता है कि database concurrency समस्याओं को रोकने के लिए डिस्ट्रीब्यूटेड लॉकिंग और एटॉमिक स्टॉक डिक्रीमेंट्स के लिए Redis का उपयोग कैसे किया जाए।

import Redis from 'ioredis';
import { PrismaClient } from '@prisma/client';

const redis = new Redis(process.env.REDIS_URL || 'redis://localhost:6379');
const prisma = new PrismaClient();

interface InventoryAdjustment {
  sku: string;
  quantity: number;
  warehouseId: string;
}

export async function secureInventoryDecrement(adjustment: InventoryAdjustment): Promise<boolean> {
  const lockKey = `lock:inventory:${adjustment.warehouseId}:${adjustment.sku}`;
  const stockKey = `inventory:${adjustment.warehouseId}:${adjustment.sku}`;
  const lockTimeout = 5000; // 5 seconds
  const acquireTimeout = 2000; // 2 seconds

  const startTime = Date.now();

  // 1. Attempt to acquire Distributed Lock
  while (Date.now() - startTime < acquireTimeout) {
    const locked = await redis.set(lockKey, 'locked', 'NX', 'PX', lockTimeout);
    if (locked === 'OK') {
      try {
        // 2. Perform Atomic Cache Check & Decrement
        const currentStockStr = await redis.get(stockKey);
        const currentStock = currentStockStr ? parseInt(currentStockStr, 10) : null;

        if (currentStock === null || currentStock < adjustment.quantity) {
          throw new Error(`Insufficient stock in cache for SKU: ${adjustment.sku}`);
        }

        // Atomic decrement in Redis cache
        const remainingStock = await redis.decrby(stockKey, adjustment.quantity);

        // 3. Persist to Relational DB asynchronously via Outbox pattern
        await prisma.$transaction(async (tx) => {
          await tx.inventory.update({
            where: { sku_warehouseId: { sku: adjustment.sku, warehouseId: adjustment.warehouseId } },
            data: { quantity: { decrement: adjustment.quantity } }
          });

          // Create outbox event for external channel sync workers
          await tx.outboxEvent.create({
            data: { 
              eventType: 'INVENTORY_UPDATED',
              payload: JSON.stringify({ sku: adjustment.sku, remainingStock }),
              status: 'PENDING'
            }
          });
        });

        return true; 
      } finally {
        // 4. Release Lock safely
        await redis.del(lockKey);
      }
    }
    // Wait 50ms before retrying lock acquisition
    await new Promise((resolve) => setTimeout(resolve, 50));
  }

  throw new Error(`Lock acquisition timeout for SKU: ${adjustment.sku}`);
}
Enter fullscreen mode Exit fullscreen mode

Code Deep-Dive:

  1. Distributed Lock (NX, PX): हम Redis के set कमांड का उपयोग NX (केवल तभी सेट करें जब मौजूद न हो) और PX (मिलीसेकंड में समाप्त हो) के साथ करते हैं ताकि सर्वर क्रैश होने पर बिना किसी डेडलॉक के म्यूचुअल एक्सक्लूजन सुनिश्चित किया जा सके।
  2. Double-Check State: भारी SQL डिस्क ट्रांजैक्शन निष्पादित करने से पहले अल्ट्रा-फास्ट मेमोरी कैश में स्टॉक लेवल को सत्यापित किया जाता है।
  3. Transactional Outbox Pattern: डेटाबेस अपडेट और आउटबॉक्स इवेंट क्रिएशन को एक ही ACID ट्रांजैक्शन के भीतर निष्पादित किया जाता है। यह गारंटी देता है कि यदि डेटाबेस राइट विफल हो जाता है, तो हम कभी भी सिंक्रोनाइज़ेशन इवेंट पब्लिश नहीं करेंगे।

Synchronization Engine को स्केल करना

जैसे-जैसे ट्रांजैक्शन की मात्रा बढ़ती है, आपके scalable inventory automation software को हॉरिजॉन्टली स्केल होना चाहिए। इसे निम्नलिखित तरीकों से हासिल किया जाता है:

  • Consumer Group Partitioning: Kafka जैसे मैसेज ब्रोकर्स का उपयोग करते समय, अपनी इन्वेंट्री कतारों (queues) को SKU या प्रोडक्ट आईडी द्वारा विभाजित (partition) करें। यह सुनिश्चित करता है कि किसी विशिष्ट SKU के अपडेट हमेशा एक ही वर्कर इंस्टेंस द्वारा क्रम में संसाधित किए जाएं, जिससे आउट-ऑफ-ऑर्डर रेस कंडीशंस समाप्त हो जाती हैं।
  • Debouncing & Batching: Shopify पर हर एक स्टॉक बदलाव के लिए API रिक्वेस्ट भेजने के बजाय, 2 से 3 सेकंड के विंडो में अपडेट्स को बैच करें। यदि स्टॉक एक सेकंड के भीतर 10 से 9 और फिर 8 पर आ जाता है, तो बाहरी चैनल पर केवल 8 का एक ही अपडेट भेजें।
  • WebSockets for Internal Dashboards: वेयरहाउस पिकर स्क्रीन और एडमिनिस्ट्रेटिव डैशबोर्ड पर सीधे रियल-टाइम अपडेट भेजने के लिए websockets stock update गेटवे का उपयोग करें, जिससे मैनुअल पेज रिफ्रेश की आवश्यकता समाप्त हो जाएगी।

Conclusion: अपने Custom ERP को आर्किटेक्ट करना

Real time inventory synchronization erp के लिए एक हाई-परफॉर्मेंस सिस्टम बनाने के लिए मजबूत ट्रांजैक्शनल गारंटियों के साथ तेज़, कंकुरेंट मेमोरी ऑपरेशन्स को संतुलित करने की आवश्यकता होती है। Node.js, TypeScript, और Redis-समर्थित event-driven architecture का लाभ उठाकर, इंजीनियरिंग टीमें ऐसी लचीली पाइपलाइन बना सकती हैं जो बिना किसी परेशानी के दैनिक लाखों ट्रांजैक्शन संभालने में सक्षम हैं।

WebVibez में, हम हाई-स्केल, एंटरप्राइज़-ग्रेड कस्टम सॉफ़्टवेयर, मजबूत बैकएंड और रिस्पॉन्सिव फ्रंटएंड बनाने में विशेषज्ञ हैं। चाहे आप अपने पुराने इन्वेंट्री सिस्टम को बदलना चाहते हों, स्क्रैच से कस्टम ERP बनाना चाहते हों, या प्रीमियम Website Development Services के साथ अपने कस्टमर-फेसिंग पोर्टल्स को ऑप्टिमाइज़ करना चाहते हों, हमारे आर्किटेक्चरल विशेषज्ञ आपके परिचालन बॉटलनेक्स को प्रतिस्पर्धात्मक लाभों में बदलने के लिए तैयार हैं।

क्या आप अपने डिजिटल इंफ्रास्ट्रक्चर को स्केल करने के लिए तैयार हैं? हमारी सीनियर इंजीनियरिंग टीम के साथ गहन आर्किटेक्चरल परामर्श शेड्यूल करने के लिए आज ही WebVibez से संपर्क करें।


👨‍💻 लेखक एवं संपर्क जानकारी (Author & Contact)

कस्टम सॉफ्टवेयर, कोचिंग मैनेजमेंट ऐप्स और वेब आर्किटेक्चर समाधान के लिए WebVibez से संपर्क करें।

Top comments (0)