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.
Scanned 2/12/2026
Install via CLI
openskills install majiayu000/claude-skill-registry---
name: fhir-generator
description: 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.
license: MIT
allowed-tools:
- python
- bash
metadata:
version: "1.0.0"
category: healthcare
fhir-version: "R4"
standard: "HL7 FHIR"
---
# FHIR R4 Resource Generator Skill
## Overview
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.
## When to Use This Skill
Use this skill when you need to:
- Convert OCR-extracted medical data to FHIR resources
- Create Patient, Observation, MedicationRequest resources
- Validate FHIR resource structure
- Prepare data for EHR (Electronic Health Record) integration
- Generate HL7 FHIR bundles for data exchange
## Core FHIR Resources
### 1. Patient Resource
```python
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"
}]
}
```
### 2. MedicationRequest Resource
```python
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"
}
}
}
```
### 3. Observation Resource (Lab Results, Vitals)
```python
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', '')
}
}]
}
```
### 4. Condition/Diagnosis Resource
```python
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', '')
}
```
### 5. DiagnosticReport Resource
```python
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', '')
}
```
## FHIR Bundle Creation
```python
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
]
}
```
## Medical Coding Systems
### Common Code Systems
```python
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
```python
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
}
```
## FHIR Validation
```python
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
}
```
## Complete Medical Document → FHIR Pipeline
```python
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)
}
```
## Example Workflows
### Example 1: Prescription → FHIR
```python
# 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")
```
### Example 2: Lab Results → FHIR
```python
# 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)
```
## Best Practices
1. **Always validate** FHIR resources before submission
2. **Use standard code systems** (LOINC, SNOMED, RxNorm, ICD-10)
3. **Include meaningful text** alongside coded values
4. **Provide reference ranges** for observations
5. **Use appropriate status codes** (active, final, entered-in-error, etc.)
6. **Include timestamps** (effectiveDateTime, authoredOn, etc.)
7. **Link resources properly** using references
8. **Document source** of data (OCR extraction, manual entry, etc.)
## Integration with Agents
This skill integrates with:
- **HEALTHCARELINC**: Receives structured medical data
- **COMPLIANCELINC**: Validates HIPAA compliance
- **Medical-OCR**: Receives OCR-extracted data
## Resources
- [FHIR R4 Specification](https://hl7.org/fhir/R4/)
- [LOINC Codes](https://loinc.org/)
- [SNOMED CT](https://www.snomed.org/)
- [RxNorm](https://www.nlm.nih.gov/research/umls/rxnorm/)
- [FHIR Validator](https://www.hl7.org/fhir/validation.html)
---
**Version**: 1.0.0
**Last Updated**: 2024-11-22
**FHIR Version**: R4
**Maintainer**: Doctors-Linc Development Team
No comments yet. Be the first to comment!