FHIR R4 resource generation and validation for healthcare interoperability. Converts medical data into FHIR-compliant JSON resources (Patient, Observation, MedicationRequest, Condition, etc.). Use when creating FHIR resources, validating healthcare data structures, or preparing data for EHR integration.
This skill enables Claude to generate valid FHIR R4 (Fast Healthcare Interoperability Resources) resources from extracted medical data. FHIR is the industry standard for healthcare data exchange.
Use this skill when you need to:
def create_fhir_patient(patient_data):
"""Generate FHIR R4 Patient resource"""
return {
"resourceType": "Patient",
"id": patient_data.get('id', 'example-patient'),
"identifier": [{
"use": "official",
"system": "http://hospital.example.org",
"value": patient_data.get('mrn', 'MRN12345')
}],
"active": True,
"name": [{
"use": "official",
"family": patient_data.get('last_name', ''),
"given": [patient_data.get('first_name', '')]
}],
"gender": patient_data.get('gender', 'unknown'),
"birthDate": patient_data.get('birth_date', ''),
"address": [{
"use": "home",
"line": [patient_data.get('address_line', '')],
"city": patient_data.get('city', ''),
"state": patient_data.get('state', ''),
"postalCode": patient_data.get('zip', ''),
"country": patient_data.get('country', 'US')
}],
"telecom": [{
"system": "phone",
"value": patient_data.get('phone', ''),
"use": "mobile"
}]
}
def create_medication_request(medication_data, patient_reference):
"""Generate FHIR R4 MedicationRequest"""
return {
"resourceType": "MedicationRequest",
"id": medication_data.get('id', 'med-request-1'),
"status": "active",
"intent": "order",
"medicationCodeableConcept": {
"coding": [{
"system": "http://www.nlm.nih.gov/research/umls/rxnorm",
"code": medication_data.get('rxnorm_code', ''),
"display": medication_data.get('name', '')
}],
"text": medication_data.get('name', '')
},
"subject": {
"reference": patient_reference,
"display": "Patient"
},
"authoredOn": medication_data.get('date', ''),
"dosageInstruction": [{
"text": medication_data.get('sig', ''),
"timing": {
"repeat": {
"frequency": medication_data.get('frequency', 1),
"period": 1,
"periodUnit": "d",
"when": [medication_data.get('timing', 'MORN')]
}
},
"route": {
"coding": [{
"system": "http://snomed.info/sct",
"code": medication_data.get('route_code', '26643006'),
"display": medication_data.get('route', 'Oral')
}]
},
"doseAndRate": [{
"doseQuantity": {
"value": medication_data.get('dose_value', 0),
"unit": medication_data.get('dose_unit', 'mg'),
"system": "http://unitsofmeasure.org",
"code": medication_data.get('ucum_code', 'mg')
}
}]
}],
"dispenseRequest": {
"quantity": {
"value": medication_data.get('quantity', 30),
"unit": "tablet"
},
"expectedSupplyDuration": {
"value": medication_data.get('days_supply', 30),
"unit": "days"
}
}
}
def create_observation(obs_data, patient_reference):
"""Generate FHIR R4 Observation for lab results or vitals"""
return {
"resourceType": "Observation",
"id": obs_data.get('id', 'obs-1'),
"status": "final",
"category": [{
"coding": [{
"system": "http://terminology.hl7.org/CodeSystem/observation-category",
"code": obs_data.get('category', 'laboratory'),
"display": obs_data.get('category_display', 'Laboratory')
}]
}],
"code": {
"coding": [{
"system": "http://loinc.org",
"code": obs_data.get('loinc_code', ''),
"display": obs_data.get('test_name', '')
}],
"text": obs_data.get('test_name', '')
},
"subject": {
"reference": patient_reference
},
"effectiveDateTime": obs_data.get('date', ''),
"valueQuantity": {
"value": obs_data.get('value', 0),
"unit": obs_data.get('unit', ''),
"system": "http://unitsofmeasure.org",
"code": obs_data.get('ucum_code', '')
},
"referenceRange": [{
"low": {
"value": obs_data.get('ref_low', 0),
"unit": obs_data.get('unit', '')
},
"high": {
"value": obs_data.get('ref_high', 0),
"unit": obs_data.get('unit', '')
}
}]
}
def create_condition(diagnosis_data, patient_reference):
"""Generate FHIR R4 Condition resource"""
return {
"resourceType": "Condition",
"id": diagnosis_data.get('id', 'condition-1'),
"clinicalStatus": {
"coding": [{
"system": "http://terminology.hl7.org/CodeSystem/condition-clinical",
"code": diagnosis_data.get('clinical_status', 'active')
}]
},
"verificationStatus": {
"coding": [{
"system": "http://terminology.hl7.org/CodeSystem/condition-ver-status",
"code": "confirmed"
}]
},
"category": [{
"coding": [{
"system": "http://terminology.hl7.org/CodeSystem/condition-category",
"code": "encounter-diagnosis",
"display": "Encounter Diagnosis"
}]
}],
"severity": {
"coding": [{
"system": "http://snomed.info/sct",
"code": diagnosis_data.get('severity_code', '24484000'),
"display": diagnosis_data.get('severity', 'Severe')
}]
},
"code": {
"coding": [{
"system": "http://snomed.info/sct",
"code": diagnosis_data.get('snomed_code', ''),
"display": diagnosis_data.get('diagnosis_name', '')
}, {
"system": "http://hl7.org/fhir/sid/icd-10-cm",
"code": diagnosis_data.get('icd10_code', ''),
"display": diagnosis_data.get('diagnosis_name', '')
}],
"text": diagnosis_data.get('diagnosis_name', '')
},
"subject": {
"reference": patient_reference
},
"onsetDateTime": diagnosis_data.get('onset_date', ''),
"recordedDate": diagnosis_data.get('recorded_date', '')
}
def create_diagnostic_report(report_data, patient_reference, observations):
"""Generate FHIR R4 DiagnosticReport"""
return {
"resourceType": "DiagnosticReport",
"id": report_data.get('id', 'report-1'),
"status": "final",
"category": [{
"coding": [{
"system": "http://terminology.hl7.org/CodeSystem/v2-0074",
"code": "LAB",
"display": "Laboratory"
}]
}],
"code": {
"coding": [{
"system": "http://loinc.org",
"code": report_data.get('loinc_code', ''),
"display": report_data.get('report_name', '')
}],
"text": report_data.get('report_name', '')
},
"subject": {
"reference": patient_reference
},
"effectiveDateTime": report_data.get('date', ''),
"issued": report_data.get('issued_date', ''),
"result": [
{"reference": f"Observation/{obs_id}"}
for obs_id in observations
],
"conclusion": report_data.get('conclusion', '')
}
def create_fhir_bundle(entries, bundle_type="transaction"):
"""Create FHIR Bundle to group multiple resources"""
return {
"resourceType": "Bundle",
"type": bundle_type,
"entry": [
{
"fullUrl": f"urn:uuid:{entry.get('id', '')}",
"resource": entry,
"request": {
"method": "POST",
"url": entry.get('resourceType', '')
}
}
for entry in entries
]
}
CODE_SYSTEMS = {
"rxnorm": {
"system": "http://www.nlm.nih.gov/research/umls/rxnorm",
"description": "RxNorm - Medication names"
},
"snomed": {
"system": "http://snomed.info/sct",
"description": "SNOMED CT - Clinical terms"
},
"loinc": {
"system": "http://loinc.org",
"description": "LOINC - Lab tests and observations"
},
"icd10": {
"system": "http://hl7.org/fhir/sid/icd-10-cm",
"description": "ICD-10-CM - Diagnoses"
},
"cpt": {
"system": "http://www.ama-assn.org/go/cpt",
"description": "CPT - Procedures"
},
"ucum": {
"system": "http://unitsofmeasure.org",
"description": "UCUM - Units of measure"
}
}
COMMON_LOINC_CODES = {
"glucose": "2345-7", # Glucose [Mass/volume] in Serum or Plasma
"hba1c": "4548-4", # Hemoglobin A1c/Hemoglobin.total in Blood
"cholesterol": "2093-3", # Cholesterol [Mass/volume] in Serum or Plasma
"hdl": "2085-9", # HDL Cholesterol [Mass/volume] in Serum or Plasma
"ldl": "2089-1", # LDL Cholesterol [Mass/volume] in Serum or Plasma
"triglycerides": "2571-8", # Triglyceride [Mass/volume] in Serum or Plasma
"creatinine": "2160-0", # Creatinine [Mass/volume] in Serum or Plasma
"hemoglobin": "718-7", # Hemoglobin [Mass/volume] in Blood
"wbc": "6690-2", # Leukocytes [#/volume] in Blood
"platelets": "777-3", # Platelets [#/volume] in Blood
"bp_systolic": "8480-6", # Systolic blood pressure
"bp_diastolic": "8462-4", # Diastolic blood pressure
"heart_rate": "8867-4", # Heart rate
"temperature": "8310-5", # Body temperature
"weight": "29463-7", # Body weight
"height": "8302-2" # Body height
}
def validate_fhir_resource(resource):
"""Basic FHIR resource validation"""
errors = []
# Required fields
if 'resourceType' not in resource:
errors.append("Missing required field: resourceType")
# Resource-specific validation
resource_type = resource.get('resourceType')
if resource_type == 'Patient':
if 'name' not in resource or not resource['name']:
errors.append("Patient must have at least one name")
elif resource_type == 'MedicationRequest':
if 'status' not in resource:
errors.append("MedicationRequest must have status")
if resource.get('status') not in ['active', 'on-hold', 'cancelled', 'completed']:
errors.append(f"Invalid status: {resource.get('status')}")
elif resource_type == 'Observation':
if 'status' not in resource:
errors.append("Observation must have status")
if 'code' not in resource:
errors.append("Observation must have code")
return {
"valid": len(errors) == 0,
"errors": errors
}
def medical_data_to_fhir_bundle(medical_data):
"""Convert complete medical document to FHIR Bundle"""
# Create Patient resource
patient = create_fhir_patient(medical_data.get('patient', {}))
patient_ref = f"Patient/{patient['id']}"
resources = [patient]
# Add MedicationRequests
for med in medical_data.get('medications', []):
med_request = create_medication_request(med, patient_ref)
resources.append(med_request)
# Add Observations (lab results, vitals)
for obs in medical_data.get('observations', []):
observation = create_observation(obs, patient_ref)
resources.append(observation)
# Add Conditions (diagnoses)
for dx in medical_data.get('diagnoses', []):
condition = create_condition(dx, patient_ref)
resources.append(condition)
# Create Bundle
bundle = create_fhir_bundle(resources, bundle_type="transaction")
# Validate all resources
validation_results = [
validate_fhir_resource(res) for res in resources
]
return {
"bundle": bundle,
"validation": validation_results,
"resource_count": len(resources)
}
# Input: OCR extracted prescription data
prescription_data = {
"patient": {
"id": "pat-001",
"first_name": "John",
"last_name": "Doe",
"mrn": "MRN123456",
"birth_date": "1980-01-15"
},
"medications": [{
"id": "med-001",
"name": "Metformin",
"rxnorm_code": "860975",
"dose_value": 500,
"dose_unit": "mg",
"frequency": 2,
"route": "Oral",
"quantity": 60,
"days_supply": 30,
"sig": "Take 500mg by mouth twice daily with meals"
}]
}
# Generate FHIR Bundle
result = medical_data_to_fhir_bundle(prescription_data)
print(f"Created {result['resource_count']} FHIR resources")
# Input: OCR extracted lab results
lab_data = {
"patient": {
"id": "pat-001",
"mrn": "MRN123456"
},
"observations": [
{
"id": "obs-glucose",
"test_name": "Glucose",
"loinc_code": "2345-7",
"value": 126,
"unit": "mg/dL",
"ucum_code": "mg/dL",
"ref_low": 70,
"ref_high": 99,
"category": "laboratory",
"date": "2024-11-22T10:30:00Z"
},
{
"id": "obs-hba1c",
"test_name": "Hemoglobin A1c",
"loinc_code": "4548-4",
"value": 7.2,
"unit": "%",
"ucum_code": "%",
"ref_low": 4.0,
"ref_high": 5.6,
"category": "laboratory",
"date": "2024-11-22T10:30:00Z"
}
]
}
# Generate FHIR Bundle
result = medical_data_to_fhir_bundle(lab_data)
This skill integrates with:
Version: 1.0.0
Last Updated: 2024-11-22
FHIR Version: R4
Maintainer: Doctors-Linc Development Team