emr-types
Version:
Comprehensive TypeScript Types Library for Electronic Medical Record (EMR) Applications - Domain-Driven Design with Zod Validation
144 lines • 4.79 kB
JavaScript
// ============================================================================
// PATIENT DOMAIN EXPORTS
// ============================================================================
// Entities
export * from './entities/Patient';
// Value Objects
export * from './value-objects/PatientId';
// Enums
export * from './enums/PatientStatus';
// Events
export * from './events/PatientDomainEvent';
export { PatientStatus, PatientStatusCategories, PatientStatusPriority, PatientStatusDescriptions, PatientStatusUtils, isPatientStatus, isStatusInCategory, DEFAULT_PATIENT_STATUS, PATIENT_STATUS_TRANSITIONS, PatientStatusExamples } from './enums/PatientStatus';
// ============================================================================
// DOMAIN-SPECIFIC UTILITIES
// ============================================================================
/**
* Patient domain utilities for common operations
*/
export const PatientDomainUtils = {
/**
* Calculate patient age from date of birth
*/
calculateAge(dateOfBirth) {
const today = new Date();
let age = today.getFullYear() - dateOfBirth.getFullYear();
const monthDiff = today.getMonth() - dateOfBirth.getMonth();
if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < dateOfBirth.getDate())) {
age--;
}
return age;
},
/**
* Calculate BMI from height and weight
*/
calculateBMI(height, weight) {
if (height <= 0 || weight <= 0)
return 0;
const heightInMeters = height / 100;
return weight / (heightInMeters * heightInMeters);
},
/**
* Get BMI category
*/
getBMICategory(bmi) {
if (bmi < 18.5)
return 'Underweight';
if (bmi < 25)
return 'Normal weight';
if (bmi < 30)
return 'Overweight';
return 'Obese';
},
/**
* Format patient name
*/
formatPatientName(firstName, lastName, middleName) {
const parts = [firstName];
if (middleName)
parts.push(middleName);
parts.push(lastName);
return parts.join(' ');
},
/**
* Generate patient code
*/
generatePatientCode(tenantId, sequence) {
const tenantPrefix = tenantId.substring(0, 3).toUpperCase();
const paddedSequence = sequence.toString().padStart(6, '0');
return `${tenantPrefix}${paddedSequence}`;
},
/**
* Validate patient data
*/
validatePatientData(patient) {
const errors = [];
if (!patient.firstName?.trim()) {
errors.push('First name is required');
}
if (!patient.lastName?.trim()) {
errors.push('Last name is required');
}
if (!patient.dateOfBirth) {
errors.push('Date of birth is required');
}
else if (patient.dateOfBirth > new Date()) {
errors.push('Date of birth cannot be in the future');
}
if (patient.email && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(patient.email)) {
errors.push('Invalid email format');
}
if (patient.phoneNumber && !/^\+?[\d\s\-\(\)]+$/.test(patient.phoneNumber)) {
errors.push('Invalid phone number format');
}
return {
isValid: errors.length === 0,
errors
};
}
};
// ============================================================================
// TYPE GUARDS
// ============================================================================
/**
* Type guard to check if a value is a Patient entity
*/
export function isPatient(value) {
return (typeof value === 'object' &&
value !== null &&
'id' in value &&
'tenantId' in value &&
'firstName' in value &&
'lastName' in value &&
'dateOfBirth' in value);
}
/**
* Type guard to check if a value is a PatientProfile
*/
export function isPatientProfile(value) {
return (typeof value === 'object' &&
value !== null &&
'patientId' in value &&
'language' in value &&
'smokingStatus' in value &&
'alcoholConsumption' in value &&
'exerciseFrequency' in value);
}
/**
* Type guard to check if a value is a MedicalHistory
*/
export function isMedicalHistory(value) {
return (typeof value === 'object' &&
value !== null &&
'patientId' in value &&
'familyHistory' in value &&
'pastMedicalConditions' in value &&
'currentSymptoms' in value &&
'vitalSigns' in value &&
'medicationHistory' in value &&
'immunizations' in value &&
'labResults' in value &&
'imagingResults' in value &&
'socialHistory' in value);
}
//# sourceMappingURL=index.js.map