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
- Learn about On-Prem Agent
- Explore HL7 Interface
- Understand SMART App Launch
- Review FHIRcast