āļāļđāđāļĄāļ·āļāļĄāļēāļāļĢāļāļēāļāļāđāļāļĄāļđāļĨāļāļēāļāļāļēāļĢāđāļāļāļĒāđ (Medical Data Standards Guide)
āļŠāļģāļŦāļĢāļąāļāļĢāļ°āļāļ MediTech Hospital Information System
Document Version: 1.0
Date: September 2, 2025
Project: MediTech HIS - Healthcare Data Interoperability
Prepared by: Medical Technology Systems Team
āļŠāļēāļĢāļāļąāļ (Table of Contents)
- āļāļāļāļģ (Introduction)
- HL7 Version 2.x
- HL7 Version 3
- FHIR (Fast Healthcare Interoperability Resources)
- āļāļēāļĢāđāļāļĢāļĩāļĒāļāđāļāļĩāļĒāļāļĄāļēāļāļĢāļāļēāļ (Standards Comparison)
- āļāļēāļĢāļāļģāđāļāđāļāđāđāļ MediTech (Implementation in MediTech)
- āļĄāļēāļāļĢāļāļēāļāļāļ·āđāļāđ āļāļĩāđāđāļāļĩāđāļĒāļ§āļāđāļāļ (Related Standards)
- Best Practices āđāļĨāļ°āļāđāļāđāļāļ°āļāļģ
1. āļāļāļāļģ (Introduction)
1.1 āļāļ§āļēāļĄāļŠāļģāļāļąāļāļāļāļāļĄāļēāļāļĢāļāļēāļāļāđāļāļĄāļđāļĨāļāļēāļāļāļēāļĢāđāļāļāļĒāđ
āļĄāļēāļāļĢāļāļēāļāļāđāļāļĄāļđāļĨāļāļēāļāļāļēāļĢāđāļāļāļĒāđāđāļāđāļāļŦāļąāļ§āđāļāļŠāļģāļāļąāļāļāļāļāļāļēāļĢāđāļĨāļāđāļāļĨāļĩāđāļĒāļāļāđāļāļĄāļđāļĨāļĢāļ°āļŦāļ§āđāļēāļāļĢāļ°āļāļāļŠāļļāļāļ āļēāļāļāđāļēāļāđ āđāļāļĒāļĄāļĩāļāļ§āļēāļĄāļāļģāđāļāđāļāđāļĨāļ°āđāļŦāļāļļāļāļĨāļŠāļģāļāļąāļāļāļąāļāļāļĩāđ:
ð āļāļąāļāļŦāļēāļāļĩāđāđāļāļīāļāļāļķāđāļāđāļāļĒāđāļĄāđāļĄāļĩāļĄāļēāļāļĢāļāļēāļ
āļŠāļģāļŦāļĢāļąāļ Development Team:
- āļāļ§āļēāļĄāļāļąāļāļāđāļāļāđāļāļāļēāļĢāļāļđāļĢāļāļēāļāļēāļĢ (Integration Complexity)
- āļāđāļāļāđāļāļĩāļĒāļ custom adapter āļŠāļģāļŦāļĢāļąāļāđāļāđāļĨāļ°āļĢāļ°āļāļ āđāļāđāļ:
- Lab System A āļŠāđāļāļāđāļāļĄāļđāļĨāđāļāđāļ CSV format
- Lab System B āļŠāđāļāļāđāļāļĄāļđāļĨāđāļāđāļ XML āđāļāđ schema āļāđāļēāļāļāļąāļ
- Pharmacy System āđāļāđ proprietary API
- āđāļ§āļĨāļēāļāļąāļāļāļēāđāļāļīāđāļĄāļāļķāđāļ 3-5 āđāļāđāļēāļāļąāļ§ āļŠāļģāļŦāļĢāļąāļāđāļāđāļĨāļ° integration
-
āđāļĄāđāļŠāļēāļĄāļēāļĢāļ reuse code āđāļāđ āļāļģāđāļŦāđ codebase āļāļēāļāļāļĨāļēāļĒ
-
āļāļēāļĢāļāļģāļĢāļļāļāļĢāļąāļāļĐāļēāļāļĩāđāļĒāļēāļ (Maintenance Nightmare)
- āđāļāđāļĨāļ° interface āļĄāļĩ bug āđāļĨāļ° edge case āļāđāļēāļāļāļąāļ
- āđāļĄāļ·āđāļ vendor āļāļąāļāđāļāļ API āļāđāļāļāđāļāđāđāļ custom code āļāļļāļāļāļĢāļąāđāļ
- Documentation āļāļĢāļ°āļāļąāļāļāļĢāļ°āļāļēāļĒ āđāļĄāđāļĄāļĩāļĄāļēāļāļĢāļāļēāļ
-
Testing āļāđāļāļāļāļģāđāļĒāļāļŠāļģāļŦāļĢāļąāļāđāļāđāļĨāļ°āļĢāļ°āļāļ
-
āļāđāļāļāļīāļāļāļĨāļēāļāđāļāļāļēāļĢāđāļāļĨāļāļāđāļāļĄāļđāļĨ (Data Transformation Errors)
- āļāļąāļ§āļāļĒāđāļēāļāļāļąāļāļŦāļēāļāļĢāļīāļ:
// Lab System A: glucose = "120 mg/dL" // Lab System B: glucose = 120 (āļŦāļāđāļ§āļĒāđāļāđāļ mg/dL) // Lab System C: glucose = 6.7 (āļŦāļāđāļ§āļĒāđāļāđāļ mmol/L) - āļāļēāļĢāđāļāļĨāļāļŦāļāđāļ§āļĒāļāļīāļāļāļēāļāļāļģāđāļŦāđāđāļāļāļĒāđāļ§āļīāļāļīāļāļāļąāļĒāļāļīāļ
- Date format āļāđāļēāļāļāļąāļ (DD/MM/YYYY vs MM/DD/YYYY)
-
Character encoding issues (UTF-8 vs TIS-620)
-
āļāļēāļāļāļēāļĢāļāļĢāļ§āļāļŠāļāļāļāļ§āļēāļĄāļāļđāļāļāđāļāļ (No Validation)
- āđāļĄāđāļĄāļĩ schema validation
- Business rules āđāļĄāđāļāļąāļāđāļāļ
- āļāđāļāļĄāļđāļĨāļāļīāļāļĢāļđāļāđāļāļāļāđāļēāļāđāļāđāļēāļĢāļ°āļāļāđāļāđ
- āļāļĢāļ§āļāļāļāļāđāļāļāļīāļāļāļĨāļēāļāļāđāļē (āļāļĩāđ user interface)
āļŠāļģāļŦāļĢāļąāļ Healthcare Operations:
- āļāļ§āļēāļĄāļĨāđāļēāļāđāļēāđāļāļāļēāļĢāļĢāļąāļāļĐāļē (Treatment Delays)
- āļŦāļĄāļāļāđāļāļāļĢāļāļāļĨāđāļĨāļāļāļēāļ 3 āļĢāļ°āļāļ āđāļāđāđāļ§āļĨāļē 15-30 āļāļēāļāļĩ
- āļāđāļāļĄāļđāļĨ vital signs āđāļĄāđ real-time
- āļāļēāļĢ approve āļĒāļēāļāđāļāļāļāđāļēāļāļŦāļĨāļēāļĒāļāļąāđāļāļāļāļ manual
-
Emergency case āļāļđāļāļāļ°āļĨāļāđāļāļĢāļēāļ°āļāđāļāļĄāļđāļĨāđāļĄāđāļāļĢāđāļāļĄ
-
āļāļ§āļēāļĄāļāļīāļāļāļĨāļēāļāļāļēāļāļāļēāļĢāđāļāļāļĒāđ (Medical Errors)
- āļāļąāļ§āļāļĒāđāļēāļāļŠāļāļēāļāļāļēāļĢāļāđāļāļĢāļīāļ:
Scenario: āļāļđāđāļāđāļ§āļĒāļĄāļĩāļāļĢāļ°āļ§āļąāļāļīāđāļāđ Penicillin - āļāđāļāļĄāļđāļĨāļāļĒāļđāđāđāļāļĢāļ°āļāļ A āđāļāđāļŦāļĄāļāļāļđāļāļēāļāļĢāļ°āļāļ B - āļŦāļĄāļāļŠāļąāđāļāļĒāļēāļāļĩāđāļĄāļĩ Penicillin - āļāļđāđāļāđāļ§āļĒāđāļāļīāļāļāļēāļāļēāļĢāđāļāđāļĢāļļāļāđāļĢāļ - Duplicate orders āđāļāļĢāļēāļ°āļāđāļāļĄāļđāļĨāđāļĄāđ sync
- Wrong patient identification
-
Medication dosage errors
-
āļāļēāļĢāļāļģāļāļēāļāļāđāļģāļāđāļāļ (Redundant Work)
- āļāļĒāļēāļāļēāļĨāļāļĢāļāļāļāđāļāļĄāļđāļĨ vital signs 3 āļĢāļ°āļāļ
- āļāđāļāļĄāļđāļĨāļāļđāđāļāđāļ§āļĒāļāļđāļāļāļĢāļāļāļāđāļģāļāļĩāđāđāļāđāļĨāļ°āđāļāļāļ
- Manual transcription āļāļēāļ paper āđāļ digital
-
Double entry āđāļāļ·āđāļ verification
-
āļāļēāļĢāļāļīāļāļāļēāļĄāļāļđāđāļāđāļ§āļĒāļāļĩāđāđāļĄāđāļāđāļāđāļāļ·āđāļāļ (Fragmented Care)
- āđāļĄāđāļĄāļĩ single source of truth
- Timeline āļāļēāļĢāļĢāļąāļāļĐāļēāđāļĄāđāļāļąāļāđāļāļ
- āļāļēāļĢāļŠāđāļāļāđāļāļāļđāđāļāđāļ§āļĒāļāđāļāļĄāļđāļĨāļŠāļđāļāļŦāļēāļĒ
- Follow-up care āđāļĄāđāļāđāļāđāļāļ·āđāļāļ
ðĄ āđāļŦāļāļļāļāļĨāļāļĩāđāļāđāļāļāđāļāđāļĄāļēāļāļĢāļāļēāļ
1. āļāļēāļĢāđāļĨāļāđāļāļĨāļĩāđāļĒāļāļāđāļāļĄāļđāļĨ (Interoperability)
āļĄāļēāļāļĢāļāļēāļāļāđāļāļĄāļđāļĨāļāļēāļāļāļēāļĢāđāļāļāļĒāđāļāđāļ§āļĒāđāļŦāđāļĢāļ°āļāļāļāđāļēāļāđ āļŠāļēāļĄāļēāļĢāļāļŠāļ·āđāļāļŠāļēāļĢāļāļąāļāđāļāđāļāļĒāđāļēāļāļĄāļĩāļāļĢāļ°āļŠāļīāļāļāļīāļ āļēāļ:
- Semantic Interoperability (āļāļ§āļēāļĄāđāļāđāļēāđāļāđāļāļĢāļ°āļāļąāļāļāļ§āļēāļĄāļŦāļĄāļēāļĒ)
- āļĢāļ°āļāļāļāđāļēāļāđ āđāļāđāļēāđāļāļāļ§āļēāļĄāļŦāļĄāļēāļĒāļāļāļāļāđāļāļĄāļđāļĨāđāļŦāļĄāļ·āļāļāļāļąāļ
- āļāļąāļ§āļāļĒāđāļēāļ: "Blood Pressure" āđāļ FHIR āļŦāļĄāļēāļĒāļāļķāļ "āļāļ§āļēāļĄāļāļąāļāđāļĨāļŦāļīāļ" āđāļŠāļĄāļ
- āļāļēāļĢāđāļāđ terminology standards āđāļāđāļ SNOMED CT, LOINC
-
āļĨāļāļāļ§āļēāļĄāļāļĨāļļāļĄāđāļāļĢāļ·āļāđāļāļāļēāļĢāļāļĩāļāļ§āļēāļĄāļāđāļāļĄāļđāļĨ
-
Syntactic Interoperability (āļāļ§āļēāļĄāđāļāđāļēāļāļąāļāđāļāđāđāļāļĢāļ°āļāļąāļāđāļāļĢāļāļŠāļĢāđāļēāļ)
- āļĢāļđāļāđāļāļāļāđāļāļĄāļđāļĨāļāļĩāđāđāļāđāļāļĄāļēāļāļĢāļāļēāļāđāļāļĩāļĒāļ§āļāļąāļ
- JSON schema āļŠāļģāļŦāļĢāļąāļ FHIR, HL7 message format
- āļāļēāļĢ validate āļāđāļāļĄāļđāļĨāļāļēāļĄ schema āļāļąāļāđāļāļĄāļąāļāļī
-
āļĨāļāļāđāļāļāļīāļāļāļĨāļēāļāđāļāļāļēāļĢāđāļāļĨāļāļāđāļāļĄāļđāļĨ
-
Technical Interoperability (āļāļ§āļēāļĄāđāļāđāļēāļāļąāļāđāļāđāļāļēāļāđāļāļāļāļīāļ)
- āļāļēāļĢāđāļāļ·āđāļāļĄāļāđāļāļāļēāļāđāļāļāļāļīāļāļāļĩāđāđāļāđāļēāļāļąāļāđāļāđ
- RESTful APIs, MLLP protocols, WebSocket connections
- Authentication āđāļĨāļ° authorization standards
- Network protocols āđāļĨāļ° message queuing
2. āļāļ§āļēāļĄāļāļđāļāļāđāļāļāļāļāļāļāđāļāļĄāļđāļĨ (Data Integrity)
āļĄāļēāļāļĢāļāļēāļāļāđāļ§āļĒāļĢāļąāļāļĢāļāļāļāļ§āļēāļĄāļāļđāļāļāđāļāļāđāļĨāļ°āļāļ§āļēāļĄāļāđāļēāđāļāļ·āđāļāļāļ·āļāļāļāļāļāđāļāļĄāļđāļĨ:
- Schema Validation (āļāļēāļĢāļāļĢāļ§āļāļŠāļāļāļĢāļđāļāđāļāļ)
// āļāļąāļ§āļāļĒāđāļēāļ FHIR validation const patientSchema = { resourceType: 'Patient', required: ['identifier', 'name', 'gender'], properties: { birthDate: { type: 'string', pattern: '^[0-9]{4}-[0-9]{2}-[0-9]{2}$' } } }; - āļāļĢāļ§āļāļŠāļāļāļĢāļđāļāđāļāļāļāđāļāļĄāļđāļĨāļāļēāļĄāļĄāļēāļāļĢāļāļēāļāđāļāļĒāļāļąāļāđāļāļĄāļąāļāļī
- Reject āļāđāļāļĄāļđāļĨāļāļĩāđāđāļĄāđāļāļđāļāļāđāļāļāļāđāļāļāđāļāđāļēāļĢāļ°āļāļ
-
Consistent data types āđāļĨāļ° formats
-
Business Rules (āļāļāļāļēāļāļāļļāļĢāļāļīāļ)
// āļāļąāļ§āļāļĒāđāļēāļ business rules if (patient.age < 18 && !patient.guardian) { throw new Error('Minor patient requires guardian information'); } if (medication.dosage > medication.maxDailyDose) { throw new Error('Dosage exceeds maximum daily limit'); } - āļāļāđāļāļāļāđāļāļēāļāļāļļāļĢāļāļīāļāļāļĩāđāđāļāđāļĢāļąāļāļāļēāļĢāļĒāļāļĄāļĢāļąāļāļĢāļ°āļŦāļ§āđāļēāļāļāļĢāļ°āđāļāļĻ
- Clinical decision support rules
-
Drug interaction checking
-
Error Detection (āļāļēāļĢāļāļĢāļ§āļāļāļąāļāļāđāļāļāļīāļāļāļĨāļēāļ)
- āļĢāļ°āļāļāļāļĢāļ§āļāļāļąāļāļāđāļāļāļīāļāļāļĨāļēāļāđāļāđāļāļąāļāđāļāļĄāļąāļāļīāđāļĨāļ°āđāļāļ real-time
- Data quality monitoring āđāļĨāļ° reporting
- Automatic error correction mechanisms
- Alert systems āļŠāļģāļŦāļĢāļąāļāļāđāļāļĄāļđāļĨāļāļĩāđāļāļīāļāļāļāļāļī
3. āļāļ§āļēāļĄāļāļĨāļāļāļ āļąāļĒ (Security)
āļĄāļēāļāļĢāļāļēāļāļĄāļĩāļāļĨāđāļāļāļēāļĢāļĢāļąāļāļĐāļēāļāļ§āļēāļĄāļāļĨāļāļāļ āļąāļĒāļāļĩāđāđāļāđāļāđāļāļĢāđāļ:
- Standardized Encryption (āļāļēāļĢāđāļāđāļēāļĢāļŦāļąāļŠāļĄāļēāļāļĢāļāļēāļ)
// FHIR OAuth 2.0 + SMART on FHIR const authConfig = { encryption: 'AES-256-GCM', tokenExpiry: 3600, // 1 hour refreshTokenExpiry: 86400, // 24 hours scope: 'patient/*.read practitioner/*.read' }; - TLS 1.3 āļŠāļģāļŦāļĢāļąāļ data in transit
- AES-256 āļŠāļģāļŦāļĢāļąāļ data at rest
-
Digital signatures āļŠāļģāļŦāļĢāļąāļ data integrity
-
Access Control (āļāļēāļĢāļāļ§āļāļāļļāļĄāļāļēāļĢāđāļāđāļēāļāļķāļ)
- Role-based access control (RBAC)
- Attribute-based access control (ABAC)
- Fine-grained permissions āļāļ resource level
-
Patient consent management
-
Audit Trails (āļāļēāļĢāļāļīāļāļāļēāļĄāļāļēāļĢāđāļāđāļāļēāļ)
interface AuditEvent { timestamp: Date; actor: User; action: 'create' | 'read' | 'update' | 'delete'; resource: FHIRResource; outcome: 'success' | 'failure'; sourceIP: string; } - Complete audit logs āļāļāļāļāļēāļĢāđāļāđāļēāļāļķāļāļāđāļāļĄāļđāļĨ
- Tamper-proof logging mechanisms
- GDPR āđāļĨāļ° HIPAA compliance
4. āļāļĢāļ°āļŠāļīāļāļāļīāļ āļēāļ (Efficiency)
āļāļēāļĢāđāļāđāļĄāļēāļāļĢāļāļēāļāļāđāļ§āļĒāđāļāļīāđāļĄāļāļĢāļ°āļŠāļīāļāļāļīāļ āļēāļāđāļāļāļēāļĢāļāļąāļāļāļēāđāļĨāļ°āļāļģāđāļāļīāļāļāļēāļ:
- Reduced Development Time (āļĨāļāđāļ§āļĨāļēāļāļąāļāļāļē)
# āđāļāļāļāļĩāđāļāļ°āđāļāļĩāļĒāļ custom parser npm install @types/fhir npm install node-hl7-complete # āđāļāđāđāļ§āļĨāļēāļāļąāļāļāļē: 2 āļ§āļąāļ āđāļāļāļāļĩāđāļāļ°āđāļāđāļ 2 āļŠāļąāļāļāļēāļŦāđ - āļāļĢāđāļāļĄ libraries āđāļĨāļ° SDKs āļŠāļģāļŦāļĢāļąāļāļāļļāļāļ āļēāļĐāļē
- Code generators āđāļĨāļ° development tools
-
Extensive documentation āđāļĨāļ° examples
-
Lower Integration Costs (āļāđāļāļāļļāļāļāļēāļĢāđāļāļ·āđāļāļĄāļāđāļāļāđāļģ)
- āļĨāļāļāļģāļāļ§āļ custom adapters āļāļĩāđāļāđāļāļāļāļąāļāļāļē
- Vendor independence - āđāļāļĨāļĩāđāļĒāļ vendor āđāļāđāļāđāļēāļĒ
- Standardized testing procedures
-
Reduced maintenance overhead
-
Faster Data Access (āđāļāđāļēāļāļķāļāļāđāļāļĄāļđāļĨāđāļĢāđāļ§āļāļķāđāļ)
// FHIR Search API - āļāđāļāļŦāļēāļāļđāđāļāđāļ§āļĒāđāļāđāđāļ 1 request GET /Patient?identifier=1234567890&_include=Patient:general-practitioner // āđāļāļāļāļĩāđāļāļ°āļāđāļāļ query āļŦāļĨāļēāļĒ tables/systems - Optimized query patterns
- Standardized search parameters
- Efficient data serialization formats
- Built-in pagination āđāļĨāļ° filtering
5. āļĄāļēāļāļĢāļāļēāļāļāļļāļāļ āļēāļāđāļĨāļ°āļāļēāļĢāļāļāļīāļāļąāļāļīāļāļēāļĄ (Quality & Compliance)
- Healthcare Quality Metrics
- CQMs (Clinical Quality Measures) reporting
- HEDIS (Healthcare Effectiveness Data and Information Set)
-
Value-based care metrics
-
Regulatory Compliance
- FDA 21 CFR Part 11 compliance
- HIPAA Security āđāļĨāļ° Privacy Rules
- European GDPR requirements
- Local regulations (PDPA āđāļāļāļĢāļ°āđāļāļĻāđāļāļĒ)
6. Innovation āđāļĨāļ° Future-Proofing
- API Economy
- Third-party app development
- Healthcare marketplace integration
-
Telemedicine platforms
-
AI/ML Integration
- Structured data āļŠāļģāļŦāļĢāļąāļ machine learning
- Clinical decision support systems
-
Predictive analytics
-
Interoperability Networks
- Health Information Exchanges (HIEs)
- National health networks
- Cross-border healthcare data sharing
ð āļāļąāļ§āļāļĒāđāļēāļāļāļĨāļāļĢāļ°āļāļāļāļĢāļīāļāđāļāđāļĢāļāļāļĒāļēāļāļēāļĨ
graph LR
subgraph "Without Standards"
A1[Lab System<br/>Custom Format] -.->|Manual Entry| B1[EMR System]
C1[Radiology<br/>DICOM Only] -.->|Print & Scan| B1
D1[Pharmacy<br/>Excel Files] -.->|Phone Call| B1
B1 -.->|Fax| E1[External Hospital]
style A1 fill:#ffcccc
style C1 fill:#ffcccc
style D1 fill:#ffcccc
style E1 fill:#ffcccc
end
subgraph "With Standards"
A2[Lab System<br/>HL7 v2.x] <-->|Automated| B2[EMR System<br/>FHIR]
C2[Radiology<br/>DICOM + HL7] <-->|Real-time| B2
D2[Pharmacy<br/>FHIR] <-->|API| B2
B2 <-->|FHIR Bundle| E2[External Hospital]
style A2 fill:#ccffcc
style B2 fill:#ccffcc
style C2 fill:#ccffcc
style D2 fill:#ccffcc
style E2 fill:#ccffcc
end
1.2 āļ āļēāļāļĢāļ§āļĄāļĄāļēāļāļĢāļāļēāļāļŦāļĨāļąāļ
graph TD
A[Medical Data Standards] --> B[HL7 Family]
A --> C[Other Standards]
B --> D[HL7 v2.x<br/>Message-based]
B --> E[HL7 v3<br/>XML-based]
B --> F[FHIR<br/>RESTful API]
C --> G[DICOM<br/>Medical Imaging]
C --> H[ICD-10<br/>Diagnosis Coding]
C --> I[LOINC<br/>Lab Results]
C --> J[SNOMED CT<br/>Clinical Terms]
2. HL7 Version 2.x
2.1 āļ āļēāļāļĢāļ§āļĄ HL7 v2.x
HL7 (Health Level Seven) Version 2.x āđāļāđāļāļĄāļēāļāļĢāļāļēāļāļāļĩāđāđāļāđāļāļąāļāļāļĒāđāļēāļāđāļāļĢāđāļŦāļĨāļēāļĒāļāļĩāđāļŠāļļāļāđāļāļāļēāļĢāđāļĨāļāđāļāļĨāļĩāđāļĒāļāļāđāļāļĄāļđāļĨāļāļēāļāļāļĨāļīāļāļīāļ āđāļāļĒāđāļāđāļĢāļđāļāđāļāļāļāđāļāļāļ§āļēāļĄ (text-based messages)
2.2 āđāļāļĢāļāļŠāļĢāđāļēāļāļāđāļāļāļ§āļēāļĄ HL7 v2.x
Message Structure:
MSH|^~\&|SendingApp|SendingFacility|ReceivingApp|ReceivingFacility|20250902120000||ADT^A01|MSG00001|P|2.5
EVN|A01|20250902120000
PID|1||123456789^^^Hospital^MR||āđāļāļāļĩ^āļŠāļĄāļāļēāļĒ^^^^^L||19850615|M||Thai|123 āļŦāļĄāļđāđ 5 āļ.āļŠāļļāļāļļāļĄāļ§āļīāļ^^āļāļĢāļļāļāđāļāļ^^10110^TH||(66)021234567|(66)021234567||Buddhist|Single||1234567890123|||||||||||
PV1|1|I|ICU^101^A^Hospital||||^āđāļāļāļĒāđ^āļāļ.āļŠāļĄāļĻāļąāļāļāļīāđ||||||||||||||||||||||||||||||||||||20250902120000
Segment Breakdown:
- MSH (Message Header): āļāđāļāļĄāļđāļĨāļŠāđāļ§āļāļŦāļąāļ§āļāļāļāļāđāļāļāļ§āļēāļĄ
- EVN (Event Type): āļāļĢāļ°āđāļ āļāļāļāļāđāļŦāļāļļāļāļēāļĢāļāđ
- PID (Patient Identification): āļāđāļāļĄāļđāļĨāļāļđāđāļāđāļ§āļĒ
- PV1 (Patient Visit): āļāđāļāļĄāļđāļĨāļāļēāļĢāđāļāđāļēāļĢāļąāļāļāļĢāļīāļāļēāļĢ
2.3 Message Types āļāļĩāđāļŠāļģāļāļąāļ
| Message Type | Description | Usage in Healthcare |
|---|---|---|
| ADT | Admission, Discharge, Transfer | āļāļąāļāļāļēāļĢāļāļēāļĢāļĢāļąāļ-āļāļģāļŦāļāđāļēāļĒāļāļđāđāļāđāļ§āļĒ |
| ORM | Order Message | āļŠāļąāđāļāļāļēāļĢāļāļĢāļ§āļāļāļēāļāļŦāđāļāļāļāļāļīāļāļąāļāļīāļāļēāļĢ |
| ORU | Observation Result | āļŠāđāļāļāļĨāļāļēāļĢāļāļĢāļ§āļ |
| SIU | Scheduling Information | āļāļąāļāļŦāļĄāļēāļĒāļāļđāđāļāđāļ§āļĒ |
| MDM | Medical Document Management | āļāļąāļāļāļēāļĢāđāļāļāļŠāļēāļĢāļāļēāļāļāļēāļĢāđāļāļāļĒāđ |
2.4 āļāļąāļ§āļāļĒāđāļēāļāļāļēāļĢāđāļāđāļāļēāļāđāļ TypeScript
// HL7 v2.x Parser Example for MediTech
interface HL7Message {
segments: Map<string, HL7Segment>;
messageType: string;
messageControlId: string;
}
interface HL7Segment {
name: string;
fields: string[];
}
class HL7Parser {
private readonly fieldSeparator = '|';
private readonly componentSeparator = '^';
parse(message: string): HL7Message {
const lines = message.split('\r');
const segments = new Map<string, HL7Segment>();
lines.forEach(line => {
if (line.length > 0) {
const fields = line.split(this.fieldSeparator);
const segmentName = fields[0];
segments.set(segmentName, {
name: segmentName,
fields: fields.slice(1)
});
}
});
const mshSegment = segments.get('MSH');
const messageType = mshSegment?.fields[7] || '';
const messageControlId = mshSegment?.fields[8] || '';
return {
segments,
messageType,
messageControlId
};
}
// āļŠāļĢāđāļēāļ ADT^A01 (Patient Admission) Message
createAdmissionMessage(patient: Patient, visit: Visit): string {
const timestamp = new Date().toISOString().replace(/[-:]/g, '').replace('T', '').split('.')[0];
const messageId = `MSG${Date.now()}`;
const msh = `MSH|^~\\&|MediTech|Hospital|ReceivingApp|Facility|${timestamp}||ADT^A01|${messageId}|P|2.5`;
const evn = `EVN|A01|${timestamp}`;
const pid = `PID|1||${patient.hn}^^^Hospital^MR||${patient.lastName}^${patient.firstName}||${patient.birthDate}|${patient.gender}||Thai|||||||${patient.nationalId}`;
const pv1 = `PV1|1|${visit.type}|${visit.ward}^${visit.bed}||||${visit.doctor}||||||||||||${visit.visitNumber}|||||||||||||||||||||||${timestamp}`;
return [msh, evn, pid, pv1].join('\r');
}
}
2.5 āļāđāļāļāļĩāđāļĨāļ°āļāđāļāļāļģāļāļąāļāļāļāļ HL7 v2.x
āļāđāļāļāļĩ: - â āđāļāđāļāļēāļāđāļāļĢāđāļŦāļĨāļēāļĒāļāļąāđāļ§āđāļĨāļ - â āļĢāļāļāļĢāļąāļāļāļēāļĢāļāļģāļāļēāļāđāļāļ real-time - â āļāļāļēāļāļāđāļāļāļ§āļēāļĄāđāļĨāđāļ āļāļĢāļ°āļŦāļĒāļąāļ bandwidth - â āļĄāļĩ library āļĢāļāļāļĢāļąāļāļŦāļĨāļēāļĒāļ āļēāļĐāļē
āļāđāļāļāļģāļāļąāļ: - â āđāļāļĢāļāļŠāļĢāđāļēāļāđāļĄāđāļĒāļ·āļāļŦāļĒāļļāđāļ - â āđāļĄāđāļĄāļĩ schema validation āđāļāļāļąāļ§ - â āļāļēāļĢ customize āļāļģāđāļāđāļĒāļēāļ - â āđāļĄāđāļĢāļāļāļĢāļąāļ RESTful API āđāļāļĒāļāļĢāļ
3. HL7 Version 3
3.1 āļ āļēāļāļĢāļ§āļĄ HL7 v3
HL7 Version 3 āđāļāđ XML āđāļāđāļāļāļ·āđāļāļāļēāļ āđāļĨāļ°āļĄāļĩāđāļāļĢāļāļŠāļĢāđāļēāļāļāļĩāđāđāļāđāļāļĢāļ°āļāļāļĄāļēāļāļāļķāđāļ āđāļāđ Reference Information Model (RIM) āđāļāđāļāđāļāļāļāļĨāļēāļ
3.2 āđāļāļĢāļāļŠāļĢāđāļēāļ XML āļāļāļ HL7 v3
<?xml version="1.0" encoding="UTF-8"?>
<PRPA_IN201301UV02 xmlns="urn:hl7-org:v3"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<id root="2.16.840.1.113883.19.1122" extension="MSG00001"/>
<creationTime value="20250902120000"/>
<versionCode code="3.0"/>
<interactionId root="2.16.840.1.113883.1.6" extension="PRPA_IN201301UV02"/>
<receiver typeCode="RCV">
<device classCode="DEV" determinerCode="INSTANCE">
<id root="2.16.840.1.113883.19.1122.1"/>
<name>MediTech HIS</name>
</device>
</receiver>
<sender typeCode="SND">
<device classCode="DEV" determinerCode="INSTANCE">
<id root="2.16.840.1.113883.19.1122.2"/>
<name>External System</name>
</device>
</sender>
<controlActProcess classCode="CACT" moodCode="EVN">
<subject typeCode="SUBJ">
<registrationEvent classCode="REG" moodCode="EVN">
<subject1 typeCode="SBJ">
<patient classCode="PAT">
<id root="2.16.840.1.113883.19.1122.5" extension="123456789"/>
<patientPerson>
<name>
<given>āļŠāļĄāļāļēāļĒ</given>
<family>āđāļāļāļĩ</family>
</name>
<birthTime value="19850615"/>
<administrativeGenderCode code="M" codeSystem="2.16.840.1.113883.5.1"/>
</patientPerson>
</patient>
</subject1>
</registrationEvent>
</subject>
</controlActProcess>
</PRPA_IN201301UV02>
3.3 CDA (Clinical Document Architecture)
CDA āđāļāđāļāļŠāđāļ§āļāļŦāļāļķāđāļāļāļāļ HL7 v3 āļāļĩāđāđāļāđāļŠāļģāļŦāļĢāļąāļāđāļĨāļāđāļāļĨāļĩāđāļĒāļāđāļāļāļŠāļēāļĢāļāļēāļāļāļĨāļīāļāļīāļ
<?xml version="1.0" encoding="UTF-8"?>
<ClinicalDocument xmlns="urn:hl7-org:v3">
<typeId root="2.16.840.1.113883.1.3" extension="POCD_HD000040"/>
<templateId root="2.16.840.1.113883.10.20.22.1.1"/>
<id root="2.16.840.1.113883.19.5" extension="DOC123456"/>
<code code="34133-9"
displayName="Summary of episode note"
codeSystem="2.16.840.1.113883.6.1"
codeSystemName="LOINC"/>
<title>Discharge Summary</title>
<effectiveTime value="20250902120000"/>
<recordTarget>
<patientRole>
<id extension="123456789" root="2.16.840.1.113883.19.5"/>
<patient>
<name>
<given>āļŠāļĄāļāļēāļĒ</given>
<family>āđāļāļāļĩ</family>
</name>
</patient>
</patientRole>
</recordTarget>
<component>
<structuredBody>
<component>
<section>
<title>Chief Complaint</title>
<text>Chest pain for 3 days</text>
</section>
</component>
</structuredBody>
</component>
</ClinicalDocument>
4. FHIR (Fast Healthcare Interoperability Resources)
4.1 āļ āļēāļāļĢāļ§āļĄ FHIR
FHIR (āļāļāļāđāļŠāļĩāļĒāļāļ§āđāļē "Fire") āđāļāđāļāļĄāļēāļāļĢāļāļēāļāļĢāļļāđāļāđāļŦāļĄāđāļāļĩāđāļāļąāļāļāļēāđāļāļĒ HL7 āđāļāđ RESTful API āđāļĨāļ°āļĢāļāļāļĢāļąāļ JSON/XML āļāļģāđāļŦāđāļāđāļēāļĒāļāđāļāļāļēāļĢāļāļąāļāļāļēāđāļĨāļ°āļāļđāļĢāļāļēāļāļēāļĢ
4.2 āļŦāļĨāļąāļāļāļēāļĢāļŠāļģāļāļąāļāļāļāļ FHIR
- Resources: āļŦāļāđāļ§āļĒāļāđāļāļĄāļđāļĨāļāļ·āđāļāļāļēāļ (Patient, Observation, Medication)
- RESTful API: āđāļāđ HTTP methods (GET, POST, PUT, DELETE)
- Bundles: āļāļēāļĢāļĢāļ§āļĄāļŦāļĨāļēāļĒ resources āđāļāđāļēāļāđāļ§āļĒāļāļąāļ
- Profiles: āļāļēāļĢāļāļĢāļąāļāđāļāđāļ resources āđāļŦāđāđāļŦāļĄāļēāļ°āļāļąāļāļāļĢāļīāļāļ
- Extensions: āļāļēāļĢāđāļāļīāđāļĄāļāđāļāļĄāļđāļĨāļāļĩāđāđāļĄāđāļĄāļĩāđāļāļĄāļēāļāļĢāļāļēāļ
4.3 FHIR Resources āļāļĩāđāļŠāļģāļāļąāļ
graph LR
A[FHIR Resources] --> B[Foundation]
A --> C[Clinical]
A --> D[Financial]
A --> E[Workflow]
B --> B1[Patient]
B --> B2[Organization]
B --> B3[Practitioner]
C --> C1[Observation]
C --> C2[Condition]
C --> C3[MedicationRequest]
C --> C4[Procedure]
D --> D1[Claim]
D --> D2[Coverage]
E --> E1[Appointment]
E --> E2[Encounter]
E --> E3[Task]
4.4 āļāļąāļ§āļāļĒāđāļēāļ FHIR Patient Resource (JSON)
{
"resourceType": "Patient",
"id": "123456789",
"meta": {
"versionId": "1",
"lastUpdated": "2025-09-02T12:00:00Z",
"profile": ["http://hl7.org/fhir/StructureDefinition/Patient"]
},
"identifier": [
{
"use": "official",
"type": {
"coding": [{
"system": "http://terminology.hl7.org/CodeSystem/v2-0203",
"code": "MR",
"display": "Medical Record Number"
}]
},
"system": "http://hospital.meditech.com/identifier/mrn",
"value": "123456789"
},
{
"use": "official",
"type": {
"coding": [{
"system": "http://terminology.hl7.org/CodeSystem/v2-0203",
"code": "NI",
"display": "National ID"
}]
},
"system": "http://thailand.gov/identifier/national-id",
"value": "1234567890123"
}
],
"active": true,
"name": [
{
"use": "official",
"text": "āļāļēāļĒāļŠāļĄāļāļēāļĒ āđāļāļāļĩ",
"family": "āđāļāļāļĩ",
"given": ["āļŠāļĄāļāļēāļĒ"]
}
],
"telecom": [
{
"system": "phone",
"value": "+66821234567",
"use": "mobile"
},
{
"system": "email",
"value": "[email protected]"
}
],
"gender": "male",
"birthDate": "1985-06-15",
"address": [
{
"use": "home",
"type": "physical",
"text": "123 āļŦāļĄāļđāđ 5 āļ.āļŠāļļāļāļļāļĄāļ§āļīāļ āđāļāļ§āļāļāļĨāļāļāļāļąāļ āđāļāļāļāļĨāļāļāđāļāļĒ āļāļĢāļļāļāđāļāļāļŊ 10110",
"line": ["123 āļŦāļĄāļđāđ 5", "āļ.āļŠāļļāļāļļāļĄāļ§āļīāļ"],
"city": "āļāļĢāļļāļāđāļāļāļĄāļŦāļēāļāļāļĢ",
"district": "āļāļĨāļāļāđāļāļĒ",
"postalCode": "10110",
"country": "TH"
}
],
"maritalStatus": {
"coding": [{
"system": "http://terminology.hl7.org/CodeSystem/v3-MaritalStatus",
"code": "M",
"display": "Married"
}]
},
"contact": [
{
"relationship": [{
"coding": [{
"system": "http://terminology.hl7.org/CodeSystem/v2-0131",
"code": "N",
"display": "Next-of-Kin"
}]
}],
"name": {
"text": "āļāļēāļāļŠāļēāļ§āļŠāļĄāļŦāļāļīāļ āđāļāļāļĩ"
},
"telecom": [{
"system": "phone",
"value": "+66823456789"
}]
}
]
}
4.5 FHIR RESTful API Operations
Basic CRUD Operations:
// TypeScript Example for MediTech FHIR Client
import axios from 'axios';
class FHIRClient {
private baseURL: string;
private headers: any;
constructor(baseURL: string, accessToken?: string) {
this.baseURL = baseURL;
this.headers = {
'Content-Type': 'application/fhir+json',
'Accept': 'application/fhir+json'
};
if (accessToken) {
this.headers['Authorization'] = `Bearer ${accessToken}`;
}
}
// CREATE - āļŠāļĢāđāļēāļ Patient āđāļŦāļĄāđ
async createPatient(patient: any): Promise<any> {
const response = await axios.post(
`${this.baseURL}/Patient`,
patient,
{ headers: this.headers }
);
return response.data;
}
// READ - āļāđāļēāļāļāđāļāļĄāļđāļĨ Patient
async getPatient(id: string): Promise<any> {
const response = await axios.get(
`${this.baseURL}/Patient/${id}`,
{ headers: this.headers }
);
return response.data;
}
// UPDATE - āļāļąāļāđāļāļ Patient
async updatePatient(id: string, patient: any): Promise<any> {
const response = await axios.put(
`${this.baseURL}/Patient/${id}`,
patient,
{ headers: this.headers }
);
return response.data;
}
// DELETE - āļĨāļ Patient
async deletePatient(id: string): Promise<void> {
await axios.delete(
`${this.baseURL}/Patient/${id}`,
{ headers: this.headers }
);
}
// SEARCH - āļāđāļāļŦāļē Patients
async searchPatients(params: any): Promise<any> {
const response = await axios.get(
`${this.baseURL}/Patient`,
{
headers: this.headers,
params: params
}
);
return response.data;
}
// BATCH/TRANSACTION - āļŠāđāļāļŦāļĨāļēāļĒ operations āļāļĢāđāļāļĄāļāļąāļ
async transaction(bundle: any): Promise<any> {
const response = await axios.post(
`${this.baseURL}`,
bundle,
{ headers: this.headers }
);
return response.data;
}
}
// āļāļąāļ§āļāļĒāđāļēāļāļāļēāļĢāđāļāđāļāļēāļ
const fhirClient = new FHIRClient('https://api.meditech.com/fhir/r4');
// āļāđāļāļŦāļēāļāļđāđāļāđāļ§āļĒāļāđāļ§āļĒ National ID
const searchParams = {
identifier: '1234567890123',
_format: 'json'
};
fhirClient.searchPatients(searchParams)
.then(bundle => {
console.log(`Found ${bundle.total} patients`);
bundle.entry?.forEach((entry: any) => {
console.log(`Patient: ${entry.resource.name[0].text}`);
});
});
4.6 FHIR Bundle Example (Transaction)
{
"resourceType": "Bundle",
"type": "transaction",
"entry": [
{
"fullUrl": "urn:uuid:61ebe359-bfdc-4613-8bf2-c5e300945f0a",
"resource": {
"resourceType": "Patient",
"identifier": [{
"system": "http://hospital.meditech.com/identifier/mrn",
"value": "123456789"
}],
"name": [{
"use": "official",
"family": "āđāļāļāļĩ",
"given": ["āļŠāļĄāļāļēāļĒ"]
}],
"gender": "male",
"birthDate": "1985-06-15"
},
"request": {
"method": "POST",
"url": "Patient"
}
},
{
"fullUrl": "urn:uuid:88f151c0-a954-468a-88bd-5ae15c08e059",
"resource": {
"resourceType": "Encounter",
"status": "in-progress",
"class": {
"system": "http://terminology.hl7.org/CodeSystem/v3-ActCode",
"code": "AMB",
"display": "ambulatory"
},
"subject": {
"reference": "urn:uuid:61ebe359-bfdc-4613-8bf2-c5e300945f0a"
},
"period": {
"start": "2025-09-02T09:00:00Z"
}
},
"request": {
"method": "POST",
"url": "Encounter"
}
}
]
}
4.7 FHIR Subscription for Real-time Updates
{
"resourceType": "Subscription",
"status": "active",
"criteria": "Patient?identifier=1234567890123",
"channel": {
"type": "websocket",
"endpoint": "wss://api.meditech.com/fhir/websocket",
"payload": "application/fhir+json"
}
}
5. āļāļēāļĢāđāļāļĢāļĩāļĒāļāđāļāļĩāļĒāļāļĄāļēāļāļĢāļāļēāļ (Standards Comparison)
5.1 āļāļēāļĢāļēāļāđāļāļĢāļĩāļĒāļāđāļāļĩāļĒāļ HL7 v2.x, HL7 v3, āđāļĨāļ° FHIR
| Feature | HL7 v2.x | HL7 v3 | FHIR |
|---|---|---|---|
| āļĢāļđāļāđāļāļāļāđāļāļĄāļđāļĨ | Pipe-delimited text | XML | JSON/XML |
| Protocol | MLLP/TCP | SOAP | RESTful API |
| āļāļ§āļēāļĄāļāļąāļāļāđāļāļ | āļāļēāļāļāļĨāļēāļ | āļŠāļđāļ | āļāđāļģ |
| āļāļ§āļēāļĄāļĒāļ·āļāļŦāļĒāļļāđāļ | āļāļģāļāļąāļ | āļāļēāļāļāļĨāļēāļ | āļŠāļđāļ |
| Learning Curve | āļāļēāļāļāļĨāļēāļ | āļŠāļđāļāļĄāļēāļ | āļāđāļģ |
| āļāļēāļĢāļĢāļāļāļĢāļąāļ Mobile | āđāļĄāđāļāļĩ | āđāļĄāđāļāļĩ | āļāļĩāļĄāļēāļ |
| Real-time Support | āļāļĩ | āļāļēāļāļāļĨāļēāļ | āļāļĩāļĄāļēāļ (WebSocket) |
| āļāļēāļĢāđāļāđāļāļēāļāđāļāļāļąāļāļāļļāļāļąāļ | āđāļāļĢāđāļŦāļĨāļēāļĒāļĄāļēāļ | āļāđāļāļĒ | āđāļāļīāđāļĄāļāļķāđāļāļāļĒāđāļēāļāļĢāļ§āļāđāļĢāđāļ§ |
| Developer-friendly | āļāļēāļāļāļĨāļēāļ | āļāđāļģ | āļŠāļđāļāļĄāļēāļ |
| āļāļāļēāļāļāđāļāļĄāļđāļĨ | āđāļĨāđāļ | āđāļŦāļāđ | āļāļēāļāļāļĨāļēāļ |
5.2 āđāļĄāļ·āđāļāđāļāļāļ§āļĢāđāļāđāļĄāļēāļāļĢāļāļēāļāđāļ
flowchart TD
A[Choose Standard] --> B{New System?}
B -->|Yes| C[FHIR R4]
B -->|No| D{Legacy Integration?}
D -->|Yes| E{What Protocol?}
D -->|No| C
E -->|MLLP/TCP| F[HL7 v2.x]
E -->|SOAP/XML| G[HL7 v3]
E -->|REST API| C
C --> H[Modern & Scalable]
F --> I[Wide Compatibility]
G --> J[Complex Requirements]
6. āļāļēāļĢāļāļģāđāļāđāļāđāđāļ MediTech (Implementation in MediTech)
6.1 Architecture Overview
graph TB
subgraph "MediTech Core System"
A[MediTech HIS<br/>PostgreSQL + Nest.js]
B[FHIR Server<br/>HAPI FHIR]
C[HL7 Interface Engine<br/>Mirth Connect]
end
subgraph "Internal Systems"
D[Laboratory<br/>HL7 v2.x]
E[Radiology<br/>DICOM + HL7]
F[Pharmacy<br/>FHIR R4]
end
subgraph "External Systems"
G[NHSO API<br/>REST/SOAP]
H[Other Hospitals<br/>FHIR/HL7]
I[Mobile Apps<br/>FHIR REST]
end
A <--> B
A <--> C
C <--> D
C <--> E
B <--> F
B <--> G
B <--> H
B <--> I
6.2 Implementation Strategy
Phase 1: Internal Integration (HL7 v2.x)
// MediTech HL7 v2.x Integration Service
@Injectable()
export class HL7IntegrationService {
constructor(
private readonly hl7Parser: HL7Parser,
private readonly patientService: PatientService,
private readonly visitService: VisitService
) {}
async processADTMessage(message: string): Promise<void> {
const parsedMessage = this.hl7Parser.parse(message);
switch (parsedMessage.messageType) {
case 'ADT^A01': // Admission
await this.handleAdmission(parsedMessage);
break;
case 'ADT^A03': // Discharge
await this.handleDischarge(parsedMessage);
break;
case 'ADT^A08': // Update patient
await this.handlePatientUpdate(parsedMessage);
break;
}
}
private async handleAdmission(message: HL7Message): Promise<void> {
const pidSegment = message.segments.get('PID');
const pv1Segment = message.segments.get('PV1');
// Extract patient data
const patient = {
hn: pidSegment?.fields[2].split('^')[0],
firstName: pidSegment?.fields[4].split('^')[1],
lastName: pidSegment?.fields[4].split('^')[0],
birthDate: pidSegment?.fields[6],
gender: pidSegment?.fields[7]
};
// Create or update patient
await this.patientService.upsert(patient);
// Create visit
const visit = {
patientHN: patient.hn,
admissionDate: pv1Segment?.fields[43],
ward: pv1Segment?.fields[2].split('^')[0],
bed: pv1Segment?.fields[2].split('^')[1]
};
await this.visitService.create(visit);
}
}
Phase 2: External Integration (FHIR R4)
// MediTech FHIR Integration Service
@Injectable()
export class FHIRIntegrationService {
private fhirClient: FHIRClient;
constructor(
@Inject('FHIR_CONFIG') private config: FHIRConfig,
private readonly patientService: PatientService
) {
this.fhirClient = new FHIRClient(config.baseURL, config.accessToken);
}
// Transform MediTech Patient to FHIR Patient
async exportPatientToFHIR(patientId: string): Promise<any> {
const patient = await this.patientService.findById(patientId);
const fhirPatient = {
resourceType: 'Patient',
identifier: [
{
system: 'http://hospital.meditech.com/identifier/mrn',
value: patient.hn
},
{
system: 'http://thailand.gov/identifier/national-id',
value: patient.nationalId
}
],
name: [{
use: 'official',
family: patient.lastName,
given: [patient.firstName]
}],
gender: patient.gender.toLowerCase(),
birthDate: patient.birthDate,
address: [{
use: 'home',
text: patient.address,
city: patient.city,
postalCode: patient.postalCode,
country: 'TH'
}],
telecom: [
{
system: 'phone',
value: patient.phone,
use: 'mobile'
}
]
};
return await this.fhirClient.createPatient(fhirPatient);
}
// Import FHIR Patient to MediTech
async importPatientFromFHIR(fhirPatientId: string): Promise<void> {
const fhirPatient = await this.fhirClient.getPatient(fhirPatientId);
const patient = {
hn: this.extractIdentifier(fhirPatient, 'MR'),
nationalId: this.extractIdentifier(fhirPatient, 'NI'),
firstName: fhirPatient.name?.[0]?.given?.[0] || '',
lastName: fhirPatient.name?.[0]?.family || '',
gender: fhirPatient.gender?.toUpperCase() || 'U',
birthDate: fhirPatient.birthDate,
phone: this.extractTelecom(fhirPatient, 'phone'),
email: this.extractTelecom(fhirPatient, 'email'),
address: fhirPatient.address?.[0]?.text || ''
};
await this.patientService.upsert(patient);
}
private extractIdentifier(patient: any, type: string): string {
const identifier = patient.identifier?.find(
(id: any) => id.type?.coding?.[0]?.code === type
);
return identifier?.value || '';
}
private extractTelecom(patient: any, system: string): string {
const telecom = patient.telecom?.find(
(t: any) => t.system === system
);
return telecom?.value || '';
}
}
6.3 MediTech API Gateway Configuration
// API Gateway routes for different standards
@Controller('api/v1/integration')
export class IntegrationController {
constructor(
private readonly hl7Service: HL7IntegrationService,
private readonly fhirService: FHIRIntegrationService
) {}
// HL7 v2.x endpoint
@Post('hl7/v2')
@Header('Content-Type', 'x-application/hl7-v2+er7')
async receiveHL7Message(@Body() message: string): Promise<string> {
await this.hl7Service.processADTMessage(message);
// Return HL7 ACK message
const ackMessage = this.generateACK(message, 'AA');
return ackMessage;
}
// FHIR endpoint
@Post('fhir/Patient')
@Header('Content-Type', 'application/fhir+json')
async createFHIRPatient(@Body() patient: any): Promise<any> {
const result = await this.fhirService.importPatientFromFHIR(patient.id);
return {
resourceType: 'OperationOutcome',
issue: [{
severity: 'information',
code: 'informational',
details: {
text: 'Patient imported successfully'
}
}]
};
}
// Webhook for real-time updates
@Post('webhook/fhir')
async handleFHIRWebhook(@Body() notification: any): Promise<void> {
// Process FHIR subscription notification
if (notification.resourceType === 'Bundle') {
for (const entry of notification.entry) {
await this.processFHIRResource(entry.resource);
}
}
}
}
7. āļĄāļēāļāļĢāļāļēāļāļāļ·āđāļāđ āļāļĩāđāđāļāļĩāđāļĒāļ§āļāđāļāļ (Related Standards)
7.1 DICOM (Digital Imaging and Communications in Medicine)
āļŠāļģāļŦāļĢāļąāļāļāļēāļĢāļāļąāļāļāļēāļĢāļ āļēāļāļāļēāļāļāļēāļĢāđāļāļāļĒāđ:
// DICOM Integration Example
interface DICOMStudy {
studyInstanceUID: string;
patientID: string;
patientName: string;
studyDate: string;
modality: string;
studyDescription: string;
series: DICOMSeries[];
}
interface DICOMSeries {
seriesInstanceUID: string;
seriesDescription: string;
modality: string;
instances: DICOMInstance[];
}
interface DICOMInstance {
sopInstanceUID: string;
instanceNumber: number;
imageURL: string;
}
7.2 ICD-10 (International Classification of Diseases)
āļŠāļģāļŦāļĢāļąāļāļāļēāļĢāļĨāļāļĢāļŦāļąāļŠāđāļĢāļ:
{
"code": "I21.0",
"display": "Acute transmural myocardial infarction of anterior wall",
"displayThai": "āļāļĨāđāļēāļĄāđāļāļ·āđāļāļŦāļąāļ§āđāļāļāļēāļĒāđāļāļĩāļĒāļāļāļĨāļąāļāļāļāļīāļāđāļāđāļĄāļāļ§āļēāļĄāļŦāļāļēāļāļāļāļāļāļąāļāļŦāļąāļ§āđāļāļŠāđāļ§āļāļŦāļāđāļē",
"category": "I21",
"chapter": "IX"
}
7.3 LOINC (Logical Observation Identifiers Names and Codes)
āļŠāļģāļŦāļĢāļąāļāļāļĨāļāļēāļĢāļāļĢāļ§āļāļāļēāļāļŦāđāļāļāļāļāļīāļāļąāļāļīāļāļēāļĢ:
{
"code": "2160-0",
"display": "Creatinine [Mass/volume] in Serum or Plasma",
"displayThai": "āļāļĢāļĩāđāļāļāļīāļāļīāļāđāļāļāļĩāļĢāļąāļĄāļŦāļĢāļ·āļāļāļĨāļēāļŠāļĄāļē",
"unit": "mg/dL",
"normalRange": {
"male": "0.7-1.3",
"female": "0.6-1.1"
}
}
7.4 SNOMED CT (Systematized Nomenclature of Medicine Clinical Terms)
āļŠāļģāļŦāļĢāļąāļāļāļģāļĻāļąāļāļāđāļāļēāļāļāļĨāļīāļāļīāļ:
{
"conceptId": "22298006",
"term": "Myocardial infarction",
"termThai": "āļāļĨāđāļēāļĄāđāļāļ·āđāļāļŦāļąāļ§āđāļāļāļēāļĒ",
"semanticTag": "disorder",
"hierarchy": [
"404684003|Clinical finding",
"118234003|Finding by site",
"301095005|Cardiac finding"
]
}
8. Best Practices āđāļĨāļ°āļāđāļāđāļāļ°āļāļģ
8.1 Security Best Practices
1. Authentication & Authorization
// OAuth 2.0 for FHIR
const fhirAuthConfig = {
authorizationURL: 'https://auth.meditech.com/oauth/authorize',
tokenURL: 'https://auth.meditech.com/oauth/token',
clientId: process.env.FHIR_CLIENT_ID,
clientSecret: process.env.FHIR_CLIENT_SECRET,
scopes: ['patient/*.read', 'patient/*.write', 'launch/patient']
};
2. Audit Logging
// Audit all data exchanges
@Injectable()
export class IntegrationAuditService {
async logDataExchange(
standard: 'HL7v2' | 'HL7v3' | 'FHIR',
operation: string,
resourceType: string,
resourceId: string,
userId: string,
success: boolean,
details?: any
): Promise<void> {
await this.auditRepository.create({
timestamp: new Date(),
standard,
operation,
resourceType,
resourceId,
userId,
success,
details,
ipAddress: this.getClientIP(),
userAgent: this.getUserAgent()
});
}
}
8.2 Performance Optimization
1. Caching Strategy
// Redis caching for frequently accessed FHIR resources
@Injectable()
export class FHIRCacheService {
constructor(
@InjectRedis() private readonly redis: Redis
) {}
async getCachedResource(
resourceType: string,
id: string
): Promise<any> {
const key = `fhir:${resourceType}:${id}`;
const cached = await this.redis.get(key);
if (cached) {
return JSON.parse(cached);
}
return null;
}
async setCachedResource(
resourceType: string,
id: string,
resource: any,
ttl: number = 3600
): Promise<void> {
const key = `fhir:${resourceType}:${id}`;
await this.redis.setex(key, ttl, JSON.stringify(resource));
}
}
2. Batch Processing
// Batch FHIR transactions for better performance
async function batchFHIROperations(operations: any[]): Promise<any> {
const bundle = {
resourceType: 'Bundle',
type: 'batch',
entry: operations.map(op => ({
resource: op.resource,
request: {
method: op.method,
url: op.url
}
}))
};
return await fhirClient.transaction(bundle);
}
8.3 Error Handling
// Comprehensive error handling for integration
class IntegrationErrorHandler {
handleError(error: any, context: string): void {
if (error.response) {
// FHIR OperationOutcome
if (error.response.data.resourceType === 'OperationOutcome') {
const issues = error.response.data.issue;
issues.forEach((issue: any) => {
console.error(`FHIR Error [${issue.severity}]: ${issue.details?.text}`);
});
}
// HL7 v2.x NAK
else if (error.message.includes('NAK')) {
console.error('HL7 Message rejected:', error.message);
}
} else if (error.request) {
// Network error
console.error(`Network error in ${context}:`, error.message);
// Implement retry logic
this.scheduleRetry(context, error);
} else {
// Other errors
console.error(`Unexpected error in ${context}:`, error.message);
}
}
private scheduleRetry(context: string, error: any): void {
// Exponential backoff retry
const retryDelay = Math.min(1000 * Math.pow(2, error.retryCount || 0), 30000);
setTimeout(() => {
// Retry operation
}, retryDelay);
}
}
8.4 Testing Strategies
// Integration testing for different standards
describe('Healthcare Standards Integration', () => {
describe('HL7 v2.x', () => {
it('should parse ADT^A01 message correctly', () => {
const message = 'MSH|^~\\&|...';
const parsed = hl7Parser.parse(message);
expect(parsed.messageType).toBe('ADT^A01');
expect(parsed.segments.get('PID')).toBeDefined();
});
});
describe('FHIR R4', () => {
it('should validate Patient resource', async () => {
const patient = {
resourceType: 'Patient',
identifier: [{ system: 'test', value: '123' }]
};
const result = await fhirValidator.validate(patient);
expect(result.isValid).toBe(true);
});
});
});
8.5 Migration Path
flowchart LR
A[Current System<br/>Custom Format] --> B[Phase 1<br/>HL7 v2.x Internal]
B --> C[Phase 2<br/>FHIR Internal APIs]
C --> D[Phase 3<br/>FHIR External]
D --> E[Phase 4<br/>Full FHIR]
style A fill:#f9f,stroke:#333,stroke-width:2px
style E fill:#9f9,stroke:#333,stroke-width:2px
āļŠāļĢāļļāļ (Conclusion)
āļāļēāļĢāđāļĨāļ·āļāļāđāļāđāļĄāļēāļāļĢāļāļēāļāļāđāļāļĄāļđāļĨāļāļēāļāļāļēāļĢāđāļāļāļĒāđāļāļĩāđāđāļŦāļĄāļēāļ°āļŠāļĄāđāļāđāļāļāļąāļāļāļąāļĒāļŠāļģāļāļąāļāđāļāļāļ§āļēāļĄāļŠāļģāđāļĢāđāļāļāļāļāļĢāļ°āļāļ MediTech HIS:
āļāđāļāđāļāļ°āļāļģāļŠāļģāļŦāļĢāļąāļ MediTech:
- āđāļāđ FHIR R4 āđāļāđāļāļĄāļēāļāļĢāļāļēāļāļŦāļĨāļąāļāļŠāļģāļŦāļĢāļąāļ:
- External APIs
- Mobile Applications
- New integrations
-
Cloud services
-
āļāļ HL7 v2.x āļŠāļģāļŦāļĢāļąāļ:
- Legacy system integration
- Laboratory interfaces
-
Real-time messaging
-
āļŦāļĨāļĩāļāđāļĨāļĩāđāļĒāļ HL7 v3 āđāļ§āđāļāđāļāđ:
- āļĄāļĩāļāļ§āļēāļĄāļāļģāđāļāđāļāđāļāļāļēāļ°
-
āļāđāļāļāļāļēāļĢāđāļāđ CDA documents
-
Implement gradually:
- Start with internal systems
- Test thoroughly
- Monitor performance
- Scale progressively
āļāļēāļĢāđāļāđāļĄāļēāļāļĢāļāļēāļāļāļĩāđāļāļđāļāļāđāļāļāļāļ°āļāđāļ§āļĒāđāļŦāđ MediTech HIS āļŠāļēāļĄāļēāļĢāļ: - â āđāļĨāļāđāļāļĨāļĩāđāļĒāļāļāđāļāļĄāļđāļĨāđāļāđāļāļĒāđāļēāļāļĄāļĩāļāļĢāļ°āļŠāļīāļāļāļīāļ āļēāļ - â āļĨāļāļāđāļēāđāļāđāļāđāļēāļĒāđāļāļāļēāļĢāļāļđāļĢāļāļēāļāļēāļĢ - â āđāļāļīāđāļĄāļāļ§āļēāļĄāļāļĨāļāļāļ āļąāļĒāļāļāļāļāđāļāļĄāļđāļĨ - â āļĢāļāļāļĢāļąāļāļāļēāļĢāļāļĒāļēāļĒāļāļąāļ§āđāļāļāļāļēāļāļ - â āļŠāļāļāļāļĨāđāļāļāļāļąāļāļĄāļēāļāļĢāļāļēāļāļŠāļēāļāļĨ
References
- HL7 International: https://www.hl7.org/
- FHIR Documentation: https://www.hl7.org/fhir/
- DICOM Standard: https://www.dicomstandard.org/
- ICD-10: https://www.who.int/classifications/icd/
- LOINC: https://loinc.org/
- SNOMED CT: https://www.snomed.org/
Document Status: Complete
Last Updated: September 2, 2025
Next Review: March 2026