Skip to content

🏗️ Main System Flow Implementation Guide

📋 Overview

This guide provides complete implementation details for integrating the main system workflows with Partner Services APIs. It covers all user journeys from partner selection to shipment assignment with detailed code examples.

Implementation Coverage: 85% (Current) → 100% (Post Phase 3.8)
User Flows Covered: Partner Setup, Zone Management, Shipment Assignment
Performance Target: <2s page load, <200ms API responses


🎯 Main System User Journeys

Journey 1: Partner Setup Flow

Main System Login → Partner Panel → Select Partner → Configure Data

Journey 2: Zone Management Flow

Zone Management → Fetch All Data → Create/Update Operations

Journey 3: Shipment Assignment Flow

Create Shipment → Assign Courier Partner → Partner Selection → Final Charges

🔄 Flow 1: Partner Setup & Configuration

Step 1: Partner Panel Initialization

javascript
class PartnerSetupFlow {
  constructor(client) {
    this.client = client;
    this.cache = new Map();
  }

  // Initialize partner panel with all available partners
  async initializePartnerPanel() {
    try {
      console.log("🚀 Initializing partner panel...");

      // Phase 1: Load all partners (after P3.8.1 implementation)
      const partners = await this.loadAllPartners();

      // Phase 2: Load partner configurations
      const configurations = await this.loadPartnerConfigurations(partners);

      // Phase 3: Build partner selection UI
      const panelData = this.buildPartnerPanelData(partners, configurations);

      console.log(
        `✅ Partner panel initialized with ${partners.length} partners`
      );
      return panelData;
    } catch (error) {
      console.error("❌ Partner panel initialization failed:", error);
      throw new Error("Failed to initialize partner panel");
    }
  }

  // Load all partners with basic info
  async loadAllPartners() {
    try {
      // 🔥 CRITICAL: This API will be available after P3.8.1
      const response = await this.client.makeRequest(
        "GET",
        "/partners/bulk-data"
      );

      return response.data.partners.map((partner) => ({
        partnerId: partner.partnerId,
        name: partner.name,
        status: partner.status,
        operationalStatus: partner.availability?.isAvailable || false,
        zones: partner.zones?.length || 0,
        services: partner.services?.length || 0,
        lastUpdated: partner.lastUpdated,
      }));
    } catch (error) {
      console.warn(
        "⚠️ Bulk partner API not available, falling back to individual calls"
      );
      return await this.loadPartnersIndividually();
    }
  }

  // Build partner panel UI data
  buildPartnerPanelData(partners, configurations = {}) {
    return {
      partners: partners.map((partner) => ({
        ...partner,
        configuration: configurations[partner.partnerId] || null,
        actions: {
          configure: `/partners/${partner.partnerId}/configure`,
          zones: `/partners/${partner.partnerId}/zones`,
          services: `/partners/${partner.partnerId}/services`,
          charges: `/partners/${partner.partnerId}/charges`,
          discounts: `/partners/${partner.partnerId}/discounts`,
        },
      })),
      summary: {
        total: partners.length,
        active: partners.filter((p) => p.status === "ACTIVE").length,
        operational: partners.filter((p) => p.operationalStatus).length,
      },
      actions: {
        refresh: "/partners/refresh",
        bulkConfigure: "/partners/bulk-configure",
      },
    };
  }
}

Step 2: Partner Selection & Data Fetching

javascript
// When user selects a partner from the panel
async function selectPartner(partnerId) {
  try {
    console.log(`🎯 Selected partner: ${partnerId}`);

    // Fetch comprehensive partner data
    const partnerData = await client.makeRequest(
      "GET",
      `/partners/comprehensive-data?format=standard&includeStatistics=true`
    );

    console.log("📊 Partner Data Summary:");
    console.log(`Zones: ${partnerData.data.zones?.total || 0}`);
    console.log(
      `Packages: ${partnerData.data.packages?.packageCharges?.total || 0}`
    );
    console.log(
      `Services: ${partnerData.data.services?.serviceTypes?.total || 0}`
    );
    console.log(
      `Charges: ${partnerData.data.charges?.customerCharges?.total || 0}`
    );
    console.log(
      `Discounts: ${partnerData.data.discounts?.discounts?.total || 0}`
    );

    // Cache partner data for quick access
    sessionStorage.setItem(`partner_${partnerId}`, JSON.stringify(partnerData));

    return {
      partnerId,
      data: partnerData.data,
      configurationStatus: assessConfigurationCompleteness(partnerData.data),
      nextActions: getRecommendedActions(partnerData.data),
    };
  } catch (error) {
    console.error(`❌ Failed to fetch partner ${partnerId} data:`, error);
    throw error;
  }
}

// Assess configuration completeness
function assessConfigurationCompleteness(data) {
  const checks = {
    zones: data.zones?.total > 0,
    packages: data.packages?.packageCharges?.total > 0,
    services: data.services?.serviceTypes?.total > 0,
    charges: data.charges?.customerCharges?.total > 0,
    discounts: data.discounts?.discounts?.total > 0,
  };

  const completed = Object.values(checks).filter(Boolean).length;
  const total = Object.keys(checks).length;

  return {
    percentage: Math.round((completed / total) * 100),
    completed,
    total,
    checks,
    isComplete: completed === total,
  };
}

🔄 Flow 2: Zone Management Operations

7-Step Zone Creation Process

javascript
class ZoneConfigurationFlow {
  constructor(client, partnerId) {
    this.client = client;
    this.partnerId = partnerId;
    this.zoneData = {
      basic: {},
      geographical: {},
      services: {},
    };
  }

  // Step 1: Basic zone information
  async setBasicInformation(zoneInfo) {
    this.zoneData.basic = {
      name: zoneInfo.name,
      description: zoneInfo.description,
      status: zoneInfo.status || true,
    };

    console.log("✅ Zone basic information set");
    return this.zoneData.basic;
  }

  // Step 2: State selection
  async selectStates(stateIds) {
    try {
      // Validate states exist
      const states = await this.client.makeRequest("GET", "/pincodes/states");
      const validStates = stateIds.filter((id) =>
        states.data.some((state) => state.id === id)
      );

      this.zoneData.geographical.states = validStates;
      console.log(`✅ Selected ${validStates.length} states`);

      return validStates;
    } catch (error) {
      console.error("❌ State selection failed:", error);
      throw error;
    }
  }

  // Step 3: City selection (dependent on states)
  async selectCities(cityIds) {
    try {
      const selectedStates = this.zoneData.geographical.states;
      if (!selectedStates?.length) {
        throw new Error("Please select states first");
      }

      // Get cities for selected states
      const cities = await this.client.makeRequest(
        "GET",
        `/pincodes/cities?stateIds=${selectedStates.join(",")}`
      );

      const validCities = cityIds.filter((id) =>
        cities.data.some((city) => city.id === id)
      );

      this.zoneData.geographical.cities = validCities;
      console.log(`✅ Selected ${validCities.length} cities`);

      return validCities;
    } catch (error) {
      console.error("❌ City selection failed:", error);
      throw error;
    }
  }

  // Step 7: Create zone with all configurations
  async createZone() {
    try {
      const zoneRequest = {
        name: this.zoneData.basic.name,
        description: this.zoneData.basic.description,
        status: this.zoneData.basic.status,
        geographical: {
          states: this.zoneData.geographical.states,
          cities: this.zoneData.geographical.cities || [],
          areas: this.zoneData.geographical.areas || [],
          pincodes: this.zoneData.geographical.pincodes || [],
        },
        services: this.zoneData.services.map((service) => ({
          serviceTypeId: service.serviceTypeId,
          isAvailable: service.isAvailable,
          baseCharge: service.baseCharge || 0,
          customCharges: service.customCharges || {},
          additionalInfo: service.additionalInfo || {},
        })),
      };

      const result = await this.client.makeRequest(
        "POST",
        "/zones",
        zoneRequest
      );

      console.log("🎉 Zone created successfully!");
      console.log(`Zone ID: ${result.data.id}`);
      console.log(`Zone Name: ${result.data.name}`);

      return result.data;
    } catch (error) {
      console.error("❌ Zone creation failed:", error);
      throw error;
    }
  }

  // Get current configuration status
  getConfigurationStatus() {
    return {
      step1_basic: !!this.zoneData.basic.name,
      step2_states: !!this.zoneData.geographical.states?.length,
      step3_cities: !!this.zoneData.geographical.cities?.length,
      step4_areas: !!this.zoneData.geographical.areas?.length,
      step5_pincodes: !!this.zoneData.geographical.pincodes?.length,
      step6_services: !!this.zoneData.services?.length,
      readyToCreate: this.isReadyToCreate(),
    };
  }

  isReadyToCreate() {
    return !!(
      this.zoneData.basic.name &&
      this.zoneData.geographical.states?.length &&
      this.zoneData.services?.length
    );
  }
}

🔄 Flow 3: Shipment Assignment Workflow

Complete Shipment Assignment Implementation

javascript
class ShipmentAssignmentFlow {
  constructor(client) {
    this.client = client;
  }

  // Main shipment assignment workflow
  async assignCourierPartner(shipmentDetails) {
    try {
      console.log("📦 Starting shipment assignment workflow...");

      // Step 1: Validate shipment details
      this.validateShipmentDetails(shipmentDetails);

      // Step 2: Find available partners
      const availablePartners = await this.findAvailablePartners(
        shipmentDetails
      );

      if (availablePartners.length === 0) {
        throw new Error("No available partners found for this shipment");
      }

      // Step 3: Calculate charges for each partner
      const partnersWithCharges = await this.calculateChargesForPartners(
        availablePartners,
        shipmentDetails
      );

      // Step 4: Rank partners (after P3.8.3 implementation)
      const rankedPartners = await this.rankPartners(
        partnersWithCharges,
        shipmentDetails
      );

      // Step 5: Present options to user
      const partnerOptions = this.formatPartnerOptions(rankedPartners);

      console.log(`✅ Found ${partnerOptions.length} available partners`);
      return {
        shipmentDetails,
        partnerOptions,
        recommendedPartner: partnerOptions[0], // Highest ranked
        metadata: {
          searchCriteria: shipmentDetails,
          evaluatedPartners: availablePartners.length,
          availablePartners: partnerOptions.length,
          timestamp: new Date().toISOString(),
        },
      };
    } catch (error) {
      console.error("❌ Shipment assignment failed:", error);
      throw error;
    }
  }

  // Find all available partners for shipment
  async findAvailablePartners(shipmentDetails) {
    try {
      // 🔥 CRITICAL: After P3.8.1, use bulk partner availability
      try {
        const bulkAvailability = await this.client.makeRequest(
          "POST",
          "/partners/bulk-availability",
          { shipmentDetails }
        );

        return bulkAvailability.data.availablePartners;
      } catch (error) {
        console.warn(
          "⚠️ Bulk availability API not available, using individual checks"
        );
        return await this.findAvailablePartnersIndividually(shipmentDetails);
      }
    } catch (error) {
      console.error("❌ Failed to find available partners:", error);
      throw error;
    }
  }

  // Calculate charges for all available partners
  async calculateChargesForPartners(partners, shipmentDetails) {
    const partnersWithCharges = [];

    for (const partner of partners) {
      try {
        const partnerClient = new PartnerServicesClient({
          ...this.client.config,
          partnerId: partner.partnerId,
        });

        const charges = await partnerClient.makeRequest(
          "POST",
          "/shipments/calculate-charges",
          {
            partnerId: partner.partnerId,
            ...shipmentDetails,
          }
        );

        if (charges.data.available) {
          partnersWithCharges.push({
            ...partner,
            charges: charges.data.charges,
            breakdown: charges.data.breakdown,
            calculationId: charges.data.calculationId,
          });
        }
      } catch (error) {
        console.warn(
          `⚠️ Charge calculation failed for partner ${partner.partnerId}`
        );
      }
    }

    return partnersWithCharges;
  }

  // Validate shipment details
  validateShipmentDetails(details) {
    const required = ["pickupPincode", "deliveryPincode", "weight"];
    const missing = required.filter((field) => !details[field]);

    if (missing.length > 0) {
      throw new Error(`Missing required fields: ${missing.join(", ")}`);
    }

    if (!/^\d{6}$/.test(details.pickupPincode)) {
      throw new Error("Invalid pickup pincode format");
    }

    if (!/^\d{6}$/.test(details.deliveryPincode)) {
      throw new Error("Invalid delivery pincode format");
    }

    if (details.weight <= 0 || details.weight > 50000) {
      throw new Error("Weight must be between 1g and 50kg");
    }
  }

  // Final partner selection and assignment
  async selectPartner(partnerId, shipmentDetails) {
    try {
      const assignmentRequest = {
        shipmentDetails: {
          ...shipmentDetails,
          assignedPartnerId: partnerId,
        },
        assignmentPreferences: {
          assignmentStrategy: "MANUAL_SELECTION",
          selectedPartner: partnerId,
        },
        options: {
          includeChargeEstimate: true,
          includeTransitTime: true,
          createAssignmentRecord: true,
        },
      };

      const assignment = await this.client.makeRequest(
        "POST",
        "/shipment-assignment/assign",
        assignmentRequest
      );

      console.log("🎉 Partner selected and assignment created!");
      console.log(`Assignment ID: ${assignment.data.assignment.assignmentId}`);

      return assignment.data;
    } catch (error) {
      console.error("❌ Partner selection failed:", error);
      throw error;
    }
  }
}

📊 Performance Optimization

Caching Strategy for Main System

javascript
class MainSystemCache {
  constructor() {
    this.cache = new Map();
    this.cacheExpiry = new Map();
  }

  // Cache partner data with TTL
  cachePartnerData(partnerId, data, ttlMinutes = 30) {
    const key = `partner_${partnerId}`;
    const expiry = Date.now() + ttlMinutes * 60 * 1000;

    this.cache.set(key, data);
    this.cacheExpiry.set(key, expiry);

    console.log(
      `💾 Cached partner ${partnerId} data for ${ttlMinutes} minutes`
    );
  }

  // Get cached partner data
  getCachedPartnerData(partnerId) {
    const key = `partner_${partnerId}`;
    const expiry = this.cacheExpiry.get(key);

    if (expiry && Date.now() < expiry) {
      console.log(`⚡ Using cached data for partner ${partnerId}`);
      return this.cache.get(key);
    }

    // Expired or not found
    this.cache.delete(key);
    this.cacheExpiry.delete(key);
    return null;
  }

  // Generate shipment hash for caching
  generateShipmentHash(shipmentDetails) {
    const hashString = [
      shipmentDetails.partnerId,
      shipmentDetails.pickupPincode,
      shipmentDetails.deliveryPincode,
      shipmentDetails.weight,
      shipmentDetails.shipmentType,
      shipmentDetails.paymentType,
    ].join("|");

    return btoa(hashString).replace(/[^a-zA-Z0-9]/g, "");
  }
}

Complete Integration Example

javascript
// Complete main system integration example
class MainSystemIntegration {
  constructor(config) {
    this.client = new PartnerServicesClient(config);
    this.cache = new MainSystemCache();
    this.setupFlow = new PartnerSetupFlow(this.client);
    this.assignmentFlow = new ShipmentAssignmentFlow(this.client);
  }

  // Initialize main system with partner services
  async initialize() {
    try {
      console.log("🚀 Initializing main system integration...");

      // Test connectivity
      await this.client.makeRequest("GET", "/health");

      // Load partner panel
      const partnerPanel = await this.setupFlow.initializePartnerPanel();

      console.log("✅ Main system integration initialized successfully");

      return {
        partnerPanel,
        status: "READY",
      };
    } catch (error) {
      console.error("❌ Main system integration failed:", error);
      throw error;
    }
  }

  // Complete shipment workflow
  async processShipment(shipmentDetails) {
    try {
      // Step 1: Assign courier partner
      const assignmentOptions = await this.assignmentFlow.assignCourierPartner(
        shipmentDetails
      );

      // Return options for user selection
      return assignmentOptions;
    } catch (error) {
      console.error("❌ Shipment processing failed:", error);
      throw error;
    }
  }

  // Finalize shipment assignment
  async finalizeShipment(partnerId, shipmentDetails) {
    try {
      const assignment = await this.assignmentFlow.selectPartner(
        partnerId,
        shipmentDetails
      );

      // Cache the successful assignment
      this.cache.cacheChargeCalculation(
        this.cache.generateShipmentHash(shipmentDetails),
        assignment.charges,
        60 // 1 hour cache for completed assignments
      );

      return assignment;
    } catch (error) {
      console.error("❌ Shipment finalization failed:", error);
      throw error;
    }
  }
}

// Usage example
const mainSystem = new MainSystemIntegration(API_CONFIG);

// Initialize system
mainSystem.initialize().then((data) => {
  console.log("🎉 Main system ready!");
});

// Process a shipment
const shipment = {
  pickupPincode: "110001",
  deliveryPincode: "400001",
  weight: 2500,
  shipmentType: "B2C",
  paymentType: "COD",
  declaredValue: 3500,
};

mainSystem
  .processShipment(shipment)
  .then((options) => {
    console.log("📦 Shipment options ready for selection");

    // User selects the recommended partner
    const selectedPartner = options.recommendedPartner.partnerId;

    // Finalize assignment
    return mainSystem.finalizeShipment(selectedPartner, shipment);
  })
  .then((assignment) => {
    console.log("✅ Shipment assigned successfully!");
    console.log(`Assignment ID: ${assignment.assignment.assignmentId}`);
  });

🎯 Next Steps

  1. Authentication Setup - HMAC implementation
  2. Partner Management - Partner configuration
  3. Zone Management - Zone operations
  4. Shipment Assignment - Assignment workflows

This guide provides 85% implementation coverage. The remaining 15% will be available after Phase 3.8 completion.

Released under the MIT License.