>Welcome to MedictIntegrateMedict Integrations

Medict Integrations

Learn how to integrate Medict with external healthcare systems and services.

Overview

Medict provides comprehensive integration capabilities to connect with various healthcare systems, including EHRs, lab systems, pharmacy systems, and other healthcare applications.

Integration Types

REST API Integrations

Connect with REST-based healthcare APIs:

import { MedictClient } from '@medplum/core';

const client = new MedictClient({
  baseUrl: 'https://api.medplum.com',
  clientId: 'your-client-id'
});

// Create a REST integration
const integration = await client.createResource({
  resourceType: 'Integration',
  name: 'EHR Integration',
  type: 'rest',
  configuration: {
    baseUrl: 'https://ehr-api.example.com',
    authentication: {
      type: 'oauth2',
      clientId: 'ehr-client-id',
      clientSecret: 'ehr-client-secret',
      tokenUrl: 'https://ehr-api.example.com/oauth/token'
    }
  }
});

HL7 FHIR Integrations

Connect with FHIR-compliant systems:

// FHIR integration configuration
const fhirIntegration = await client.createResource({
  resourceType: 'Integration',
  name: 'FHIR System Integration',
  type: 'fhir',
  configuration: {
    fhirBaseUrl: 'https://fhir-server.example.com/fhir',
    authentication: {
      type: 'basic',
      username: 'fhir-user',
      password: 'fhir-password'
    },
    supportedResources: ['Patient', 'Encounter', 'Observation', 'MedicationRequest']
  }
});

Database Integrations

Connect with existing databases:

// Database integration
const dbIntegration = await client.createResource({
  resourceType: 'Integration',
  name: 'Legacy Database Integration',
  type: 'database',
  configuration: {
    connectionString: 'postgresql://user:password@localhost:5432/legacy_db',
    mapping: {
      'Patient': {
        table: 'patients',
        fields: {
          'id': 'patient_id',
          'name.family': 'last_name',
          'name.given': 'first_name',
          'birthDate': 'date_of_birth'
        }
      }
    }
  }
});

Data Synchronization

Bidirectional Sync

// Set up bidirectional synchronization
async function setupBidirectionalSync(integrationId, resourceType) {
  const sync = await client.createResource({
    resourceType: 'DataSync',
    integration: {
      reference: `Integration/${integrationId}`
    },
    resourceType: resourceType,
    direction: 'bidirectional',
    schedule: {
      frequency: 'hourly',
      interval: 1
    },
    mapping: {
      // Define field mappings
    }
  });
  
  return sync;
}

One-Way Sync

// Set up one-way synchronization
async function setupOneWaySync(integrationId, resourceType, direction) {
  const sync = await client.createResource({
    resourceType: 'DataSync',
    integration: {
      reference: `Integration/${integrationId}`
    },
    resourceType: resourceType,
    direction: direction, // 'inbound' or 'outbound'
    schedule: {
      frequency: 'daily',
      interval: 1
    }
  });
  
  return sync;
}

Real-Time Integrations

Webhook Integrations

// Set up webhook integration
const webhookIntegration = await client.createResource({
  resourceType: 'Integration',
  name: 'Webhook Integration',
  type: 'webhook',
  configuration: {
    webhookUrl: 'https://your-app.com/webhook',
    events: ['Patient.created', 'Patient.updated', 'Encounter.created'],
    authentication: {
      type: 'hmac',
      secret: 'webhook-secret'
    }
  }
});

Message Queue Integrations

// Set up message queue integration
const mqIntegration = await client.createResource({
  resourceType: 'Integration',
  name: 'Message Queue Integration',
  type: 'message-queue',
  configuration: {
    provider: 'aws-sqs',
    queueUrl: 'https://sqs.us-east-1.amazonaws.com/123456789/medplum-queue',
    region: 'us-east-1',
    accessKeyId: 'your-access-key',
    secretAccessKey: 'your-secret-key'
  }
});

Common Integration Patterns

Patient Data Sync

// Sync patient data between systems
async function syncPatientData(patientId, integrationId) {
  const patient = await client.readResource('Patient', patientId);
  
  // Transform data for external system
  const transformedData = transformPatientData(patient);
  
  // Send to external system
  const result = await client.executeIntegration(integrationId, {
    method: 'POST',
    path: '/patients',
    data: transformedData
  });
  
  return result;
}

function transformPatientData(patient) {
  return {
    externalId: patient.identifier?.[0]?.value,
    firstName: patient.name?.[0]?.given?.[0],
    lastName: patient.name?.[0]?.family,
    dateOfBirth: patient.birthDate,
    gender: patient.gender,
    email: patient.telecom?.find(t => t.system === 'email')?.value
  };
}

Lab Results Integration

// Integrate lab results
async function integrateLabResults(integrationId, labResults) {
  for (const result of labResults) {
    // Create FHIR Observation
    const observation = await client.createResource({
      resourceType: 'Observation',
      status: 'final',
      category: [{
        coding: [{
          system: 'http://terminology.hl7.org/CodeSystem/observation-category',
          code: 'laboratory'
        }]
      }],
      code: {
        coding: [{
          system: 'http://loinc.org',
          code: result.loincCode,
          display: result.testName
        }]
      },
      subject: {
        reference: `Patient/${result.patientId}`
      },
      valueQuantity: {
        value: result.value,
        unit: result.unit
      },
      effectiveDateTime: result.collectionDate
    });
    
    // Send to external system
    await client.executeIntegration(integrationId, {
      method: 'POST',
      path: '/lab-results',
      data: {
        observationId: observation.id,
        patientId: result.patientId,
        testName: result.testName,
        value: result.value,
        unit: result.unit
      }
    });
  }
}

Medication Integration

// Integrate medication data
async function integrateMedications(integrationId, medications) {
  for (const med of medications) {
    // Create FHIR MedicationRequest
    const medicationRequest = await client.createResource({
      resourceType: 'MedicationRequest',
      status: 'active',
      intent: 'order',
      medicationCodeableConcept: {
        coding: [{
          system: 'http://www.nlm.nih.gov/research/umls/rxnorm',
          code: med.rxnormCode,
          display: med.name
        }]
      },
      subject: {
        reference: `Patient/${med.patientId}`
      },
      dosageInstruction: [{
        text: med.instructions
      }]
    });
    
    // Send to pharmacy system
    await client.executeIntegration(integrationId, {
      method: 'POST',
      path: '/prescriptions',
      data: {
        medicationRequestId: medicationRequest.id,
        patientId: med.patientId,
        medication: med.name,
        instructions: med.instructions
      }
    });
  }
}

Error Handling and Monitoring

Integration Error Handling

// Handle integration errors
async function executeIntegrationWithErrorHandling(integrationId, request) {
  try {
    const result = await client.executeIntegration(integrationId, request);
    return result;
  } catch (error) {
    // Log error
    await client.createResource({
      resourceType: 'AuditEvent',
      type: {
        coding: [{
          system: 'http://dicom.nema.org/resources/ontology/DCM',
          code: '110100',
          display: 'Application Activity'
        }]
      },
      action: 'E',
      outcome: '4', // Minor failure
      description: `Integration error: ${error.message}`,
      source: {
        observer: {
          reference: `Integration/${integrationId}`
        }
      }
    });
    
    // Retry logic
    if (error.retryable) {
      await new Promise(resolve => setTimeout(resolve, 5000));
      return await client.executeIntegration(integrationId, request);
    }
    
    throw error;
  }
}

Integration Monitoring

// Monitor integration health
async function monitorIntegrationHealth(integrationId) {
  const health = await client.request('GET', `/integrations/${integrationId}/health`);
  
  if (health.status !== 'healthy') {
    // Send alert
    await client.createResource({
      resourceType: 'Communication',
      status: 'completed',
      subject: {
        reference: `Integration/${integrationId}`
      },
      payload: [{
        contentString: `Integration ${integrationId} is ${health.status}: ${health.message}`
      }]
    });
  }
  
  return health;
}

Testing Integrations

Integration Testing

// Test integration configuration
async function testIntegration(integrationId) {
  const testResult = await client.request('POST', `/integrations/${integrationId}/test`);
  
  return {
    success: testResult.success,
    message: testResult.message,
    details: testResult.details
  };
}

Mock Integration

// Create mock integration for testing
const mockIntegration = await client.createResource({
  resourceType: 'Integration',
  name: 'Mock Integration',
  type: 'mock',
  configuration: {
    responses: {
      'GET /patients': {
        status: 200,
        data: [
          { id: '1', name: 'John Doe' },
          { id: '2', name: 'Jane Smith' }
        ]
      },
      'POST /patients': {
        status: 201,
        data: { id: '3', name: 'New Patient' }
      }
    }
  }
});

Best Practices

1. Data Mapping

  • Use consistent field mappings
  • Handle data type conversions
  • Validate data before sending

2. Error Handling

  • Implement retry logic
  • Log all errors
  • Provide meaningful error messages

3. Security

  • Use secure authentication methods
  • Encrypt sensitive data
  • Implement proper access controls

4. Performance

  • Use batch operations when possible
  • Implement caching
  • Monitor performance metrics

Next Steps