@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
421 lines (360 loc) ⢠16.4 kB
JavaScript
require('dotenv').config();
const Dispatch9Client = require('../src/client');
/**
* Query & Tracking Example
* Demonstrates the new getOrderById and getClientById methods:
* - Client verification and registration checking
* - Order status tracking and monitoring
* - Detailed information retrieval with population
* - Error handling for not found scenarios
* - Real-world tracking and verification use cases
*/
async function queryTrackingExample() {
console.log('š Dispatch9 SDK - Query & Tracking Example\n');
console.log('š Demonstrating getOrderById and getClientById for tracking and verification\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
});
console.log('ā
SDK initialized successfully\n');
// ==========================================
// PART 1: CLIENT VERIFICATION & REGISTRATION CHECK
// ==========================================
console.log('š¤ PART 1: Client Verification & Registration');
console.log('ā'.repeat(60));
// Get a list of clients to work with
console.log('š Getting existing clients...');
const clientsList = await dispatch9.getClients({ limit: 2 });
if (!clientsList.results || clientsList.results.length === 0) {
throw new Error('No clients found. Please create a client first using basic-usage.js');
}
const testClientId = clientsList.results[0].id;
console.log(`ā
Found ${clientsList.results.length} clients, using: ${testClientId}\n`);
// Example 1: Basic client verification
console.log('š Example 1: Basic Client Verification');
console.log('-'.repeat(40));
const clientBasic = await dispatch9.getClientById(testClientId);
console.log(`ā
Client verified successfully:`);
console.log(` ID: ${clientBasic.id}`);
console.log(` Name: ${clientBasic.name}`);
console.log(` Email: ${clientBasic.email}`);
console.log(` Status: ${clientBasic.status}`);
console.log(` Business Type: ${clientBasic.businessType}`);
console.log(` Registration Date: ${new Date(clientBasic.createdAt).toLocaleDateString()}\n`);
// Example 2: Client with populated addresses
console.log('š Example 2: Client with Address Details');
console.log('-'.repeat(40));
try {
const clientWithAddresses = await dispatch9.getClientById(testClientId, {
populate: 'addresses,primaryAddress,billingAddress'
});
console.log(`ā
Client with address details:`);
console.log(` Name: ${clientWithAddresses.name}`);
if (clientWithAddresses.primaryAddress) {
console.log(` Primary Address: ${clientWithAddresses.primaryAddress.street}, ${clientWithAddresses.primaryAddress.city}`);
}
if (clientWithAddresses.addresses) {
console.log(` Total Addresses: ${clientWithAddresses.addresses.length}`);
}
} catch (error) {
console.log(`ā¹ļø Address population not available: ${error.message}`);
}
console.log('');
// Example 3: Client with statistics
console.log('š Example 3: Client with Statistics');
console.log('-'.repeat(40));
try {
const clientWithStats = await dispatch9.getClientById(testClientId, {
includeStats: true
});
console.log(`ā
Client statistics:`);
if (clientWithStats.stats) {
console.log(` Total Orders: ${clientWithStats.stats.totalOrders || 0}`);
console.log(` Total Revenue: $${clientWithStats.stats.totalRevenue || 0}`);
console.log(` Average Order Value: $${clientWithStats.stats.averageOrderValue || 0}`);
console.log(` Last Order Date: ${clientWithStats.stats.lastOrderDate || 'Never'}`);
} else {
console.log(` Statistics: Not available for this client`);
}
} catch (error) {
console.log(`ā¹ļø Statistics not available: ${error.message}`);
}
console.log('');
// Example 4: Test non-existent client
console.log('ā Example 4: Non-existent Client Handling');
console.log('-'.repeat(40));
try {
await dispatch9.getClientById('507f1f77bcf86cd799439999'); // Fake ID
} catch (error) {
console.log(`ā
Properly handled non-existent client:`);
console.log(` Error: ${error.message}`);
console.log(` Status: Client not found (as expected)\n`);
}
// ==========================================
// PART 2: ORDER STATUS TRACKING & MONITORING
// ==========================================
console.log('š¦ PART 2: Order Status Tracking & Monitoring');
console.log('ā'.repeat(60));
// First, let's create an order to track
console.log('š Creating a sample order for tracking...');
const sampleOrder = await dispatch9.createOrder({
orderTotal: 89.99,
client: testClientId,
hasServices: true,
priority: 6,
services: [
{
serviceCode: 'TRACK001',
serviceName: 'Package Tracking Demo',
category: 'other',
description: 'Demo service for tracking example',
estimatedDuration: 60,
workersRequired: 1,
price: 89.99
}
],
serviceLocation: '507f1f77bcf86cd799439014', // Replace with actual address ID
specialInstructions: 'Demo order for tracking example',
customerNotes: 'This is a test order for SDK demonstration'
});
console.log(`ā
Sample order created: ${sampleOrder.id}\n`);
// Example 1: Basic order tracking
console.log('š Example 1: Basic Order Status Check');
console.log('-'.repeat(40));
const orderBasic = await dispatch9.getOrderById(sampleOrder.id);
console.log(`ā
Order tracking information:`);
console.log(` Order ID: ${orderBasic.id}`);
console.log(` Status: ${orderBasic.status}`);
console.log(` Total: $${orderBasic.orderTotal}`);
console.log(` Priority: ${orderBasic.priority}`);
console.log(` Created: ${new Date(orderBasic.createdAt).toLocaleString()}`);
console.log(` Services: ${orderBasic.services.length}`);
orderBasic.services.forEach((service, index) => {
console.log(` ${index + 1}. ${service.serviceName} (${service.workersRequired} workers)`);
});
console.log('');
// Example 2: Order with populated client details
console.log('š¤ Example 2: Order with Client Information');
console.log('-'.repeat(40));
try {
const orderWithClient = await dispatch9.getOrderById(sampleOrder.id, {
populate: 'client'
});
console.log(`ā
Order with client details:`);
console.log(` Order ID: ${orderWithClient.id}`);
console.log(` Status: ${orderWithClient.status}`);
if (orderWithClient.client) {
console.log(` Client Name: ${orderWithClient.client.name}`);
console.log(` Client Email: ${orderWithClient.client.email}`);
console.log(` Client Status: ${orderWithClient.client.status}`);
}
} catch (error) {
console.log(`ā¹ļø Client population not available: ${error.message}`);
}
console.log('');
// Example 3: Order with location details
console.log('š Example 3: Order with Location Information');
console.log('-'.repeat(40));
try {
const orderWithLocations = await dispatch9.getOrderById(sampleOrder.id, {
populate: 'serviceLocation,pickupLocation,deliveryLocation'
});
console.log(`ā
Order with location details:`);
console.log(` Order ID: ${orderWithLocations.id}`);
if (orderWithLocations.serviceLocation) {
console.log(` Service Location: ${orderWithLocations.serviceLocation.street || 'Address details'}`);
}
if (orderWithLocations.pickupLocation) {
console.log(` Pickup Location: ${orderWithLocations.pickupLocation.street || 'Address details'}`);
}
if (orderWithLocations.deliveryLocation) {
console.log(` Delivery Location: ${orderWithLocations.deliveryLocation.street || 'Address details'}`);
}
} catch (error) {
console.log(`ā¹ļø Location population not available: ${error.message}`);
}
console.log('');
// Example 4: Order with associated jobs
console.log('š· Example 4: Order with Job Information');
console.log('-'.repeat(40));
try {
const orderWithJobs = await dispatch9.getOrderById(sampleOrder.id, {
includeJobs: true
});
console.log(`ā
Order with job details:`);
console.log(` Order ID: ${orderWithJobs.id}`);
console.log(` Status: ${orderWithJobs.status}`);
if (orderWithJobs.jobs && orderWithJobs.jobs.length > 0) {
console.log(` Associated Jobs: ${orderWithJobs.jobs.length}`);
orderWithJobs.jobs.forEach((job, index) => {
console.log(` ${index + 1}. Job ${job.jobId}: ${job.status}`);
console.log(` Worker: ${job.assignedWorker || 'Unassigned'}`);
console.log(` Type: ${job.type || 'N/A'}`);
});
} else {
console.log(` Associated Jobs: No jobs created yet`);
}
} catch (error) {
console.log(`ā¹ļø Job information not available: ${error.message}`);
}
console.log('');
// Example 5: Comprehensive order tracking function
console.log('šÆ Example 5: Comprehensive Order Tracking');
console.log('-'.repeat(40));
const trackOrderComprehensive = async (orderId) => {
try {
const order = await dispatch9.getOrderById(orderId, {
populate: 'client,serviceLocation',
includeJobs: true
});
return {
// Basic Info
id: order.id,
orderNumber: order.orderNumber,
status: order.status,
total: order.orderTotal,
priority: order.priority,
// Progress Info
isCompleted: order.status === 'completed',
isCancelled: order.status === 'cancelled',
isInProgress: order.status === 'in_progress',
completionPercentage: order.completionPercentage || 0,
// Timeline
createdAt: order.createdAt,
updatedAt: order.updatedAt,
estimatedCompletion: order.estimatedDeliveryTime,
// Client Info
client: order.client ? {
id: order.client.id,
name: order.client.name,
email: order.client.email
} : null,
// Services Info
services: order.services.map(service => ({
name: service.serviceName,
status: service.status?.isCompleted ? 'completed' : 'pending',
workersRequired: service.workersRequired,
estimatedDuration: service.estimatedDuration
})),
// Jobs Info
jobs: order.jobs ? order.jobs.map(job => ({
id: job.jobId,
status: job.status,
worker: job.assignedWorker,
type: job.type
})) : [],
// Location Info
location: order.serviceLocation ? {
street: order.serviceLocation.street,
city: order.serviceLocation.city,
coordinates: order.serviceLocation.coordinates
} : null
};
} catch (error) {
return {
error: true,
message: error.message,
notFound: error.message.includes('404')
};
}
};
const trackingInfo = await trackOrderComprehensive(sampleOrder.id);
if (trackingInfo.error) {
console.log(`ā Tracking failed: ${trackingInfo.message}`);
} else {
console.log(`ā
Comprehensive tracking info:`);
console.log(` Order: ${trackingInfo.orderNumber || trackingInfo.id}`);
console.log(` Status: ${trackingInfo.status} (${trackingInfo.completionPercentage}% complete)`);
console.log(` Client: ${trackingInfo.client?.name || 'Unknown'}`);
console.log(` Total: $${trackingInfo.total}`);
console.log(` Services: ${trackingInfo.services.length}`);
trackingInfo.services.forEach((service, index) => {
console.log(` ${index + 1}. ${service.name}: ${service.status} (${service.workersRequired} workers)`);
});
console.log(` Jobs: ${trackingInfo.jobs.length}`);
console.log(` Created: ${new Date(trackingInfo.createdAt).toLocaleString()}`);
}
console.log('');
// ==========================================
// PART 3: ERROR HANDLING & VALIDATION
// ==========================================
console.log('š”ļø PART 3: Error Handling & Validation');
console.log('ā'.repeat(60));
// Test invalid ObjectId formats
const invalidIds = [
'invalid-id',
'507f1f77bcf86cd79943901', // too short
'507f1f77bcf86cd799439011g', // invalid character
'',
null
];
console.log('ā Testing invalid ID formats:');
for (const invalidId of invalidIds) {
try {
await dispatch9.getOrderById(invalidId);
} catch (error) {
console.log(` ā
"${invalidId || 'null'}": ${error.message}`);
}
}
console.log('');
// Test non-existent IDs
console.log('š Testing non-existent resources:');
try {
await dispatch9.getOrderById('507f1f77bcf86cd799439999');
} catch (error) {
console.log(` ā
Non-existent order: ${error.message}`);
}
try {
await dispatch9.getClientById('507f1f77bcf86cd799439888');
} catch (error) {
console.log(` ā
Non-existent client: ${error.message}`);
}
console.log('');
// ==========================================
// SUMMARY & USE CASES
// ==========================================
console.log('š SUMMARY & REAL-WORLD USE CASES');
console.log('ā'.repeat(60));
console.log('šÆ Key Benefits of getOrderById and getClientById:');
console.log(' ā Real-time order status tracking');
console.log(' ā Client registration verification');
console.log(' ā Detailed information retrieval with population');
console.log(' ā Comprehensive error handling');
console.log(' ā Integration with monitoring systems');
console.log(' ā Customer service support tools');
console.log('\nš” Real-World Use Cases:');
console.log(' š± Mobile apps: Track order progress in real-time');
console.log(' š Web portals: Customer order history and status');
console.log(' š Call centers: Quick client and order lookup');
console.log(' š Analytics: Order completion rates and client metrics');
console.log(' š Notifications: Status change alerts and updates');
console.log(' š ļø Monitoring: Automated health checks and reporting');
console.log('\nš Performance Tips:');
console.log(' ⢠Use populate selectively to reduce response size');
console.log(' ⢠Cache frequently accessed client information');
console.log(' ⢠Implement proper error handling for 404s');
console.log(' ⢠Use includeStats only when analytics are needed');
console.log(' ⢠Validate ObjectId format before API calls');
console.log('\nš Query & Tracking Example Completed Successfully!');
} catch (error) {
console.error('ā Error in query & tracking example:', error.message);
if (error.message.includes('No clients found')) {
console.error('\nš§ Setup Required:');
console.error(' ⢠Run basic-usage.js first to create a client');
console.error(' ⢠Or use client-management.js to create test clients');
} else if (error.message.includes('must be a valid ObjectId')) {
console.error('\nš§ ObjectId Validation:');
console.error(' ⢠Ensure IDs are 24 character hexadecimal strings');
console.error(' ⢠Use the exact ID returned from create operations');
}
process.exit(1);
}
}
// Run the example
if (require.main === module) {
queryTrackingExample();
}
module.exports = queryTrackingExample;