Skip to main content
Glama
medicationUtils.ts8.52 kB
import { Medication, CodeableConcept, Identifier, OperationOutcome, Reference, Organization, Resource, } from '@medplum/fhirtypes'; import { medplum, MedplumClient, ensureAuthenticated } from '../config/medplumClient'; // Medication.status is a string literal type in FHIR R4 export type MedicationStatus = 'active' | 'inactive' | 'entered-in-error'; export interface CreateMedicationArgs { code: CodeableConcept; status?: MedicationStatus; manufacturer?: Reference<Organization>; // Corrected to Reference<Organization> form?: CodeableConcept; identifier?: Identifier[]; } export interface MedicationSearchArgs { code?: string; identifier?: string; status?: MedicationStatus; } /** * Creates a new Medication resource. * @param args The arguments for creating the medication. * @returns The created Medication resource or an OperationOutcome in case of an error. */ export async function createMedication( args: CreateMedicationArgs, client?: MedplumClient, // Restore optional client ): Promise<Medication | OperationOutcome> { const medplumClient = client || medplum; await ensureAuthenticated(); try { if (!args.code || !args.code.coding || args.code.coding.length === 0) { throw new Error('Medication code with at least one coding is required.'); } const medicationResource: Medication = { resourceType: 'Medication', code: args.code, status: args.status, manufacturer: args.manufacturer, form: args.form, identifier: args.identifier, }; Object.keys(medicationResource).forEach( (key) => (medicationResource as any)[key] === undefined && delete (medicationResource as any)[key], ); const createdMedication = (await medplumClient.createResource( medicationResource, )) as Medication; console.log('Medication created successfully:', createdMedication); return createdMedication; } catch (error: any) { console.error('Error creating Medication:', error); const outcome: OperationOutcome = { resourceType: 'OperationOutcome', issue: [ { severity: 'error', code: 'exception', diagnostics: `Error creating Medication: ${error.message || 'Unknown error'}`, }, ], }; if (error.outcome) { console.error('Server OperationOutcome:', JSON.stringify(error.outcome, null, 2)); return error.outcome as OperationOutcome; } return outcome; } } /** * Retrieves a Medication resource by its ID. * @param medicationId The ID of the Medication to retrieve. * @returns The Medication resource or null if not found, or an OperationOutcome on error. */ export async function getMedicationById( medicationId: string, client?: MedplumClient, ): Promise<Medication | null | OperationOutcome> { const medplumClient = client || medplum; await ensureAuthenticated(); try { if (!medicationId) { throw new Error('Medication ID is required.'); } const medication = (await medplumClient.readResource( 'Medication', medicationId, )) as Medication | null; console.log('Medication retrieved:', medication); return medication; } catch (error: any) { if (error.outcome && error.outcome.issue && error.outcome.issue[0]?.code === 'not-found') { console.log(`Medication with ID "${medicationId}" not found.`); return null; } console.error(`Error retrieving Medication with ID "${medicationId}":`, error); const outcome: OperationOutcome = { resourceType: 'OperationOutcome', issue: [ { severity: 'error', code: 'exception', diagnostics: `Error retrieving Medication: ${error.message || 'Unknown error'}`, }, ], }; if (error.outcome) { console.error('Server OperationOutcome:', JSON.stringify(error.outcome, null, 2)); return error.outcome as OperationOutcome; } return outcome; } } /** * Searches for Medication resources based on specified criteria. * @param args The search criteria. * @returns An array of Medication resources matching the criteria or an OperationOutcome on error. */ export async function searchMedications( args: MedicationSearchArgs, client?: MedplumClient, ): Promise<Medication[] | OperationOutcome> { const medplumClient = client || medplum; await ensureAuthenticated(); try { const searchCriteria: string[] = []; if (args.code) { searchCriteria.push(`code=${args.code}`); } if (args.identifier) { searchCriteria.push(`identifier=${args.identifier}`); } if (args.status) { searchCriteria.push(`status=${args.status}`); } if (searchCriteria.length === 0) { console.warn( 'Searching for medications without any criteria. This might return a large dataset or be restricted by the server.', ); return { resourceType: 'OperationOutcome', issue: [ { severity: 'error', code: 'invalid', diagnostics: 'At least one search criterion (code, identifier, or status) must be provided for searching medications.', }, ], }; } const query = searchCriteria.join('&'); console.log('Searching medications with query:', query); const searchResult = await medplumClient.searchResources('Medication', query); const medications = searchResult as Medication[]; console.log(`Found ${medications.length} medications.`); return medications; } catch (error: any) { console.error('Error searching Medications:', error); const outcome: OperationOutcome = { resourceType: 'OperationOutcome', issue: [ { severity: 'error', code: 'exception', diagnostics: `Error searching Medications: ${error.message || 'Unknown error'}`, }, ], }; if (error.outcome) { console.error('Server OperationOutcome:', JSON.stringify(error.outcome, null, 2)); return error.outcome as OperationOutcome; } return outcome; } } // Example usage (for local testing, can be removed or commented out) /* async function main() { // Make sure your .env file is configured for medplumClient // Example: Create a Medication const newMed: CreateMedicationArgs = { code: { coding: [ { system: 'http://www.nlm.nih.gov/research/umls/rxnorm', code: '313782', // Amoxicillin 250mg display: 'Amoxicillin 250mg Oral Tablet', }, ], text: 'Amoxicillin 250mg Oral Tablet', }, status: 'active', form: { coding: [ { system: 'http://snomed.info/sct', code: '385055001', display: 'Oral tablet', }, ], text: 'Oral tablet', }, // manufacturer: { reference: "Organization/your-org-id" } // If you have an Org ID }; const created = await createMedication(newMed); if (created.resourceType === 'Medication') { console.log('Created medication:', JSON.stringify(created, null, 2)); // Example: Get Medication by ID const medicationId = created.id; if ( medicationId ) { const fetched = await getMedicationById(medicationId); if (fetched && fetched.resourceType === 'Medication') { console.log('Fetched medication:', JSON.stringify(fetched, null, 2)); } else if (!fetched) { console.log('Medication not found by ID after creation.'); } else { console.log('Error fetching medication by ID:', JSON.stringify(fetched, null, 2)); } } // Example: Search Medications // By code const searchByCodeResults = await searchMedications({ code: 'http://www.nlm.nih.gov/research/umls/rxnorm|313782' }); console.log('Search by code results:', JSON.stringify(searchByCodeResults, null, 2)); // By status const searchByStatusResults = await searchMedications({ status: 'active' }); console.log('Search by status results:', JSON.stringify(searchByStatusResults, null, 2)); } else { console.log('Error creating medication:', JSON.stringify(created, null, 2)); } // Test Get Not Found const notFound = await getMedicationById('non-existent-id'); if (!notFound) { console.log('Correctly handled getMedicationById for non-existent ID.'); } else { console.log('Unexpected result for non-existent ID:', JSON.stringify(notFound, null, 2)); } } main().catch(console.error); */

Implementation Reference

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/rkirkendall/medplum-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server