/** * @fileoverview Generate complete provider tools documentation * Creates exact tool names and complete documentation table for all 147 provider endpoints */ import fs from 'fs'; import path from 'path'; /** * Generate complete provider tools documentation */ function generateCompleteProviderTools() { try { console.log('=== GENERATING COMPLETE PROVIDER TOOLS DOCUMENTATION ==='); console.log(''); // Read the complete provider endpoints const completeProviderPath = path.join(process.cwd(), 'complete-provider-endpoints.json'); const completeProviderContent = fs.readFileSync(completeProviderPath, 'utf8'); const completeProviderEndpoints = JSON.parse(completeProviderContent); console.log(`Processing ${completeProviderEndpoints.length} provider endpoints`); console.log(''); const providerTools = []; // Process each provider endpoint to create exact tool definitions completeProviderEndpoints.forEach((endpoint, index) => { console.log(`Processing ${index + 1}/${completeProviderEndpoints.length}: ${endpoint.method} ${endpoint.path}`); const tool = { toolName: generateExactToolName(endpoint), method: endpoint.method, path: endpoint.path, description: endpoint.detailedDescription || endpoint.summary || 'Provider endpoint', category: endpoint.category, parameters: formatParametersForDocumentation(endpoint), operationId: endpoint.operationId, tags: endpoint.tags || [], endpoint: endpoint }; providerTools.push(tool); }); console.log(''); console.log(`=== TOOL GENERATION COMPLETE ===`); console.log(`Generated ${providerTools.length} provider tools`); console.log(''); // Generate the complete documentation table const documentationTable = generateDocumentationTable(providerTools); // Save the complete provider tools const outputPath = path.join(process.cwd(), 'complete-provider-tools.json'); fs.writeFileSync(outputPath, JSON.stringify(providerTools, null, 2)); console.log(`Complete provider tools saved to: ${outputPath}`); // Save the documentation table const tableOutputPath = path.join(process.cwd(), 'provider-tools-documentation-table.md'); fs.writeFileSync(tableOutputPath, documentationTable); console.log(`Documentation table saved to: ${tableOutputPath}`); // Display summary by category const categoryCount = {}; providerTools.forEach(tool => { const category = tool.category || 'unknown'; categoryCount[category] = (categoryCount[category] || 0) + 1; }); console.log(''); console.log('=== PROVIDER TOOLS BY CATEGORY ==='); Object.keys(categoryCount).sort().forEach(category => { console.log(`${category}: ${categoryCount[category]} tools`); }); return { providerTools, documentationTable }; } catch (error) { console.error('Error generating complete provider tools:', error); throw error; } } /** * Generate exact tool name following the established convention */ function generateExactToolName(endpoint) { const method = endpoint.method.toLowerCase(); const path = endpoint.path.toLowerCase(); // Extract meaningful parts from the path let pathParts = path.split('/').filter(part => part && !part.startsWith('{') && !part.endsWith('}')); // Remove common prefixes pathParts = pathParts.filter(part => !['api', 'emr', 'emr-api'].includes(part)); // Determine action based on method and path context let action = method; if (method === 'get') { action = 'get'; } else if (method === 'post') { if (path.includes('/store') || path.includes('/save') || path.includes('/add') || path.includes('/create')) { action = 'create'; } else if (path.includes('/search') || path.includes('/find') || path.includes('/list')) { action = 'search'; } else if (path.includes('/login') || path.includes('/register')) { action = 'auth'; } else if (path.includes('/sync') || path.includes('/update')) { action = 'update'; } else { action = 'create'; } } else if (method === 'put' || method === 'patch') { action = 'update'; } else if (method === 'delete') { action = 'delete'; } // Create resource name from path parts with better naming let resource = pathParts.join('_').replace(/-/g, '_'); // Handle special naming cases if (path.includes('appointment')) { resource = resource.replace(/appointment/g, 'appointment'); } if (path.includes('patient')) { resource = resource.replace(/patient/g, 'patient'); } if (path.includes('meeting')) { resource = resource.replace(/meeting/g, 'meeting'); } if (path.includes('form')) { resource = resource.replace(/form/g, 'form'); } if (path.includes('document')) { resource = resource.replace(/document/g, 'document'); } if (path.includes('practitioner')) { resource = resource.replace(/practitioner/g, 'practitioner'); } if (path.includes('inventory')) { resource = resource.replace(/inventory/g, 'inventory'); } if (path.includes('location')) { resource = resource.replace(/location/g, 'location'); } if (path.includes('insurance')) { resource = resource.replace(/insurance/g, 'insurance'); } if (path.includes('vital')) { resource = resource.replace(/vital/g, 'vital'); } if (path.includes('task')) { resource = resource.replace(/task/g, 'task'); } if (path.includes('tag')) { resource = resource.replace(/tag/g, 'tag'); } if (path.includes('token')) { resource = resource.replace(/token/g, 'token'); } if (path.includes('email')) { resource = resource.replace(/email/g, 'email'); } if (path.includes('company')) { resource = resource.replace(/company/g, 'company'); } if (path.includes('product')) { resource = resource.replace(/product/g, 'product'); } if (path.includes('category')) { resource = resource.replace(/category/g, 'category'); } if (path.includes('signature')) { resource = resource.replace(/signature/g, 'signature'); } if (path.includes('payment')) { resource = resource.replace(/payment/g, 'payment'); } if (path.includes('medical')) { resource = resource.replace(/medical/g, 'medical'); } if (path.includes('prescription')) { resource = resource.replace(/prescription/g, 'prescription'); } if (path.includes('phone')) { resource = resource.replace(/phone/g, 'phone'); } if (path.includes('availability')) { resource = resource.replace(/availability/g, 'availability'); } if (path.includes('wizard')) { resource = resource.replace(/wizard/g, 'wizard'); } if (path.includes('status')) { resource = resource.replace(/status/g, 'status'); } if (path.includes('queue')) { resource = resource.replace(/queue/g, 'queue'); } if (path.includes('transcribe')) { resource = resource.replace(/transcribe/g, 'transcribe'); } if (path.includes('report')) { resource = resource.replace(/report/g, 'report'); } if (path.includes('analysis')) { resource = resource.replace(/analysis/g, 'analysis'); } if (path.includes('download')) { resource = resource.replace(/download/g, 'download'); } if (path.includes('render')) { resource = resource.replace(/render/g, 'render'); } if (path.includes('intake')) { resource = resource.replace(/intake/g, 'intake'); } if (path.includes('consent')) { resource = resource.replace(/consent/g, 'consent'); } if (path.includes('questionnaire')) { resource = resource.replace(/questionnaire/g, 'questionnaire'); } if (path.includes('subscription')) { resource = resource.replace(/subscription/g, 'subscription'); } if (path.includes('notification')) { resource = resource.replace(/notification/g, 'notification'); } if (path.includes('history')) { resource = resource.replace(/history/g, 'history'); } if (path.includes('profile')) { resource = resource.replace(/profile/g, 'profile'); } if (path.includes('picture')) { resource = resource.replace(/picture/g, 'picture'); } if (path.includes('cancel')) { resource = resource.replace(/cancel/g, 'cancel'); } if (path.includes('process')) { resource = resource.replace(/process/g, 'process'); } if (path.includes('generate')) { resource = resource.replace(/generate/g, 'generate'); } if (path.includes('revoke')) { resource = resource.replace(/revoke/g, 'revoke'); } if (path.includes('refresh')) { resource = resource.replace(/refresh/g, 'refresh'); } if (path.includes('abilities')) { resource = resource.replace(/abilities/g, 'abilities'); } if (path.includes('temporary')) { resource = resource.replace(/temporary/g, 'temporary'); } if (path.includes('logout')) { resource = resource.replace(/logout/g, 'logout'); } if (path.includes('setup')) { resource = resource.replace(/setup/g, 'setup'); } if (path.includes('complete')) { resource = resource.replace(/complete/g, 'complete'); } if (path.includes('realtime')) { resource = resource.replace(/realtime/g, 'realtime'); } if (path.includes('questions')) { resource = resource.replace(/questions/g, 'questions'); } if (path.includes('asseblyai')) { resource = resource.replace(/asseblyai/g, 'assemblyai'); } if (path.includes('labs')) { resource = resource.replace(/labs/g, 'labs'); } if (path.includes('slots')) { resource = resource.replace(/slots/g, 'slots'); } if (path.includes('detail')) { resource = resource.replace(/detail/g, 'detail'); } if (path.includes('note')) { resource = resource.replace(/note/g, 'note'); } if (path.includes('data')) { resource = resource.replace(/data/g, 'data'); } if (path.includes('pdf')) { resource = resource.replace(/pdf/g, 'pdf'); } if (path.includes('vue')) { resource = resource.replace(/vue/g, 'vue'); } if (path.includes('questioner')) { resource = resource.replace(/questioner/g, 'questioner'); } if (path.includes('question')) { resource = resource.replace(/question/g, 'question'); } if (path.includes('problem')) { resource = resource.replace(/problem/g, 'problem'); } if (path.includes('log')) { resource = resource.replace(/log/g, 'log'); } if (path.includes('plans')) { resource = resource.replace(/plans/g, 'plans'); } if (path.includes('sync')) { resource = resource.replace(/sync/g, 'sync'); } if (path.includes('user')) { resource = resource.replace(/user/g, 'user'); } if (path.includes('me')) { resource = resource.replace(/me/g, 'me'); } if (path.includes('password')) { resource = resource.replace(/password/g, 'password'); } if (path.includes('method')) { resource = resource.replace(/method/g, 'method'); } if (path.includes('stored')) { resource = resource.replace(/stored/g, 'stored'); } if (path.includes('session')) { resource = resource.replace(/session/g, 'session'); } if (path.includes('carts')) { resource = resource.replace(/carts/g, 'carts'); } if (path.includes('items')) { resource = resource.replace(/items/g, 'items'); } if (path.includes('agent')) { resource = resource.replace(/agent/g, 'agent'); } if (path.includes('order')) { resource = resource.replace(/order/g, 'order'); } if (path.includes('call')) { resource = resource.replace(/call/g, 'call'); } if (path.includes('start')) { resource = resource.replace(/start/g, 'start'); } if (path.includes('end')) { resource = resource.replace(/end/g, 'end'); } if (path.includes('join')) { resource = resource.replace(/join/g, 'join'); } if (path.includes('create')) { resource = resource.replace(/create/g, 'create'); } if (path.includes('book')) { resource = resource.replace(/book/g, 'book'); } if (path.includes('info')) { resource = resource.replace(/info/g, 'info'); } if (path.includes('doctors')) { resource = resource.replace(/doctors/g, 'doctors'); } if (path.includes('list')) { resource = resource.replace(/list/g, 'list'); } if (path.includes('date')) { resource = resource.replace(/date/g, 'date'); } if (path.includes('by')) { resource = resource.replace(/by/g, 'by'); } if (path.includes('id')) { resource = resource.replace(/id/g, 'id'); } if (path.includes('all')) { resource = resource.replace(/all/g, 'all'); } if (path.includes('assistant')) { resource = resource.replace(/assistant/g, 'assistant'); } if (path.includes('store')) { resource = resource.replace(/store/g, 'store'); } if (path.includes('save')) { resource = resource.replace(/save/g, 'save'); } if (path.includes('add')) { resource = resource.replace(/add/g, 'add'); } if (path.includes('get')) { resource = resource.replace(/get/g, 'get'); } if (path.includes('update')) { resource = resource.replace(/update/g, 'update'); } if (path.includes('delete')) { resource = resource.replace(/delete/g, 'delete'); } if (path.includes('put')) { resource = resource.replace(/put/g, 'put'); } if (path.includes('post')) { resource = resource.replace(/post/g, 'post'); } // Clean up resource name resource = resource.replace(/[^a-z0-9_]/g, ''); // Remove duplicate underscores resource = resource.replace(/_+/g, '_'); // Remove leading/trailing underscores resource = resource.replace(/^_+|_+$/g, ''); // Ensure we have a resource name if (!resource) { if (endpoint.operationId) { resource = endpoint.operationId.toLowerCase().replace(/[^a-z0-9_]/g, '_'); } else { resource = 'unknown'; } } return `provider_${action}_${resource}`; } /** * Format parameters for documentation */ function formatParametersForDocumentation(endpoint) { const params = []; // Add path parameters if (endpoint.completeParameters) { Object.keys(endpoint.completeParameters).forEach(paramName => { const param = endpoint.completeParameters[paramName]; const required = param.required ? '**Required:**' : '**Optional:**'; const type = param.type || 'string'; const description = param.description || `${paramName} parameter`; params.push(`${required} ${paramName} (${type}) - ${description}`); }); } // Add request body parameters if (endpoint.requestBodySchema && endpoint.requestBodySchema.content) { const jsonContent = endpoint.requestBodySchema.content['application/json']; if (jsonContent && jsonContent.properties) { Object.keys(jsonContent.properties).slice(0, 5).forEach(propName => { const prop = jsonContent.properties[propName]; const required = prop.required ? '**Required:**' : '**Optional:**'; const type = prop.type || 'string'; const description = prop.description || `${propName} property`; params.push(`${required} ${propName} (${type}) - ${description}`); }); } } return params.length > 0 ? params.join(', ') : 'No parameters'; } /** * Generate the complete documentation table */ function generateDocumentationTable(providerTools) { let table = `### Provider Tools (${providerTools.length} tools)\n\n`; table += `*All provider tools require provider authentication (Sanctum token) for HIPAA-compliant access to clinical data.*\n\n`; table += `| Tool Name | Method | Endpoint | Description | Key Parameters |\n`; table += `| --------- | ------ | -------- | ----------- | -------------- |\n`; providerTools.forEach(tool => { const toolName = tool.toolName; const method = tool.method; const endpoint = tool.path; const description = (tool.description || '').replace(/\|/g, '\\|').replace(/\n/g, ' '); const parameters = (tool.parameters || 'No parameters').replace(/\|/g, '\\|').replace(/\n/g, ' '); table += `| \`${toolName}\` | ${method} | \`${endpoint}\` | ${description} | ${parameters} |\n`; }); return table; } // Run the generation if (import.meta.url === `file://${process.argv[1]}`) { generateCompleteProviderTools(); } export { generateCompleteProviderTools };