🏗️ 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
- Authentication Setup - HMAC implementation
- Partner Management - Partner configuration
- Zone Management - Zone operations
- Shipment Assignment - Assignment workflows
This guide provides 85% implementation coverage. The remaining 15% will be available after Phase 3.8 completion.