Skip to main content
Glama
medicationRequestUtils.ts10.7 kB
import { medplum, ensureAuthenticated } from '../config/medplumClient'; import { MedicationRequest, Patient, Practitioner, Encounter, Reference, Identifier, CodeableConcept, Dosage, Period } from '@medplum/fhirtypes'; // Interface for creating a MedicationRequest export interface CreateMedicationRequestArgs { status: MedicationRequest['status']; intent: MedicationRequest['intent']; medicationCodeableConcept?: CodeableConcept; // medicationReference?: Reference; // TODO: Add if direct reference to Medication resource is needed subjectId: string; // Convenience for Patient reference encounterId?: string; // Convenience for Encounter reference authoredOn?: string; requesterId?: string; // Convenience for Practitioner reference dosageInstruction?: Dosage[]; note?: string; identifier?: { system?: string; value: string }; // Add other relevant fields like dispenseRequest, category, priority, etc. as needed } // Interface for retrieving a MedicationRequest by ID export interface GetMedicationRequestByIdArgs { medicationRequestId: string; } // Interface for updating a MedicationRequest export interface UpdateMedicationRequestArgs { status?: MedicationRequest['status']; intent?: MedicationRequest['intent']; medicationCodeableConcept?: CodeableConcept | null; // medicationReference?: Reference | null; subjectId?: string | null; encounterId?: string | null; authoredOn?: string | null; requesterId?: string | null; dosageInstruction?: Dosage[] | null; note?: string | null; identifier?: { system?: string; value: string } | null; // Add other relevant fields from CreateMedicationRequestArgs as optional and nullable } // Interface for searching MedicationRequests export interface SearchMedicationRequestsArgs { patientId?: string; // Searches for subject=Patient/[patientId] status?: MedicationRequest['status']; intent?: MedicationRequest['intent']; code?: string; // Searches by medicationCodeableConcept.coding.code codeSystem?: string; // System for the medication code authoredon?: string; // Date search for authoredOn, supports prefixes like eq, gt, le requester?: string; // FHIR style search param: Practitioner/XYZ or Organization/XYZ identifier?: string; // Search by identifier value (e.g. value or system|value) _lastUpdated?: string; // Add other common search parameters } /** * Creates a new MedicationRequest resource. * @param args - The arguments for creating the medication request. * @returns The created MedicationRequest resource. */ export async function createMedicationRequest(args: CreateMedicationRequestArgs): Promise<MedicationRequest> { await ensureAuthenticated(); if (!args.status) { throw new Error('MedicationRequest status is required.'); } if (!args.intent) { throw new Error('MedicationRequest intent is required.'); } if (!args.medicationCodeableConcept) { // Add || !args.medicationReference if that's supported throw new Error('Medication (medicationCodeableConcept or medicationReference) is required.'); } if (!args.subjectId) { throw new Error('Subject (Patient ID) is required to create a MedicationRequest.'); } const medicationRequestResource: MedicationRequest = { resourceType: 'MedicationRequest', status: args.status, intent: args.intent, medicationCodeableConcept: args.medicationCodeableConcept, // medicationReference: args.medicationReference, subject: { reference: `Patient/${args.subjectId}` }, authoredOn: args.authoredOn || new Date().toISOString(), dosageInstruction: args.dosageInstruction, }; if (args.encounterId) { medicationRequestResource.encounter = { reference: `Encounter/${args.encounterId}` }; } if (args.requesterId) { medicationRequestResource.requester = { reference: `Practitioner/${args.requesterId}` }; } if (args.note) { medicationRequestResource.note = [{ text: args.note }]; } if (args.identifier) { medicationRequestResource.identifier = [{ system: args.identifier.system, value: args.identifier.value }]; } return medplum.createResource<MedicationRequest>(medicationRequestResource); } /** * Retrieves a MedicationRequest by its ID. * @param args - The arguments containing the medication request ID. * @returns The MedicationRequest resource, or null if not found. */ export async function getMedicationRequestById(args: GetMedicationRequestByIdArgs): Promise<MedicationRequest | null> { await ensureAuthenticated(); if (!args.medicationRequestId) { throw new Error('MedicationRequest ID is required to fetch a medication request.'); } try { return await medplum.readResource('MedicationRequest', args.medicationRequestId); } catch (error: any) { if (error.outcome?.issue?.[0]?.code === 'not-found') { return null; } throw error; } } /** * Updates an existing MedicationRequest resource. * @param medicationRequestId - The ID of the medication request to update. * @param updates - An object containing the fields to update. * @returns The updated MedicationRequest resource. */ export async function updateMedicationRequest(medicationRequestId: string, updates: UpdateMedicationRequestArgs): Promise<MedicationRequest> { await ensureAuthenticated(); if (!medicationRequestId) { throw new Error('MedicationRequest ID is required to update a medication request.'); } if (!updates || Object.keys(updates).length === 0) { throw new Error('Updates object cannot be empty for updating a medication request.'); } const existingMedicationRequest = await medplum.readResource('MedicationRequest', medicationRequestId); if (!existingMedicationRequest) { throw new Error(`MedicationRequest with ID ${medicationRequestId} not found.`); } const { note: noteInput, identifier: identifierInput, subjectId: subjectIdInput, encounterId: encounterIdInput, requesterId: requesterIdInput, medicationCodeableConcept: medicationCodeableConceptInput, // medicationReference: medicationReferenceInput, // If added to UpdateMedicationRequestArgs ...restOfUpdates } = updates; const workingUpdates: Partial<MedicationRequest> = {}; // Handle fields from restOfUpdates, converting null to undefined for (const key in restOfUpdates) { if (Object.prototype.hasOwnProperty.call(restOfUpdates, key)) { const value = (restOfUpdates as any)[key]; if (value === null) { (workingUpdates as any)[key] = undefined; } else if (value !== undefined) { (workingUpdates as any)[key] = value; } } } // Handle specific conversions if (typeof noteInput === 'string') { workingUpdates.note = [{ text: noteInput }]; } else if (noteInput === null) { workingUpdates.note = undefined; } else if (noteInput !== undefined) { // If it was already Annotation[] workingUpdates.note = noteInput as any; } if (identifierInput && typeof identifierInput === 'object') { workingUpdates.identifier = [identifierInput as Identifier]; } else if (identifierInput === null) { workingUpdates.identifier = undefined; } if (typeof subjectIdInput === 'string') { workingUpdates.subject = { reference: `Patient/${subjectIdInput}` }; } else if (subjectIdInput === null) { workingUpdates.subject = undefined; } if (typeof encounterIdInput === 'string') { workingUpdates.encounter = { reference: `Encounter/${encounterIdInput}` }; } else if (encounterIdInput === null) { workingUpdates.encounter = undefined; } if (typeof requesterIdInput === 'string') { workingUpdates.requester = { reference: `Practitioner/${requesterIdInput}` }; } else if (requesterIdInput === null) { workingUpdates.requester = undefined; } if (medicationCodeableConceptInput === null) { workingUpdates.medicationCodeableConcept = undefined; } else if (medicationCodeableConceptInput !== undefined) { workingUpdates.medicationCodeableConcept = medicationCodeableConceptInput; // workingUpdates.medicationReference = undefined; // Ensure exclusivity if medicationReference is also handled } // Similar logic for medicationReference if it gets added // if (medicationReferenceInput === null) { // workingUpdates.medicationReference = undefined; // workingUpdates.medicationCodeableConcept = undefined; // Clear the other if one is nulled // } else if (medicationReferenceInput !== undefined) { // workingUpdates.medicationReference = medicationReferenceInput; // workingUpdates.medicationCodeableConcept = undefined; // Ensure exclusivity // } const updatedResource: MedicationRequest = { ...existingMedicationRequest, ...workingUpdates, resourceType: 'MedicationRequest', id: medicationRequestId, }; return medplum.updateResource(updatedResource); } /** * Searches for MedicationRequest resources based on specified criteria. * @param args - The search criteria. * @returns An array of matching MedicationRequest resources. */ export async function searchMedicationRequests(args: SearchMedicationRequestsArgs): Promise<MedicationRequest[]> { await ensureAuthenticated(); const searchCriteria: string[] = []; if (Object.keys(args).length === 0) { console.warn('MedicationRequest search called with no specific criteria. This might return a large number of results or be inefficient.'); } if (args.patientId) { searchCriteria.push(`patient=Patient/${args.patientId}`); } if (args.status) { searchCriteria.push(`status=${args.status}`); } if (args.intent) { searchCriteria.push(`intent=${args.intent}`); } if (args.code) { searchCriteria.push(`code=${args.code}`); } if (args.authoredon) { searchCriteria.push(`authoredon=${args.authoredon}`); } if (args.requester) { searchCriteria.push(`requester=${args.requester}`); } if (args.identifier) { searchCriteria.push(`identifier=${args.identifier}`); } if (args._lastUpdated) { searchCriteria.push(`_lastUpdated=${args._lastUpdated}`); } if (searchCriteria.length === 0 && Object.keys(args).length > 0) { console.warn('MedicationRequest search arguments provided but did not map to any known search parameters:', args); return []; } // Only search if there are criteria or if no arguments were provided (search all) if (searchCriteria.length > 0 || Object.keys(args).length === 0) { const queryString = searchCriteria.join('&'); return medplum.searchResources('MedicationRequest', queryString); } else { return []; // Should be caught by the warning above, but as a fallback } }

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