@dispatch9/client-sdk
Version:
Official Node.js SDK for Dispatch9 API - Complete solution with email/phone client creation, order management, client management, and dual-method authentication
344 lines (301 loc) ⢠13.2 kB
JavaScript
require('dotenv').config();
const Dispatch9Client = require('../src/client');
/**
* Complete Workflow Example
* Demonstrates end-to-end usage of all 4 core operations:
* 1. Create Client ā 2. Get Clients ā 3. Create Order ā 4. Update Order
*
* This example shows a realistic business scenario where:
* - A new restaurant partner joins the platform
* - They start receiving and processing orders
* - Orders are tracked and updated through their lifecycle
*/
async function completeWorkflowExample() {
console.log('š Dispatch9 SDK - Complete Workflow Example\n');
console.log('š Scenario: New restaurant partner onboarding and first orders\n');
try {
// Initialize the SDK
const dispatch9 = new Dispatch9Client({
apiKey: process.env.DISPATCH9_API_KEY,
baseURL: process.env.DISPATCH9_BASE_URL || 'https://api.dispatch9.com',
debug: false // Keep output clean for workflow demo
});
console.log('ā
SDK initialized successfully\n');
// ==========================================
// PHASE 1: PARTNER ONBOARDING
// ==========================================
console.log('š¢ PHASE 1: Partner Onboarding');
console.log('ā'.repeat(50));
console.log('š Creating new restaurant partner...');
const newPartner = await dispatch9.createClient({
name: 'Bella Vista Italian Kitchen',
email: 'operations@bellavista.com',
businessType: 'restaurant',
websiteURL: 'https://www.bellavista.com',
taxId: '12-9876543',
webhookURL: 'https://www.bellavista.com/api/dispatch9-webhook',
orderSettings: {
autoAccept: false, // Manual review for new partner
autoAssign: false,
maxOrdersPerHour: 30,
preparationTime: 35,
deliveryRadius: 10.0
},
permissions: {
createOrders: true,
viewOrders: true,
modify: false,
delete: false
},
authentication: {
enablePortalAccess: true,
firstName: 'Giuseppe',
lastName: 'Romano',
businessName: 'Bella Vista Italian Kitchen',
phone: '+1-555-BELLA-1'
},
apiConfig: {
enabled: true,
rateLimit: 300
}
});
console.log(`ā
Partner onboarded successfully!`);
console.log(` Partner ID: ${newPartner.id}`);
console.log(` Name: ${newPartner.name}`);
console.log(` Contact: ${newPartner.authentication?.firstName} ${newPartner.authentication?.lastName}`);
console.log(` Preparation Time: ${newPartner.orderSettings?.preparationTime} minutes`);
console.log(` Delivery Radius: ${newPartner.orderSettings?.deliveryRadius} km\n`);
// ==========================================
// PHASE 2: PARTNER VERIFICATION
// ==========================================
console.log('š PHASE 2: Partner Verification');
console.log('ā'.repeat(50));
console.log('š Retrieving all restaurant partners for verification...');
const restaurants = await dispatch9.getClients({
businessType: 'restaurant',
status: 'active',
limit: 10,
sortBy: 'createdAt:desc'
});
console.log(`ā
Found ${restaurants.totalResults} total restaurant partners`);
console.log(` Showing ${restaurants.results.length} most recent:`);
restaurants.results.forEach((partner, index) => {
const isNew = partner.id === newPartner.id;
const marker = isNew ? 'š' : ' ';
console.log(` ${marker} ${index + 1}. ${partner.name} (${partner.email})`);
if (isNew) {
console.log(` ā³ This is our new partner!`);
}
});
console.log();
// ==========================================
// PHASE 3: FIRST ORDER PROCESSING
// ==========================================
console.log('š PHASE 3: First Order Processing');
console.log('ā'.repeat(50));
console.log('š¦ Creating first order from new partner...');
const firstOrder = await dispatch9.createOrder({
orderTotal: 78.95,
client: newPartner.id,
orderCurrency: 'USD',
hasGoods: true,
priority: 5,
items: [
{
SKU: 'PASTA001',
itemName: 'Spaghetti Carbonara',
price: 24.95,
quantity: 2,
category: 'Main Course',
description: 'Classic Roman pasta with eggs, cheese, and pancetta',
weight: 0.6,
weightUnit: 'kg',
notes: 'Extra cheese on the side'
},
{
SKU: 'APP001',
itemName: 'Bruschetta al Pomodoro',
price: 12.95,
quantity: 1,
category: 'Appetizer',
description: 'Grilled bread with fresh tomatoes and basil',
weight: 0.3,
weightUnit: 'kg'
},
{
SKU: 'DESS001',
itemName: 'Tiramisu',
price: 8.95,
quantity: 2,
category: 'Dessert',
description: 'Classic Italian coffee-flavored dessert',
weight: 0.4,
weightUnit: 'kg',
handling: 'Keep refrigerated'
}
],
specialInstructions: 'First order for new partner - handle with extra care',
customerNotes: 'Customer requested contactless delivery',
requiredProof: {
signature: false,
photo: true
},
metadata: {
isFirstOrder: true,
partnerOnboardingDate: new Date().toISOString(),
customerType: 'regular'
}
});
console.log(`ā
First order created successfully!`);
console.log(` Order ID: ${firstOrder.id}`);
console.log(` Total: $${firstOrder.orderTotal}`);
console.log(` Items: ${firstOrder.items.length} items`);
console.log(` Status: ${firstOrder.status}`);
console.log(` Priority: ${firstOrder.priority}`);
// Show order items
console.log(' š Order Items:');
firstOrder.items.forEach((item, index) => {
console.log(` ${index + 1}. ${item.itemName} x${item.quantity} - $${item.price}`);
});
console.log();
// ==========================================
// PHASE 4: ORDER LIFECYCLE MANAGEMENT
// ==========================================
console.log('š PHASE 4: Order Lifecycle Management');
console.log('ā'.repeat(50));
// Step 1: Confirm the order
console.log('ā
Step 1: Restaurant confirms the order...');
const confirmedOrder = await dispatch9.updateOrder(firstOrder.id, {
status: 'confirmed',
statusNotes: 'Order confirmed by kitchen staff',
priority: 6, // Slightly increased priority
metadata: {
...firstOrder.metadata,
confirmedBy: 'Giuseppe Romano',
confirmedAt: new Date().toISOString(),
estimatedPrepTime: 35
}
});
console.log(` ā
Order confirmed - Status: ${confirmedOrder.status}`);
console.log(` š Notes: ${confirmedOrder.statusNotes}`);
console.log(` šÆ Priority: ${confirmedOrder.priority}\n`);
// Step 2: Order preparation begins
console.log('šØāš³ Step 2: Kitchen begins preparation...');
const inProgressOrder = await dispatch9.updateOrder(firstOrder.id, {
status: 'in_progress',
statusNotes: 'Kitchen has started preparing the order',
specialInstructions: 'First order for new partner - handle with extra care. Customer requested contactless delivery.',
metadata: {
...confirmedOrder.metadata,
prepStartedAt: new Date().toISOString(),
kitchenStation: 'Station 3',
chefAssigned: 'Marco Antonelli'
}
});
console.log(` ā
Preparation started - Status: ${inProgressOrder.status}`);
console.log(` šØāš³ Chef: ${inProgressOrder.metadata?.chefAssigned}`);
console.log(` šŖ Station: ${inProgressOrder.metadata?.kitchenStation}\n`);
// Step 3: Add special request
console.log('š Step 3: Customer calls with special request...');
const updatedOrder = await dispatch9.updateOrder(firstOrder.id, {
customerNotes: 'Customer requested contactless delivery. UPDATED: Please include extra napkins and utensils.',
statusNotes: 'Customer called with additional request for extra napkins',
items: [
...inProgressOrder.items.map(item =>
item.SKU === 'PASTA001'
? { ...item, notes: 'Extra cheese on the side + extra napkins requested' }
: item
)
],
metadata: {
...inProgressOrder.metadata,
customerCallTime: new Date().toISOString(),
specialRequest: 'Extra napkins and utensils'
}
});
console.log(` ā
Special request added`);
console.log(` š Updated notes: ${updatedOrder.customerNotes}`);
console.log(` š Updated pasta notes: ${updatedOrder.items.find(i => i.SKU === 'PASTA001')?.notes}\n`);
// ==========================================
// PHASE 5: PARTNER SUCCESS METRICS
// ==========================================
console.log('š PHASE 5: Partner Success Metrics');
console.log('ā'.repeat(50));
// Update partner settings based on successful first order
console.log('šÆ Updating partner settings based on successful first order...');
const optimizedPartner = await dispatch9.updateClient(newPartner.id, {
orderSettings: {
autoAccept: true, // Enable auto-accept after successful first order
autoAssign: false, // Keep manual assignment for now
maxOrdersPerHour: 35, // Slightly increased capacity
preparationTime: 30, // Reduced based on actual performance
deliveryRadius: 12.0 // Expanded radius
},
apiConfig: {
enabled: true,
rateLimit: 500 // Increased rate limit
},
status: 'active'
});
console.log(` ā
Partner settings optimized!`);
console.log(` š Auto Accept: ${optimizedPartner.orderSettings?.autoAccept}`);
console.log(` ā±ļø Prep Time: ${optimizedPartner.orderSettings?.preparationTime} minutes`);
console.log(` š Delivery Radius: ${optimizedPartner.orderSettings?.deliveryRadius} km`);
console.log(` š„ Rate Limit: ${optimizedPartner.apiConfig?.rateLimit} req/hour\n`);
// ==========================================
// WORKFLOW SUMMARY
// ==========================================
console.log('š WORKFLOW COMPLETED SUCCESSFULLY!');
console.log('ā'.repeat(50));
console.log('š Complete Business Flow Summary:');
console.log();
console.log('š¢ PARTNER ONBOARDING:');
console.log(` ā Created: ${newPartner.name}`);
console.log(` ā Contact: ${newPartner.authentication?.firstName} ${newPartner.authentication?.lastName}`);
console.log(` ā Business Type: ${newPartner.businessType}`);
console.log();
console.log('š VERIFICATION:');
console.log(` ā Retrieved ${restaurants.totalResults} restaurant partners`);
console.log(` ā Verified new partner in system`);
console.log();
console.log('š¦ ORDER PROCESSING:');
console.log(` ā Created first order: $${firstOrder.orderTotal}`);
console.log(` ā Order items: ${firstOrder.items.length} items`);
console.log(` ā Initial status: ${firstOrder.status}`);
console.log();
console.log('š LIFECYCLE MANAGEMENT:');
console.log(` ā Confirmed ā In Progress ā Updated`);
console.log(` ā Final status: ${updatedOrder.status}`);
console.log(` ā Priority: ${updatedOrder.priority}`);
console.log(` ā Special requests handled`);
console.log();
console.log('ā” OPTIMIZATION:');
console.log(` ā Auto Accept: ${optimizedPartner.orderSettings?.autoAccept}`);
console.log(` ā Reduced prep time: ${optimizedPartner.orderSettings?.preparationTime} min`);
console.log(` ā Expanded radius: ${optimizedPartner.orderSettings?.deliveryRadius} km`);
console.log();
console.log('š Ready for production operations!');
} catch (error) {
console.error('ā Error in complete workflow:', error.message);
// Provide helpful troubleshooting information
if (error.message.includes('Authentication failed')) {
console.error('\nš§ Troubleshooting:');
console.error(' ⢠Check your DISPATCH9_API_KEY in the .env file');
console.error(' ⢠Ensure the API key is valid and not expired');
} else if (error.message.includes('Access forbidden')) {
console.error('\nš§ Troubleshooting:');
console.error(' ⢠Your API key may not have the required permissions');
console.error(' ⢠Required permissions: orders.create, orders.update, clients.create, clients.read, clients.update');
} else if (error.message.includes('Rate limit exceeded')) {
console.error('\nš§ Troubleshooting:');
console.error(' ⢠You are making requests too quickly');
console.error(' ⢠Wait a moment and try again');
}
process.exit(1);
}
}
// Run the example
if (require.main === module) {
completeWorkflowExample();
}
module.exports = completeWorkflowExample;