501 lines
17 KiB
JavaScript
501 lines
17 KiB
JavaScript
/**
|
|
* @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 };
|