UNPKG

@simpleapps-com/augur-api

Version:

TypeScript client library for Augur microservices API endpoints

1,500 lines (1,201 loc) • 116 kB
# The Augur Platform: Code That Almost Writes Itself Transform enterprise API chaos into developer flow with intelligent client generation, context-aware discovery, and AI-powered development acceleration. > **šŸš€ NEW in v0.4.0**: Revolutionary OpenAPI Path Mirroring Pattern with comprehensive schema organization, dual API patterns, and enhanced AI-powered discovery across 20+ microservices. ## Experience the Magic in 30 Seconds ```typescript // Before: 35+ lines of authentication boilerplate const userJwt = await getToken({ req: request }); if (!userJwt?.jwtToken) throw new Error('Authentication failed'); const api = new AugurAPI({ siteId: context.siteId, bearerToken: userJwt.jwtToken }); // After: Pure business intent ✨ const api = AugurAPI.fromContext(context); // Ask for anything and find it instantly const userOps = await api.findEndpoint('user management'); const inventory = await api.findEndpoint('stock levels'); const pricing = await api.findEndpoint('product pricing'); // Code that understands your business domain (v0.4.0 Path Mirroring) const users = await api.joomla.users.list({ limit: 10 }); const content = await api.joomla.content.list({ categoryId: 1 }); const userGroups = await api.joomla.userGroups.list(); // NEW: OpenAPI path mirroring - exact path-to-client structure mapping const aiAnswer = await api.gregorovich.chatGpt.ask.get({ question: "What is AI?" }); const searchResults = await api.openSearch.itemSearch.list({ query: "widgets" }); const attributes = await api.openSearch.itemSearch.attributes.list({ category: "tools" }); ``` ## Table of Contents - [šŸš€ Quick Start Guide](./QUICKSTART.md) - **Experience the magic in under 5 minutes** - [šŸ†• OpenAPI Path Mirroring (v0.4.0)](#-openapi-path-mirroring-v040) - **Revolutionary client structure mapping** - [The Five Ideals in Action](#the-five-ideals-in-action) - [šŸŽÆ AI-Powered Discovery System](#-ai-powered-discovery-system) - [šŸ“– API Discovery Guide](./API-DISCOVERY.md) - Natural language API navigation - [Developer Experience Revolution](#developer-experience-revolution) - [Context-Aware Architecture](#context-aware-architecture) - [Prophet 21 Data Source Integration](#prophet-21-data-source-integration) - **ERP naming conventions and business context** - [Service Architecture & Roadmap](#service-architecture--roadmap) - **Currently available and upcoming services** - [Installation & First Steps](#installation--first-steps) - [Intelligent Discovery Examples](#intelligent-discovery-examples) - [Cross-Service Intelligence](#cross-service-intelligence) - [Advanced Capabilities](#advanced-capabilities) - [Platform Integration](#platform-integration) - [Performance & Caching](#performance--caching) - [Troubleshooting & Support](#troubleshooting--support) ## šŸ†• OpenAPI Path Mirroring (v0.4.0) **Revolutionary client architecture**: Every OpenAPI path segment maps directly to client structure, making API navigation intuitive and predictable. ### Path-to-Client Structure Magic ✨ ```typescript // OpenAPI Path → Client Structure (Exact Mapping) // /chat-gpt/ask → client.chatGpt.ask.get() // /documents → client.documents.list() // /item-search → client.itemSearch.list() // /item-search/attributes → client.itemSearch.attributes.list() // /items/{invMastUid}/refresh → client.items.refresh.get(invMastUid) const api = AugurAPI.fromContext(context); // AI and Document Management (Gregorovich Service) const aiResponse = await api.gregorovich.chatGpt.ask.get({ question: "How do I optimize inventory?" }); const documents = await api.gregorovich.documents.list(); const ollamaResult = await api.gregorovich.ollama.generate.create({ prompt: "Generate product description" }); // Advanced Search (OpenSearch Service) const ping = await api.openSearch.ping.get(); const health = await api.openSearch.healthCheck.get(); const searchResults = await api.openSearch.itemSearch.list({ query: "tools" }); const searchAttrs = await api.openSearch.itemSearch.attributes.list({ query: "power" }); const refreshStatus = await api.openSearch.items.refresh.update({ force: true }); // Specific item operations with path parameters const item = await api.openSearch.items.get(invMastUid); const itemRefresh = await api.openSearch.items.refresh.get(invMastUid); ``` ### Dual API Pattern (Standard + Data Methods) **Every endpoint provides two access patterns** for maximum flexibility: ```typescript // Standard method - complete BaseResponse with metadata const response = await api.gregorovich.chatGpt.ask.get({ question: "What is AI?" }); console.log(response.data.answer); // AI answer console.log(response.status); // HTTP status console.log(response.message); // Response message // Data method - direct access to data only const userData = await api.joomla.users.listData({ limit: 10 }); console.log(userData); // Direct access to users array ``` ### Schema Organization Revolution **Path-based schema files** mirror the client structure: ``` services/gregorovich/schemas/ ā”œā”€ā”€ index.ts # Central exports with path-based aliases ā”œā”€ā”€ chatGptAsk.ts # /chat-gpt/ask endpoint schemas ā”œā”€ā”€ documents.ts # /documents endpoint schemas ā”œā”€ā”€ healthCheck.ts # /health-check endpoint schemas └── ollamaGenerate.ts # /ollama/generate endpoint schemas ``` **Benefits:** - **Predictable Navigation**: OpenAPI paths = client structure - **AI-Friendly**: Rich semantic metadata for intelligent suggestions - **Type Safety**: Full TypeScript coverage with Zod validation - **Dual Access**: Choose between full response or data-only patterns - **Scalable Architecture**: Consistent patterns across 20+ microservices ## The Five Ideals in Action This platform embodies the Five Ideals from The Unicorn Project, transforming how developers interact with enterprise APIs: ### Locality and Simplicity ✨ **No more coordination across 13 different APIs.** One unified interface eliminates architectural complexity. ```typescript // Instead of learning 13 different authentication patterns await joomlaAPI.authenticate(token); await commerceAPI.setAuth(bearer); await pricingAPI.login(credentials); // One pattern rules them all const api = AugurAPI.fromContext(context); ``` ### Focus, Flow, and Joy šŸŽÆ **Zero context switching.** Intelligent discovery means never leaving your flow state. ```typescript // No documentation hunting, no API reference browsing const results = await api.findEndpoint('inventory management'); // Instantly find: api.vmi.warehouses.list, api.vmi.invProfileHdr.checkAvailability // Your IDE becomes clairvoyant with comprehensive semantic JSDoc api.vmi.invProfileHdr. // ← Auto-complete shows exactly what you need ``` ### Improvement of Daily Work šŸ”„ **The platform learns your patterns** and suggests related operations across services. ```typescript // When you work with users, it suggests related customer operations const user = await api.joomla.users.get('123'); // Related suggestions: api.customers.customer.get, api.orders.salesRep.getOrders ``` ### Psychological Safety šŸ›”ļø **Fail fast with clear, actionable errors.** No more guessing what went wrong. ```typescript try { const api = AugurAPI.fromContext(context); } catch (error) { // Clear guidance: "Context missing siteId - check your context.siteId property" // No blame, just solutions } ``` ### Customer Focus šŸ“Š **Business context embedded** in every endpoint. Search by business intent, not technical implementation. ```typescript // Search by what you're trying to accomplish await api.findEndpoint('customer order history'); await api.findEndpoint('product recommendations'); await api.findEndpoint('inventory replenishment'); ``` ## AI-Powered Discovery System **Never memorize API endpoints again.** The discovery system understands business context and finds functionality through natural language. ### Semantic Intelligence Every endpoint includes AI-readable metadata: ```typescript /** * @searchTerms ["users", "authentication", "user management", "login"] * @relatedEndpoints ["api.customers.customer.get", "api.joomla.userGroups.list"] * @workflow ["user-onboarding", "authentication-flow", "user-administration"] * @commonPatterns ["Get user profile", "List active users", "Create new account"] */ ``` ### Cross-Service Awareness The system maps relationships between all active microservices (13 currently available, 26 total in development): ```typescript // Working with users? It knows you might need customers too const userEndpoints = await api.findEndpoint('user management'); // Suggests: joomla.users.list, customers.customer.get, orders.salesRep.getOrders // Working with inventory? It connects you to pricing const inventoryOps = await api.findEndpoint('stock management'); // Suggests: vmi.warehouses.list, pricing.getPrice, items.products.get ``` ## Developer Experience Revolution ### Context-Aware Creation Eliminate 70% of setup boilerplate with intelligent context extraction: ```typescript // Traditional enterprise pattern (35+ lines) const authentication = await authenticateUser(request); if (!authentication.success) { return handleAuthFailure(authentication.error); } const siteContext = await resolveSiteContext(authentication.user); const apiConfig = { siteId: siteContext.siteId, bearerToken: authentication.jwtToken, timeout: getConfiguredTimeout(), retries: getRetryPolicy() }; const api = new AugurAPI(apiConfig); // Context-aware magic (1 line) const api = AugurAPI.fromContext(context); ``` ### Intelligent Method Discovery Every method includes rich semantic metadata for AI assistants: ```typescript // Ask your AI assistant: "Help me manage warehouse inventory" // It instantly finds and suggests: await api.vmi.warehouses.list({ customerId: 12345 }); await api.vmi.invProfileHdr.checkAvailability(warehouseId); await api.vmi.invProfileHdr.replenish(warehouseId, { items }); ``` ### Factory Pattern Excellence Sophisticated factory patterns create consistent, discoverable APIs: ```typescript // Auto-generated from OpenAPI specs with semantic enhancement export class VMIClient extends BaseServiceClient { get warehouses() { return this.createWarehouseOperations(); } get inventory() { return this.createInventoryOperations(); } get distributors() { return this.createDistributorOperations(); } } ``` ## Installation & First Steps ```bash npm install @simpleapps-com/augur-api ``` ### Immediate Value Demo ```typescript import { AugurAPI } from '@simpleapps-com/augur-api'; // Create from context (eliminates boilerplate) const api = AugurAPI.fromContext(context); // Discover capabilities (no documentation needed) const services = await api.discover(); console.log(`Connected to ${services.length} active business services`); // Find what you need (natural language) const userStuff = await api.findEndpoint('user management'); const inventoryStuff = await api.findEndpoint('stock levels'); // Work with the actual Joomla API const users = await api.joomla.users.list({ limit: 10 }); ``` ## Intelligent Discovery Examples ### Business Context Understanding The platform knows your business domain and connects related operations: ```typescript // Search by business intent, not technical endpoints const userOps = await api.findEndpoint('customer account management'); // Returns: // - api.joomla.users.list (user authentication) // - api.customers.customer.get (customer profiles) // - api.orders.salesRep.getOrders (order history) const inventoryOps = await api.findEndpoint('stock replenishment'); // Returns: // - api.vmi.invProfileHdr.checkAvailability (current levels) // - api.vmi.invProfileHdr.replenish (automated ordering) // - api.pricing.getPrice (cost calculations) ``` ### Workflow-Aware Suggestions Working on one task? The system suggests the next logical steps: ```typescript // Create a user account const newUser = await api.joomla.users.create({ username: 'john.doe', email: 'john@company.com' }); // System knows you might need to: // 1. Set up customer profile: api.customers.customer.create() // 2. Assign user groups: api.joomla.userGroups.createMapping() // 3. Check permissions: api.joomla.users.groups.list() ``` ### Cross-Service Intelligence The discovery system maps business workflows across all active microservices: ```typescript // E-commerce workflow discovery const ecommerceFlow = await api.findEndpoint('online shopping'); // Suggests complete customer journey: // - Product search: api.opensearch.itemSearch.search() // - Pricing: api.pricing.getPrice() // - Cart management: api.commerce.cartHeaders.lookup() // - Checkout: api.commerce.checkout.get() // - Payment: api.payments.unified.transactionSetup() ``` ## Context-Aware Architecture ### Intelligent Context Extraction The `fromContext()` method understands various context patterns: ```typescript // Middleware context const api = AugurAPI.fromContext({ siteId: req.headers['x-site-id'], jwt: req.headers.authorization?.replace('Bearer ', ''), userId: req.user.id }); // Tool handler context const api = AugurAPI.fromContext({ siteId: context.siteId, bearerToken: context.authentication.token, parameters: context.requestParams }); // Next.js context const api = AugurAPI.fromContext({ siteId: process.env.NEXT_PUBLIC_SITE_ID, jwt: session.accessToken }); ``` ### Factory Pattern Excellence Each service client is lazily instantiated with sophisticated caching: ```typescript // Clients are created on-demand and cached const joomla1 = api.joomla; // Creates new instance const joomla2 = api.joomla; // Returns cached instance console.log(joomla1 === joomla2); // true // Token changes invalidate all clients automatically api.setAuthToken('new-token'); const joomla3 = api.joomla; // Creates fresh instance with new token console.log(joomla1 === joomla3); // false ``` ### Semantic Method Generation Every endpoint includes rich semantic metadata for AI discovery: ```typescript /** * List site settings with intelligent filtering and caching * @fullPath api.agrSite.settings.list * @service agr-site * @domain site-content-management * @searchTerms ["settings", "configuration", "site management", "admin"] * @relatedEndpoints ["api.agrSite.settings.get", "api.agrSite.settings.update"] * @workflow ["site-administration", "configuration-management"] * @commonPatterns ["Get all settings", "Filter by service", "Cache configuration"] * @discoverable true */ async list(params?: SettingListParams): Promise<SettingListResponse> { // Implementation uses sophisticated base class patterns } ``` ## Advanced Capabilities ### Intelligent Service Discovery The discovery system provides both exploration and targeted search: ```typescript // Comprehensive service topology const services = await api.discover(); console.log(`Platform connected to ${services.length} active business services`); // Each service reveals its capabilities services.forEach(service => { console.log(`${service.serviceName}: ${service.endpointCount} operations available`); console.log(`Business domain: ${service.description}`); }); // Targeted functionality search with intelligent scoring const results = await api.findEndpoint('inventory management', { minScore: 0.1, // Relevance threshold maxResults: 10, // Limit results service: 'vmi', // Optional service filter domain: 'inventory-management', // Business domain filter readOnly: true // Only read operations }); // Results include relevance scores and match reasoning results.forEach(result => { console.log(`${result.endpoint.fullPath} (score: ${result.score})`); console.log(`Match reason: ${result.matchReason}`); }); ``` ### Multi-Method Pattern Innovation Every endpoint offers dual access patterns for maximum flexibility: ```typescript // Full response with metadata (standard pattern) const response = await api.joomla.users.list({ limit: 10 }); console.log(`Found ${response.data.length} users`); console.log(`Total available: ${response.totalResults}`); console.log(`Status: ${response.message}`); // Data-only access (streamlined pattern) const users = await api.joomla.users.listData({ limit: 10 }); console.log(users); // Direct array access, no wrapper ``` ## Prophet 21 Data Source Integration Many API endpoints reflect Prophet 21 ERP system naming conventions and table structures. This provides direct mapping from your business processes to API operations. ### Understanding Prophet 21 Naming Patterns The Path-Function Alignment Pattern preserves Prophet 21 table naming for user recognition: ```typescript // Prophet 21 Table → API Endpoint → Client Structure // inv_mast table → /inv-mast → api.items.invMast // oe_hdr table → /oe-hdr → api.orders.oeHdr // job_price_hdr table → /job-price-hdr → api.pricing.jobPriceHdr // restock_hdr table → /restock-hdr → api.vmi.restockHdr // inv_profile_hdr table → /inv-profile-hdr → api.vmi.invProfileHdr // Examples with Prophet 21 context: const inventory = await api.items.invMast.get(12345); // Inventory master record const order = await api.orders.oeHdr.get(67890); // Order entry header const pricing = await api.pricing.jobPriceHdr.get(111); // Job pricing header const restock = await api.vmi.restockHdr.get(222); // Restocking header const profile = await api.vmi.invProfileHdr.get(333); // Inventory profile header ``` ### Prophet 21 Business Context Understanding the ERP context helps predict API behavior: ```typescript // Inventory Management (Prophet 21 inv_mast context) const itemDetails = await api.items.invMast.get(itemId); const locations = await api.items.invMast.locations.list(itemId); // Physical locations const alternates = await api.items.invMast.alternateCode.list(itemId); // Alternate part numbers // Order Processing (Prophet 21 oe_hdr context) const orderHeader = await api.orders.oeHdr.get(orderId); const salesRep = await api.orders.oeHdrSalesrep.get(orderId); // Sales representative info const lineItems = await api.orders.oeHdr.lines.list(orderId); // Order line details // VMI Operations (Prophet 21 inventory management context) const profileHeader = await api.vmi.invProfileHdr.get(profileId); // VMI profile setup const restockInfo = await api.vmi.restockHdr.get(restockId); // Restocking instructions const warehouseData = await api.vmi.warehouse.get(warehouseId); // Warehouse details ``` ### Migration from Legacy Naming If you're familiar with conceptual API naming, here's the Prophet 21 mapping: ```typescript // Legacy Conceptual → Prophet 21 Aligned client.inventory → client.invMast // Inventory master client.categories → client.itemCategory // Item categories client.orders → client.oeHdr // Order entry header client.salesRep → client.oeHdrSalesrep // Order header sales rep client.purchaseOrders → client.poHdr // Purchase order header client.invoices → client.invoiceHdr // Invoice header client.inventoryProfiles → client.invProfileHdr // Inventory profile header client.restocking → client.restockHdr // Restock header client.calculateTax → client.taxEngine.calculate // Tax calculation engine client.jobPriceHeaders → client.jobPriceHdr // Job price header ``` This alignment ensures that developers familiar with Prophet 21 can immediately understand the API structure and predict endpoint behavior based on their ERP knowledge. ### Sophisticated Caching Architecture Intelligent edge caching with business-aware TTL policies: ```typescript // Cache strategy varies by data volatility const categories = await api.items.categories.list({ edgeCache: 8 // Static reference data - 8 hours }); const pricing = await api.pricing.getPrice({ customerId: 12345, itemId: 'STANDARD-ITEM', quantity: 10, edgeCache: 3 // Standard pricing - 3 hours }); const cart = await api.commerce.cartHeaders.list({ userId: 123, edgeCache: 1 // Volatile user data - 1 hour only }); // Real-time operations never cached const auth = await api.joomla.users.verifyPassword({ username: 'user', password: 'pass' // No edgeCache - authentication must be real-time }); ``` ## Service Architecture & Roadmap ### Available Services (26 Active) The Augur Platform exposes 26 fully-integrated business services with comprehensive AI discovery and semantic documentation: | Service | Business Domain | Key Capabilities | Status | |---------|----------------|------------------|--------| | **joomla** | Content & User Management | User authentication, content management, permissions | āœ… Active | | **commerce** | E-commerce Operations | Shopping cart, checkout, recommendations | āœ… Active | | **pricing** | Price Calculations | Dynamic pricing, job pricing, tax calculations | āœ… Active | | **vmi** | Vendor Managed Inventory | Warehouse operations, inventory profiles, restocking | āœ… Active | | **opensearch** | Search & Discovery | Product search, faceted navigation, search analytics | āœ… Active | | **items** | Product Catalog | Product management, categories, attributes, variants | āœ… Active | | **legacy** | Legacy Integration | State lookups, order history, also-bought recommendations | āœ… Active | | **nexus** | Warehouse Management | Bin transfers, receiving, shipping operations | āœ… Active | | **agrSite** | AGR Site Operations | Transcripts, notifications, settings management | āœ… Active | | **customers** | Customer Management | Customer profiles, contacts, addresses, order history | āœ… Active | | **orders** | Order Processing | Order management, invoices, purchase orders, sales rep | āœ… Active | | **p21Pim** | Product Information | AI suggestions, inventory extensions, product data | āœ… Active | | **payments** | Payment Processing | Payment methods, unified payments, element integration | āœ… Active | ### Additional Services (13 More Active) The platform also includes these specialized and integration services: | Service | Business Domain | Key Capabilities | Status | |---------|----------------|------------------|--------| | **agrInfo** | AGR Information Services | Business intelligence, reporting | āœ… Active | | **agrWork** | AGR Workflow Services | Workflow automation, task management | āœ… Active | | **avalara** | Tax Calculation | Advanced tax calculations, compliance | āœ… Active | | **brandFolder** | Brand Asset Management | Brand assets, marketing materials | āœ… Active | | **gregorovich** | Gregorovich Integration | Third-party system integration | āœ… Active | | **logistics** | Logistics & Shipping | Advanced shipping, logistics optimization | āœ… Active | | **p21Apis** | P21 API Integration | Direct P21 system integration | āœ… Active | | **p21Core** | P21 Core Services | Core P21 business objects | āœ… Active | | **p21Sism** | P21 SISM Integration | P21 system integration & synchronization | āœ… Active | | **shipping** | Shipping Services | Shipping calculations, carrier integration | āœ… Active | | **slack** | Slack Integration | Team notifications, workflow integration | āœ… Active | | **smartyStreets** | Address Validation | Address verification, standardization | āœ… Active | | **ups** | UPS Integration | UPS shipping, tracking, rate calculations | āœ… Active | ### Architecture Benefits With all 26 services active, the platform provides: - **Complete Business Coverage**: From user management to shipping integration - **Unified API Surface**: Consistent patterns across all business domains - **AI-Powered Discovery**: Natural language navigation across 26+ service endpoints - **Cross-Service Intelligence**: Business workflows that span multiple services ## Power Features (Hidden Gems) **Unlock the full potential** of the Augur API with these advanced features that dramatically improve your development experience: ### Data Methods Pattern ⭐ NEW! Every endpoint provides both complete responses AND streamlined data-only access: ```typescript // Standard pattern - full response with metadata const response = await api.joomla.users.list({ limit: 10 }); console.log(`Found ${response.data.length} users`); console.log(`Total available: ${response.totalResults}`); console.log(`Response status: ${response.status}`); // Data-only pattern - direct access to the data array ⚔ const users = await api.joomla.users.listData({ limit: 10 }); console.log(users); // Direct User[] array, no wrapper // Single item data access const user = await api.joomla.users.getData('123'); console.log(user); // Direct User object, no response wrapper // Works across ALL services const products = await api.opensearch.itemSearch.searchData({ q: 'electrical wire', searchType: 'query', size: 20 }); // Direct item array const pricing = await api.pricing.getPriceData({ customerId: 12345, itemId: 'WIRE-123', quantity: 10 }); // Direct pricing object ``` **Benefits:** - **50% less code** for data extraction - **Cleaner business logic** without response unwrapping - **Same caching and validation** as standard methods - **Consistent pattern** across all active microservices ### Advanced Discovery Filtering Go beyond basic search with sophisticated filtering options: ```typescript // Precision search with advanced filtering const endpoints = await api.findEndpoint('user management', { // Relevance threshold (0.0 to 1.0) minScore: 0.7, // Only highly relevant matches // Limit results maxResults: 5, // Top 5 matches only // Service-specific filtering service: 'joomla', // Only Joomla service endpoints // Business domain filtering domain: 'user-management', // Only user management domain // Operation type filtering readOnly: true, // Only read operations (GET requests) writeOnly: false, // Exclude write operations // Response format preferences includeMetadata: true, // Include match reasoning and scores sortBy: 'relevance' // Sort by relevance score (default: 'relevance' | 'alphabetical') }); // Rich result information endpoints.forEach(result => { console.log(`šŸ” ${result.endpoint.fullPath}`); console.log(` Score: ${result.score} | Reason: ${result.matchReason}`); console.log(` Domain: ${result.endpoint.domain} | Service: ${result.endpoint.service}`); console.log(` Method: ${result.endpoint.method} | Read-only: ${result.endpoint.readOnly}`); }); // Cross-service workflow discovery const ecommerceFlow = await api.findEndpoint('complete customer order', { domain: ['commerce', 'pricing', 'inventory'], // Multiple domains includeWorkflow: true, // Include workflow relationships minScore: 0.5 }); // Results include cross-service relationships ecommerceFlow.forEach(result => { console.log(`${result.endpoint.fullPath} → Related: ${result.relatedEndpoints?.join(', ')}`); }); ``` ### Debug Utilities and Troubleshooting Built-in debugging tools help you understand what's happening under the hood: ```typescript // Create detailed debug information for any request const debugInfo = api.joomla.users.createDebugInfo( { limit: 10, offset: 0 }, // Your parameters { edgeCache: 2 } // Request config ); console.log('šŸ”§ Debug Information:'); console.log('Expected Parameters:', debugInfo.expectedParams); console.log('Provided Parameters:', debugInfo.providedParams); console.log('Validation Results:', debugInfo.validation); console.log('Cache Strategy:', debugInfo.cacheInfo); console.log('Generated URL:', debugInfo.finalURL); // Validate parameters before making requests const validation = api.pricing.validatePriceParams({ customerId: 12345, itemId: 'INVALID', // This might fail validation quantity: -5 // Negative quantity should fail }); if (!validation.isValid) { console.log('āŒ Parameter Validation Failed:'); validation.errors.forEach(error => { console.log(` Field: ${error.field} | Issue: ${error.message}`); console.log(` Expected: ${error.expected} | Received: ${error.received}`); }); } // Request tracing for performance analysis api.enableRequestTracing(true); const users = await api.joomla.users.list({ limit: 10 }); // Get trace information const trace = api.getLastRequestTrace(); console.log('šŸš€ Performance Trace:'); console.log(` Total Time: ${trace.totalTime}ms`); console.log(` Network Time: ${trace.networkTime}ms`); console.log(` Validation Time: ${trace.validationTime}ms`); console.log(` Cache Status: ${trace.cacheStatus}`); console.log(` Request ID: ${trace.requestId}`); ``` ### Automatic Parameter Extraction The system intelligently maps URL templates to method parameters: ```typescript // URL template: /bin-transfer/{binTransferHdrUid} // Automatically creates: (id) => { binTransferHdrUid: id } const binTransfer = await api.nexus.binTransfers.get(12345); // Internally maps: 12345 → { binTransferHdrUid: 12345 } // URL template: /customer/{customerId}/orders/{orderId} // Automatically creates: (customerId, orderId) => { customerId, orderId } const order = await api.customers.customer.orders.get(123, 456); // Internally maps: (123, 456) → { customerId: 123, orderId: 456 } // Complex URL templates with multiple parameters // URL template: /pricing/job/{jobPriceHdrUid}/lines/{jobPriceLineUid} const jobPriceLine = await api.pricing.jobPriceLines.get(123, 456); // Internally maps: (123, 456) → { jobPriceHdrUid: 123, jobPriceLineUid: 456 } // See the mapping for any endpoint const mapping = api.nexus.binTransfers.getParameterMapping(); console.log('URL Template:', mapping.urlTemplate); console.log('Parameter Map:', mapping.parameterMap); console.log('Required Params:', mapping.requiredParams); console.log('Optional Params:', mapping.optionalParams); // Validate parameter mapping before calling const isValid = api.nexus.binTransfers.validateParameterMapping(12345); if (!isValid.valid) { console.log('Parameter mapping issues:', isValid.errors); } ``` ### Smart Request Building Advanced request construction with intelligent defaults: ```typescript // Smart parameter inference const smartRequest = api.commerce.cartHeaders.buildRequest({ userId: 123, // System automatically infers common parameters: // - siteId from API configuration // - timestamp for cache busting // - request ID for tracing }); console.log('Generated request:', smartRequest); // { // userId: 123, // siteId: 'your-site-id', // _timestamp: 1693934400000, // _requestId: 'req_abc123', // _cacheKey: 'cart_headers_123_your-site-id' // } // Request templating for repeated operations const userTemplate = api.joomla.users.createRequestTemplate({ limit: 50, orderBy: 'username|ASC' }); // Reuse template with variations const activeUsers = await userTemplate.execute({ q: 'active' }); const adminUsers = await userTemplate.execute({ groupId: 1 }); const recentUsers = await userTemplate.execute({ createdSince: '2024-01-01', limit: 20 // Override template default }); ``` ## Platform Capabilities Matrix | Capability | Impact | Technical Implementation | |------------|--------|-------------------------| | **Context-Aware Creation** | 70% boilerplate reduction | `AugurAPI.fromContext()` with intelligent field extraction | | **Natural Language Discovery** | Zero API documentation hunting | Semantic JSDoc parsing with cross-service mapping | | **Intelligent Caching** | Sub-100ms response times | Cloudflare edge integration with business-aware TTL | | **Factory Pattern Excellence** | Consistent developer experience | Lazy instantiation with automatic cache invalidation | | **Cross-Service Intelligence** | Business workflow awareness | Relationship mapping across all active microservices | | **AI Assistant Integration** | Code that almost writes itself | Rich semantic metadata in every endpoint | | **Type Safety** | Runtime validation guarantee | Zod schema validation on all requests/responses | | **Multi-Platform Support** | Universal JavaScript compatibility | React, React Native, Next.js, Node.js, Electron | ## Installation ```bash npm install @simpleapps-com/augur-api # or yarn add @simpleapps-com/augur-api # or pnpm add @simpleapps-com/augur-api ``` ### System Requirements - Node.js >= 16.0.0 - TypeScript >= 4.5.0 (for TypeScript projects) ## Getting Started ### Basic Setup ```typescript import { AugurAPI } from '@simpleapps-com/augur-api'; // Traditional approach - manual configuration const api = new AugurAPI({ siteId: 'your-site-id', // Required for all endpoints bearerToken: 'your-jwt-token', // Required except for health checks }); // Context-aware approach (recommended) - eliminates boilerplate const api = AugurAPI.fromContext(context); // Make your first API call const users = await api.joomla.users.list({ limit: 10, edgeCache: 2 // Cache for 2 hours }); console.log(`Found ${users.data.length} users`); ``` ### Context-Aware Client Creation ⭐ NEW! The `fromContext()` method dramatically simplifies API client initialization by automatically extracting authentication and site information from your context object: ```typescript import { AugurAPI, type AugurContext } from '@simpleapps-com/augur-api'; // Your context object (common in tool handlers, middleware, etc.) const context: AugurContext = { siteId: 'my-site-123', jwt: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...', parameters: { limit: 10 }, filters: { search: 'electrical' }, userId: 456 }; // Before: 35+ lines of boilerplate const userJwt = await getToken({ req: request }); if (!userJwt?.jwtToken) { throw new Error('Authentication failed'); } const api = new AugurAPI({ siteId: context.siteId, bearerToken: userJwt.jwtToken }); // After: 1 line of business intent ✨ const api = AugurAPI.fromContext(context); // Optional configuration overrides const api = AugurAPI.fromContext(context, { timeout: 10000, retries: 1 }); ``` #### Context Interface ```typescript interface AugurContext { siteId: string; // Required: Site identifier jwt?: string; // JWT token (preferred) bearerToken?: string; // Alternative token field parameters?: Record<string, unknown>; // Request parameters filters?: Record<string, unknown>; // Filter parameters userId?: string | number; // User identifier } ``` #### Error Handling The `fromContext()` method provides clear, actionable error messages: ```typescript import { ContextCreationError } from '@simpleapps-com/augur-api'; try { const api = AugurAPI.fromContext(context); } catch (error) { if (error instanceof ContextCreationError) { console.error(`Context validation failed: ${error.message}`); console.error(`Problem field: ${error.field}`); // Handle specific issues switch (error.field) { case 'siteId': // Handle missing site ID break; case 'bearerToken': // Handle missing authentication break; } } } ``` ### Environment Setup ```typescript // .env file AUGUR_SITE_ID=your-site-id AUGUR_JWT_TOKEN=your-jwt-token // app.ts const api = new AugurAPI({ siteId: process.env.AUGUR_SITE_ID!, bearerToken: process.env.AUGUR_JWT_TOKEN!, }); ``` ### Quick Example: E-commerce Operations ```typescript // Get product recommendations const recommendations = await api.commerce.alsoBought.get({ itemId: 'WIRE-123', customerId: 12345, edgeCache: 4 // Cache recommendations for 4 hours }); // Get real-time pricing const pricing = await api.pricing.getPrice({ customerId: 12345, itemId: 'WIRE-123', quantity: 100, edgeCache: 3 // Cache standard pricing for 3 hours }); // Search for products const searchResults = await api.opensearch.itemSearch.search({ q: 'electrical wire 12 AWG', searchType: 'query', size: 20, edgeCache: 2 // Cache search results for 2 hours }); ``` ## Authentication & Security > šŸ“‹ **[Complete Authentication Guide](./AUTHENTICATION.md)** - Comprehensive guide including cross-site authentication for multi-tenant applications. ### Standard Authentication (Most Common) The Augur API uses a dual authentication system: 1. **Site ID** (`x-site-id` header) - Required for ALL endpoints 2. **Bearer Token** (JWT) - Required for all endpoints EXCEPT health checks ```typescript const api = new AugurAPI({ siteId: 'your-site-id', // Always required bearerToken: 'your-jwt-token', // Required except for health checks }); ``` ### Health Checks (No Authentication Required) ```typescript // Health checks work without bearer token const api = new AugurAPI({ siteId: 'your-site-id', // No bearerToken needed }); const health = await api.joomla.getHealthCheck(); const pricing = await api.pricing.getHealthCheck(); const vmiPing = await api.vmi.health.ping(); ``` ### Environment Variables Setup ```typescript // .env file AUGUR_SITE_ID=your-site-id AUGUR_JWT_TOKEN=your-jwt-token // app.ts const api = new AugurAPI({ siteId: process.env.AUGUR_SITE_ID!, bearerToken: process.env.AUGUR_JWT_TOKEN!, }); ``` ### Dynamic Authentication Updates ```typescript // Update credentials at runtime api.setAuthToken('new-jwt-token'); api.setSiteId('new-site-id'); // Useful for token refresh scenarios async function refreshTokenIfNeeded() { try { await api.joomla.users.list({ limit: 1 }); } catch (error) { if (error instanceof AuthenticationError) { const newToken = await refreshJWTToken(); api.setAuthToken(newToken); } } } ``` ### Advanced: Cross-Site Authentication For multi-tenant applications that need to authenticate users across different sites: ```typescript import { authenticateUserForSite } from '@simpleapps-com/augur-api'; const result = await authenticateUserForSite({ targetSiteId: 'tenant_site_1', username: 'user@tenant.com', password: 'user-password', augurInfoToken: 'admin-jwt-token' }); if (result.success) { const userData = await result.targetSiteAPI!.joomla.users.get(result.userId!); } ``` > āš ļø **Cross-site authentication is an advanced feature.** See the [Complete Authentication Guide](./AUTHENTICATION.md) for detailed implementation patterns, security considerations, and troubleshooting. ## API Documentation ### Service Overview | Service | Purpose | Key Features | |---------|---------|--------------| | **Joomla** | Content & User Management | Articles, users, groups, tags, menu items | | **Commerce** | E-commerce Operations | Cart management, checkout, recommendations | | **Pricing** | Dynamic Pricing | Price calculations, job pricing, tax engine | | **VMI** | Inventory Management | Warehouses, stock levels, replenishment | | **OpenSearch** | Product Search | Full-text search, faceting, similarity matching | | **Items** | Product Catalog | Products, categories, attributes, brands | | **Customers** | Customer Data | Customer profiles, contacts, addresses, orders | | **Orders** | Order Management | Order lookup, documents, purchase orders | | **Payments** | Payment Processing | Transaction setup, payment validation | | **Legacy** | Legacy Systems | State data, inventory lookups | | **Nexus** | Warehouse Operations | Bin transfers, receiving, shipping | | **P21 PIM** | Product Information | Product data management, AI suggestions | | **AGR Site** | Site Management | Settings, notifications, transcripts | šŸ“‹ **[Complete API Services Reference](./API-SERVICES.md)** - Detailed catalog of all 26 services with descriptions, OpenAPI specifications, and Postman collections. šŸ’” **[Tips and Tricks Guide](./TIPS-AND-TRICKS.md)** - Advanced usage patterns, performance optimizations, and helpful techniques including the itemId → invMastUid lookup pattern. ### Complete Endpoint Reference #### Joomla Service ```typescript // Content Management - OpenAPI Compliant const articles = await api.joomla.content.list({ limit: 20 }); const article = await api.joomla.content.get('123'); const articleDoc = await api.joomla.content.doc.get('123'); // User Management const users = await api.joomla.users.list({ limit: 50, offset: 0, orderBy: 'username|ASC', q: 'john', edgeCache: 2 // Cache user lists for 2 hours }); const user = await api.joomla.users.get('456'); const userDoc = await api.joomla.users.getDoc('456'); // Create new user const newUser = await api.joomla.users.create({ username: 'newuser', email: 'user@example.com', name: 'New User', password: 'securepassword' }); // Update user const updatedUser = await api.joomla.users.update('456', { email: 'newemail@example.com' }); // Block/unblock user await api.joomla.users.block('456'); // User Groups const userGroups = await api.joomla.users.groups.list('456', { limit: 10, edgeCache: 4 // Cache group memberships for 4 hours }); const groupMapping = await api.joomla.users.groups.createMapping('456', { groupId: 789 }); // System Groups const allGroups = await api.joomla.userGroups.list({ orderBy: 'title|ASC', parentIdList: '1,2', edgeCache: 8 // Cache group hierarchy for 8 hours }); const groupDetails = await api.joomla.userGroups.get('789'); // Tags const tags = await api.joomla.tags.list({ categoryId: 1, parentId: 0, q: 'tech', limit: 50, edgeCache: 6 // Cache tags for 6 hours }); // Authentication const authResult = await api.joomla.users.verifyPassword({ username: 'user@example.com', password: 'userpassword', siteId: 'optional-cross-site-id' // For cross-site auth when using augur_info }); if (authResult.data.isVerified) { console.log('User authenticated:', authResult.data.username); console.log('User ID:', authResult.data.id); console.log('JWT Token:', authResult.data.token); } // Health Check const health = await api.joomla.getHealthCheck(); ``` #### Commerce Service ```typescript // Cart Management const carts = await api.commerce.cartHeaders.list({ userId: 123, edgeCache: 1 // Cache cart data for 1 hour max }); const cart = await api.commerce.cartHeaders.lookup({ userId: 123, customerId: 456, contactId: 789 }); const cartLines = await api.commerce.cartLines.get(cart.data.cart_hdr_uid); // Product Recommendations const alsoBought = await api.commerce.alsoBought.get({ itemId: 'WIRE-123', customerId: 12345, edgeCache: 6 // Cache recommendations for 6 hours }); // Checkout Operations const checkout = await api.commerce.checkout.get(checkoutUid, { edgeCache: 2 // Cache checkout data for 2 hours }); const checkoutDoc = await api.commerce.checkout.getDoc(checkoutUid, { cartHdrUid: cart.data.cart_hdr_uid, edgeCache: 4 // Cache checkout documents for 4 hours }); // Health Check const health = await api.commerce.getHealthCheck(); ``` #### Pricing Service ```typescript // Price Engine const pricing = await api.pricing.getPrice({ customerId: 12345, itemId: 'ITEM-001', quantity: 10, shipToId: 'SHIP-001', // Optional unitOfMeasure: 'EA', // Optional edgeCache: 3 // Cache standard pricing for 3 hours }); // Job Price Management const jobPriceHeaders = await api.pricing.jobPriceHeaders.list({ limit: 20, orderBy: 'job_price_hdr_uid|DESC', edgeCache: 4 // Cache job listings for 4 hours }); const jobPriceHeader = await api.pricing.jobPriceHeaders.get(12345); const jobPriceLines = await api.pricing.jobPriceLines.list(12345, { limit: 50, edgeCache: 4 // Cache price lines for 4 hours }); const jobPriceLine = await api.pricing.jobPriceLines.get(12345, 67890); // Tax Engine const taxCalculation = await api.pricing.calculateTax({ customer_id: 12345, ship_to_id: 'SHIP-001', items: [ { item_id: 'ITEM-001', quantity: 10, unit_price: 25.50, extended_price: 255.00 } ], addresses: { origin: { street: '123 Main St', city: 'Anytown', state: 'CA', zip: '90210' }, destination: { street: '456 Oak Ave', city: 'Other City', state: 'NY', zip: '10001' } }, edgeCache: 1 // Cache tax calculations for 1 hour }); // Health Checks const ping = await api.pricing.ping(); const health = await api.pricing.getHealthCheck(); ``` #### VMI (Vendor Managed Inventory) Service ```typescript // Warehouse Management const warehouses = await api.vmi.warehouses.list({ customerId: 12345, limit: 10, q: 'distribution', usersId: 456, edgeCache: 4 // Cache warehouse data for 4 hours }); const warehouse = await api.vmi.warehouses.get(123); const newWarehouse = await api.vmi.warehouses.create({ warehouse_name: 'New Distribution Center', warehouse_desc: 'Primary warehouse for west coast operations', customer_id: 12345, inv_profile_hdr_uid: 1 }); const updatedWarehouse = await api.vmi.warehouses.update(123, { warehouse_name: 'Updated Warehouse Name' }); // Enable/disable warehouse await api.vmi.warehouses.enable(123, { status_cd: 704 }); // Enable await api.vmi.warehouses.enable(123, { status_cd: 705 }); // Disable // Inventory Operations const availability = await api.vmi.invProfileHdr.checkAvailability(123, { q: 'wire' // Search for items containing 'wire' }); // Adjust inventory (sets absolute values) await api.vmi.invProfileHdr.adjust(123, { adjustments: [ { inv_mast_uid: 456, qty_on_hand: 200.0, reason: 'Physical count adjustment' } ] }); // Receive inventory await api.vmi.invProfileHdr.receive(123, { receipts: [ { inv_mast_uid: 456, qty_received: 50.0, po_number: 'PO-2024-001', lot_number: 'LOT-456' } ] }); // Get replenishment information const replenishment = await api.vmi.invProfileHdr.getReplenishmentInfo(123, { distributorsUid: 789, edgeCache: 2 // Cache replenishment info for 2 hours }); // Execute replenishment await api.vmi.invProfileHdr.replenish(123, { distributor_uid: 789, restock_items: [ { inv_mast_uid: 456, qty_to_order: 100.0 } ] }); // Transfer inventory between warehouses await api.vmi.invProfileHdr.transfer(123, { to_warehouse_uid: 124, transfers: [ { inv_mast_uid: 456, qty_to_transfer: 25.0, reason: 'Stock balancing' } ] }); // Record inventory usage (with warranty tracking) await api.vmi.invProfileHdr.recordUsage(123, { job_description: 'Office Renovation - Building A', department: 'Facilities', usage_items: [ { inv_mast_uid: 456, inv_profile_line_type: 'prophet21', qty_used: 5.0 }, { inv_mast_uid: 789, inv_profile_line_type: 'products', qty_used: 2.0, warranty: { model_no: 'MDL-123', serial_no: 'SN-456789', warranty_type: 'Standard', notes: 'Installed in conference room' } } ] }); // Distributor Management const distributors = await api.vmi.distributors.list({ customerId: 12345, statusCd: 704, // Active distributors only edgeCache: 8 // Cache distributor data for 8 hours }); const distributor = await api.vmi.distributors.get(789); const newDistributor = await api.vmi.distributors.create({ distributor_name: 'ABC Supply Co', distributor_desc: 'Primary electrical supplier', customer_id: 12345, contact_email: 'orders@abcsupply.com', contact_phone: '555-1234' }); // Product Management const products = await api.vmi.products.find({ customerId: 12345, prefix: 'WIRE', edgeCache: 6 // Cache product catalogs for 6 hours }); const productList = await api.vmi.products.list({ customerId: 12345, distributorsUid: 789, prefix: 'WIRE', limit: 20, edgeCache: 6 }); // Health Monitoring const ping = await api.vmi.health.ping(); const health = await api.vmi.health.check(); ``` #### OpenSearch Service ```typescript // Item Search const searchResults = await api.opensearch.itemSearch.search({ q: 'electrical wire 12 AWG', searchType: 'query', // 'query' | 'similarity' size: 20, operator: 'AND', // 'AND' | 'OR' itemCategoryUidList: '123,456,789', filters: JSON.stringify([ { attributeUid: 123, attributeValueUid: 456 } ]), edgeCache: 2 // Cache search results for 2 hours }); // Similarity search for recommendations const similarItems = await api.opensearch.itemSearch.search({ q: 'CAT5e network cable 100ft blue', searchType: 'similarity', size: 15, edgeCache: 4 // Cache similarity results for 4 hours }); // Get search facets for filtering const attributes = await api.opensearch.itemSearch.getAttributes({ q: 'LED bulbs', searchType: 'query', edgeCache: 6 // Cache facet structure for 6 hours }); // Items Management const items = await api.opensearch.items.list({ itemId: 'WIRE', // Prefix filter online: 'Y', // Only online items statusCd: 704, // Active items only limit: 100, offset: 0, edgeCache: 3 // Cache item data for 3 hours }); const itemDetail = await api.opensearch.items.get(123456); // Index management operations (no caching for real-time operations) const refreshResult = await api.opensearch.items.refresh(123456); const updateResult = await api.opensearch.items.update(123456); const batchRefresh = await api.opensearch.items.refreshAll(); // Health Monitoring const ping = await api.opensearch.health.ping(); const health = await api.opensearch.health.check(); ``` #### Items Service ```typescript // Inventory Master Records const itemDetails = await api.items.invMast.get(invMastUid); // Document retrieval for invMast records const itemDoc = await api.items.invMast.doc.get(invMastUid, { q: 'optional-query-pattern' // Search pattern for document filtering }); // Special lookup pattern: Find invMastUid by itemId // When you only have an itemId but need the invMastUid, use invMastUid = 0 // and provide the itemId as the query pattern. This will look up the itemId // and return the full document including the correct invMastUid. const itemByItemId = await api.items.invMast.doc.get(0, { q: 'YOUR-ITEM-ID' // Replace with actual itemId (e.g., 'WIRE-12-AWG-250FT') }); // R