@ritas-inc/hanaqueryapi-client
Version:
TypeScript client for HANA Query API with full type safety and error handling
427 lines (351 loc) • 15.3 kB
text/typescript
/**
* Basic Usage Examples
*
* This file demonstrates the most common use cases for the HANA Query API client.
*/
import {
HanaQueryClient,
createClient,
ENVIRONMENT_CONFIGS,
type SalesParams,
type Plan
} from '../index.ts';
// ============================================================================
// Example 1: Basic Client Usage
// ============================================================================
async function basicClientUsage() {
console.log('=== Basic Client Usage ===');
// Create a client with explicit configuration
const client = new HanaQueryClient({ baseUrl: 'http://localhost:3001' });
try {
// Test the connection first
console.log('Testing API connection...');
const isOnline = await client.testConnection();
if (!isOnline) {
console.error('❌ API is not reachable');
return;
}
console.log('✅ API is online');
// Get health status
const health = await client.getHealth();
console.log(`Server status: ${health.data.status}`);
console.log(`Server uptime: ${Math.round(health.data.uptime / 60)} minutes`);
// Get API documentation
const docs = await client.getDocs();
console.log(`API: ${docs.data.name} v${docs.data.version}`);
console.log(`Available endpoints: ${Object.keys(docs.data.endpoints).length}`);
} catch (error: unknown) {
if (error instanceof Error) {
console.error('Error in basic usage:', error.message);
} else {
console.error('Unknown error in basic usage:', error);
}
}
}
// ============================================================================
// Example 2: Working with Items
// ============================================================================
async function workingWithItems() {
console.log('\\n=== Working with Items ===');
const client = new HanaQueryClient({ baseUrl: 'http://localhost:3001' });
try {
// Get all items (using default date range)
console.log('Fetching all items...');
const allItems = await client.getItems();
console.log(`Total items: ${allItems.metadata.count}`);
// Get sales for a specific date range
const params: SalesParams = {
from: '2025-01-01',
to: '2025-06-30'
};
console.log('Fetching sales for date range...');
const salesData = await client.getSales(params);
console.log(`Sales found: ${salesData.metadata.count}`);
console.log(`Date range: ${salesData.metadata.from} to ${salesData.metadata.to}`);
// Analyze some items from allItems
const items = allItems.data.items.slice(0, 5); // First 5 items
console.log('\\nSample items:');
items.forEach((item: any) => {
const stockStatus = item.onhand >= item.min ? '✅' : '⚠️';
console.log(`${stockStatus} ${item.itemcode}: ${item.onhand}/${item.min} - ${item.description}`);
});
// Get item hierarchies
console.log('\\nFetching item hierarchies...');
const hierarchies = await client.getItemHierarchies();
console.log(`Total hierarchy relationships: ${hierarchies.metadata.count}`);
// Show some hierarchy examples
const sampleHierarchies = hierarchies.data.hierarchies.slice(0, 3);
console.log('\\nSample hierarchies:');
sampleHierarchies.forEach(h => {
const parentInfo = h.parent ? `Parent: ${h.parent}` : 'Root item';
console.log(` ${h.node} (${parentInfo}) - Qty: ${h.quantity}, Rank: ${h.rank}`);
});
} catch (error: unknown) {
if (error instanceof Error) {
console.error('Error working with items:', error.message);
} else {
console.error('Unknown error working with items:', error);
}
}
}
// ============================================================================
// Example 3: Production Planning Workflow
// ============================================================================
async function productionPlanningWorkflow() {
console.log('\\n=== Production Planning Workflow ===');
const client = new HanaQueryClient({ baseUrl: 'http://localhost:3001' });
try {
// Get all production plans
console.log('Fetching production plans...');
const plansResponse = await client.getPlans();
const plans = plansResponse.data.plans;
console.log(`Found ${plans.length} production plans`);
// Analyze plan statuses
const statusCounts = plans.reduce((acc, plan) => {
acc[plan.plan_status] = (acc[plan.plan_status] || 0) + 1;
return acc;
}, {} as Record<string, number>);
console.log('\\nPlan status distribution:');
Object.entries(statusCounts).forEach(([status, count]) => {
console.log(` ${status}: ${count} plans`);
});
// Get detailed information for the first few plans
const samplePlans = plans.slice(0, 3);
for (const plan of samplePlans) {
console.log(`\\n--- Plan ${plan.plan_id} Details ---`);
console.log(`Status: ${plan.plan_status}`);
console.log(`Created by: ${plan.plan_username} on ${new Date(plan.plan_createdate).toLocaleDateString()}`);
console.log(`Products: ${plan.products_total} total, ${plan.products_released} released, ${plan.products_closed} closed`);
try {
// Get plan products
const products = await client.getPlanProducts(plan.plan_id);
console.log(`Products in plan: ${products.metadata.count}`);
if (products.data.products.length > 0) {
console.log('Sample products:');
products.data.products.slice(0, 3).forEach(product => {
console.log(` - ${product.itemcode}: ${product.quantity} units`);
});
}
// Try to get work orders (may not exist for all plans)
try {
const workOrders = await client.getPlanWorkOrders(plan.plan_id);
console.log(`Work orders: ${workOrders.metadata.count}`);
if (workOrders.data.workOrders.length > 0) {
const totalPlanned = workOrders.data.workOrders.reduce((sum, wo) => sum + wo.order_plannedqty, 0);
const totalCompleted = workOrders.data.workOrders.reduce((sum, wo) => sum + wo.order_completedqty, 0);
const completionRate = totalPlanned > 0 ? (totalCompleted / totalPlanned * 100) : 0;
console.log(`Completion rate: ${completionRate.toFixed(1)}%`);
}
} catch (error: unknown) {
console.log('No work orders found for this plan');
}
} catch (error: unknown) {
if (error instanceof Error) {
console.error(`Error getting details for plan ${plan.plan_id}:`, error.message);
} else {
console.error(`Unknown error getting details for plan ${plan.plan_id}:`, error);
}
}
}
} catch (error: unknown) {
if (error instanceof Error) {
console.error('Error in production planning workflow:', error.message);
} else {
console.error('Unknown error in production planning workflow:', error);
}
}
}
// ============================================================================
// Example 4: Using Environment-Specific Clients
// ============================================================================
async function environmentSpecificClients() {
console.log('\\n=== Environment-Specific Clients ===');
// Development client (with debug logging)
const devClient = createClient({
...ENVIRONMENT_CONFIGS.development,
enableLogging: true,
logLevel: 'debug'
});
// Production client (minimal logging)
const prodClient = createClient({
...ENVIRONMENT_CONFIGS.production,
enableLogging: true,
logLevel: 'error'
});
// Custom client
const customClient = createClient({
baseUrl: 'http://localhost:3001',
timeout: 60000,
retries: 5,
enableLogging: true,
logLevel: 'info'
});
console.log('Created environment-specific clients:');
console.log(`- Development client: ${ENVIRONMENT_CONFIGS.development.baseUrl}`);
console.log(`- Production client: ${ENVIRONMENT_CONFIGS.production.baseUrl}`);
console.log(`- Custom client: http://localhost:3001`);
try {
// Test with development client
const health = await devClient.getHealth();
console.log(`Development API status: ${health.data.status}`);
} catch (error: unknown) {
if (error instanceof Error) {
console.log('Development API not available:', error.message);
} else {
console.log('Development API not available:', error);
}
}
}
// ============================================================================
// Example 5: Using Utility Functions
// ============================================================================
async function usingUtilityFunctions() {
console.log('\\n=== Using Utility Functions ===');
const client = createClient({ baseUrl: 'http://localhost:3001' });
try {
// Test connection using utility
const isOnline = await client.testConnection();
console.log(`API connection test: ${isOnline ? '✅ Online' : '❌ Offline'}`);
if (!isOnline) {
return;
}
// Get all plan IDs
const plansResponse = await client.getPlans();
const planIds = plansResponse.data.plans.map((plan: Plan) => plan.plan_id);
console.log(`Available plan IDs: ${planIds.join(', ')}`);
// Get complete plan data (if plans exist)
if (planIds.length > 0) {
const firstPlanId = planIds[0];
console.log(`\\nGetting complete data for plan ${firstPlanId}...`);
// Manual implementation of getCompletePlanData utility
const [plan, products, workOrders] = await Promise.allSettled([
client.getPlan(firstPlanId),
client.getPlanProducts(firstPlanId),
client.getPlanWorkOrders(firstPlanId)
]);
const completePlan = {
plan: plan.status === 'fulfilled' ? plan.value.data.plan : null,
products: products.status === 'fulfilled' ? products.value.data.products : [],
workOrders: workOrders.status === 'fulfilled' ? workOrders.value.data.workOrders : [],
errors: {
plan: plan.status === 'rejected' ? plan.reason : null,
products: products.status === 'rejected' ? products.reason : null,
workOrders: workOrders.status === 'rejected' ? workOrders.reason : null
}
};
console.log('Complete plan data:');
console.log(`- Plan: ${completePlan.plan ? '✅ Available' : '❌ Not found'}`);
console.log(`- Products: ${completePlan.products.length} items`);
console.log(`- Work orders: ${completePlan.workOrders.length} orders`);
if (completePlan.errors.plan) {
console.log(`- Plan error: ${(completePlan.errors.plan as Error).message}`);
}
if (completePlan.errors.products) {
console.log(`- Products error: ${(completePlan.errors.products as Error).message}`);
}
if (completePlan.errors.workOrders) {
console.log(`- Work orders error: ${(completePlan.errors.workOrders as Error).message}`);
}
}
// Search for items containing "pump" in the name
console.log('\\nSearching for items containing "pump"...');
const itemsResponse = await client.getItems();
const searchTerm = 'pump'.toLowerCase();
const pumpItems = itemsResponse.data.items.filter((item: any) =>
item.itemcode.toLowerCase().includes(searchTerm) ||
item.description.toLowerCase().includes(searchTerm) ||
item.itemgroup.toLowerCase().includes(searchTerm)
);
console.log(`Found ${pumpItems.length} items containing "pump"`);
pumpItems.slice(0, 3).forEach((item: any) => {
console.log(` - ${item.itemcode}: ${item.description}`);
});
// Get low stock items
console.log('\\nChecking for low stock items...');
const lowStockItems = itemsResponse.data.items.filter((item: any) => item.onhand < item.min);
console.log(`Found ${lowStockItems.length} items with low stock`);
lowStockItems.slice(0, 5).forEach((item: any) => {
console.log(` ⚠️ ${item.itemcode}: ${item.onhand}/${item.min} (${item.description})`);
});
} catch (error: unknown) {
if (error instanceof Error) {
console.error('Error using utility functions:', error.message);
} else {
console.error('Unknown error using utility functions:', error);
}
}
}
// ============================================================================
// Example 6: Static Endpoint Functions
// ============================================================================
async function staticEndpointFunctions() {
console.log('\\n=== Client Instance Functions ===');
const client = createClient({ baseUrl: 'http://localhost:3001' });
try {
// Use client instance functions
const health = await client.getHealth();
console.log(`Health check: ${health.data.status}`);
const plans = await client.getPlans();
console.log(`Plans query: ${plans.metadata.count} plans`);
const items = await client.getItems();
console.log(`Items query: ${items.metadata.count} items`);
// Get sales data with date range
const sales = await client.getSales({
from: '2025-01-01',
to: '2025-03-31'
});
console.log(`Sales query: ${sales.metadata.count} sales`);
// Get user information
try {
const user = await client.getUser('USER001');
console.log(`User lookup: User ID ${user.data.userId} for username ${user.metadata.username}`);
} catch (error: unknown) {
if (error instanceof Error) {
console.log('User lookup failed (user may not exist):', error.message);
} else {
console.log('User lookup failed (user may not exist):', error);
}
}
} catch (error: unknown) {
if (error instanceof Error) {
console.error('Error using client functions:', error.message);
} else {
console.error('Unknown error using client functions:', error);
}
}
}
// ============================================================================
// Main Execution
// ============================================================================
async function runAllExamples() {
console.log('🚀 HANA Query API Client - Basic Usage Examples');
console.log('='.repeat(60));
try {
await basicClientUsage();
await workingWithItems();
await productionPlanningWorkflow();
await environmentSpecificClients();
await usingUtilityFunctions();
await staticEndpointFunctions();
console.log('\\n✅ All examples completed successfully!');
} catch (error: unknown) {
if (error instanceof Error) {
console.error('\\n❌ Example execution failed:', error);
} else {
console.error('\\n❌ Example execution failed:', error);
}
}
}
// Run examples if this file is executed directly
if (import.meta.url === `file://${process.argv[1]}`) {
runAllExamples().catch(console.error);
}
export {
basicClientUsage,
workingWithItems,
productionPlanningWorkflow,
environmentSpecificClients,
usingUtilityFunctions,
staticEndpointFunctions,
runAllExamples
};