372 lines
11 KiB
JavaScript
372 lines
11 KiB
JavaScript
/**
|
|
* @fileoverview Healthcare data mocking utilities for Laravel Healthcare MCP Server tests
|
|
* Provides HIPAA-compliant mock data and validation utilities for healthcare testing
|
|
*/
|
|
|
|
import { jest } from '@jest/globals';
|
|
|
|
/**
|
|
* Healthcare Data Mock Manager for handling healthcare-specific mock data
|
|
*/
|
|
export class HealthcareDataMockManager {
|
|
constructor() {
|
|
this.patientData = new Map();
|
|
this.providerData = new Map();
|
|
this.prescriptionData = new Map();
|
|
this.appointmentData = new Map();
|
|
this.medicalRecords = new Map();
|
|
}
|
|
|
|
/**
|
|
* Generate comprehensive mock patient data
|
|
* @param {Object} overrides - Optional field overrides
|
|
* @returns {Object} Mock patient data
|
|
*/
|
|
generateMockPatient(overrides = {}) {
|
|
const basePatient = {
|
|
id: `patient_${Date.now()}_${Math.random().toString(36).substring(2)}`,
|
|
firstName: 'John',
|
|
lastName: 'Doe',
|
|
email: 'john.doe@test.example.com',
|
|
dateOfBirth: '1990-01-01',
|
|
genderIdentity: 'Male',
|
|
preferredPhone: '555-0123',
|
|
address: '123 Test St',
|
|
city: 'Test City',
|
|
state: 'TS',
|
|
zipcode: '12345',
|
|
status: 'active',
|
|
isPortalAccess: true,
|
|
emergencyContact: {
|
|
name: 'Jane Doe',
|
|
relationship: 'Spouse',
|
|
phone: '555-0124'
|
|
},
|
|
insurance: {
|
|
provider: 'Test Insurance',
|
|
policyNumber: 'TEST123456',
|
|
groupNumber: 'GRP789'
|
|
},
|
|
medicalHistory: {
|
|
allergies: ['Penicillin'],
|
|
conditions: ['Hypertension'],
|
|
medications: ['Lisinopril 10mg']
|
|
},
|
|
hipaaConsent: {
|
|
signed: true,
|
|
signedDate: '2025-01-01',
|
|
version: '1.0'
|
|
},
|
|
createdAt: new Date().toISOString(),
|
|
updatedAt: new Date().toISOString()
|
|
};
|
|
|
|
return { ...basePatient, ...overrides };
|
|
}
|
|
|
|
/**
|
|
* Generate comprehensive mock provider data
|
|
* @param {Object} overrides - Optional field overrides
|
|
* @returns {Object} Mock provider data
|
|
*/
|
|
generateMockProvider(overrides = {}) {
|
|
const baseProvider = {
|
|
id: `provider_${Date.now()}_${Math.random().toString(36).substring(2)}`,
|
|
firstName: 'Dr. Jane',
|
|
lastName: 'Smith',
|
|
emailAddress: 'dr.smith@test.example.com',
|
|
textMessageNumber: '555-0456',
|
|
username: 'drsmith',
|
|
company_name: 'Test Medical Center',
|
|
npiNumber: '1234567890',
|
|
licenseNumber: 'MD123456',
|
|
specialty: 'Internal Medicine',
|
|
accessRights: {
|
|
admin: true,
|
|
practitioner: true,
|
|
patientPortal: false
|
|
},
|
|
credentials: {
|
|
degree: 'MD',
|
|
boardCertifications: ['Internal Medicine'],
|
|
yearsExperience: 10
|
|
},
|
|
workSchedule: {
|
|
monday: { start: '09:00', end: '17:00' },
|
|
tuesday: { start: '09:00', end: '17:00' },
|
|
wednesday: { start: '09:00', end: '17:00' },
|
|
thursday: { start: '09:00', end: '17:00' },
|
|
friday: { start: '09:00', end: '17:00' }
|
|
},
|
|
hipaaTraining: {
|
|
completed: true,
|
|
completedDate: '2025-01-01',
|
|
expirationDate: '2026-01-01'
|
|
},
|
|
createdAt: new Date().toISOString(),
|
|
updatedAt: new Date().toISOString()
|
|
};
|
|
|
|
return { ...baseProvider, ...overrides };
|
|
}
|
|
|
|
/**
|
|
* Generate comprehensive mock prescription data
|
|
* @param {Object} overrides - Optional field overrides
|
|
* @returns {Object} Mock prescription data
|
|
*/
|
|
generateMockPrescription(overrides = {}) {
|
|
const basePrescription = {
|
|
id: `prescription_${Date.now()}_${Math.random().toString(36).substring(2)}`,
|
|
patientId: 'test-patient-123',
|
|
providerId: 'test-provider-456',
|
|
medication: {
|
|
name: 'Lisinopril',
|
|
genericName: 'Lisinopril',
|
|
strength: '10mg',
|
|
form: 'Tablet'
|
|
},
|
|
dosage: '10mg',
|
|
frequency: 'Once daily',
|
|
duration: '30 days',
|
|
quantity: 30,
|
|
refills: 2,
|
|
instructions: 'Take with food',
|
|
status: 'active',
|
|
prescribedDate: new Date().toISOString(),
|
|
startDate: new Date().toISOString(),
|
|
endDate: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString(),
|
|
pharmacy: {
|
|
name: 'Test Pharmacy',
|
|
phone: '555-0789',
|
|
address: '456 Pharmacy St'
|
|
},
|
|
interactions: [],
|
|
contraindications: [],
|
|
sideEffects: ['Dizziness', 'Dry cough'],
|
|
createdAt: new Date().toISOString(),
|
|
updatedAt: new Date().toISOString()
|
|
};
|
|
|
|
return { ...basePrescription, ...overrides };
|
|
}
|
|
|
|
/**
|
|
* Generate comprehensive mock appointment data
|
|
* @param {Object} overrides - Optional field overrides
|
|
* @returns {Object} Mock appointment data
|
|
*/
|
|
generateMockAppointment(overrides = {}) {
|
|
const baseAppointment = {
|
|
id: `appointment_${Date.now()}_${Math.random().toString(36).substring(2)}`,
|
|
patientId: 'test-patient-123',
|
|
providerId: 'test-provider-456',
|
|
date: '2025-07-15',
|
|
time: '10:00',
|
|
duration: 30,
|
|
type: 'consultation',
|
|
status: 'scheduled',
|
|
reason: 'Annual checkup',
|
|
notes: 'Patient reports feeling well',
|
|
location: {
|
|
room: 'Room 101',
|
|
building: 'Main Building',
|
|
address: '123 Medical Center Dr'
|
|
},
|
|
reminders: {
|
|
email: true,
|
|
sms: true,
|
|
sentAt: null
|
|
},
|
|
telehealth: {
|
|
enabled: false,
|
|
platform: null,
|
|
meetingId: null
|
|
},
|
|
billing: {
|
|
cptCodes: ['99213'],
|
|
estimatedCost: 150.00,
|
|
insuranceCovered: true
|
|
},
|
|
createdAt: new Date().toISOString(),
|
|
updatedAt: new Date().toISOString()
|
|
};
|
|
|
|
return { ...baseAppointment, ...overrides };
|
|
}
|
|
|
|
/**
|
|
* Generate mock medical record data
|
|
* @param {Object} overrides - Optional field overrides
|
|
* @returns {Object} Mock medical record data
|
|
*/
|
|
generateMockMedicalRecord(overrides = {}) {
|
|
const baseRecord = {
|
|
id: `record_${Date.now()}_${Math.random().toString(36).substring(2)}`,
|
|
patientId: 'test-patient-123',
|
|
providerId: 'test-provider-456',
|
|
appointmentId: 'test-appointment-101',
|
|
type: 'progress_note',
|
|
date: new Date().toISOString(),
|
|
chiefComplaint: 'Annual physical examination',
|
|
historyOfPresentIllness: 'Patient reports feeling well with no acute concerns',
|
|
physicalExam: {
|
|
vitals: {
|
|
bloodPressure: '120/80',
|
|
heartRate: 72,
|
|
temperature: 98.6,
|
|
weight: 150,
|
|
height: 68
|
|
},
|
|
general: 'Well-appearing, no acute distress',
|
|
cardiovascular: 'Regular rate and rhythm, no murmurs',
|
|
respiratory: 'Clear to auscultation bilaterally',
|
|
neurological: 'Alert and oriented x3'
|
|
},
|
|
assessment: 'Healthy adult, no acute issues',
|
|
plan: 'Continue current medications, return in 1 year',
|
|
medications: ['Lisinopril 10mg daily'],
|
|
allergies: ['Penicillin'],
|
|
diagnosis: {
|
|
primary: 'Z00.00 - Encounter for general adult medical examination',
|
|
secondary: []
|
|
},
|
|
labResults: [],
|
|
imagingResults: [],
|
|
followUp: {
|
|
required: true,
|
|
timeframe: '1 year',
|
|
provider: 'same'
|
|
},
|
|
hipaaAccess: {
|
|
accessedBy: ['test-provider-456'],
|
|
accessLog: [
|
|
{
|
|
userId: 'test-provider-456',
|
|
action: 'view',
|
|
timestamp: new Date().toISOString()
|
|
}
|
|
]
|
|
},
|
|
createdAt: new Date().toISOString(),
|
|
updatedAt: new Date().toISOString()
|
|
};
|
|
|
|
return { ...baseRecord, ...overrides };
|
|
}
|
|
|
|
/**
|
|
* Create HIPAA-compliant mock data with proper access controls
|
|
* @param {string} dataType - Type of data to create
|
|
* @param {string} userRole - Role of the accessing user
|
|
* @param {Object} overrides - Optional field overrides
|
|
* @returns {Object} HIPAA-compliant mock data
|
|
*/
|
|
createHIPAACompliantData(dataType, userRole, overrides = {}) {
|
|
let data;
|
|
|
|
switch (dataType) {
|
|
case 'patient':
|
|
data = this.generateMockPatient(overrides);
|
|
break;
|
|
case 'provider':
|
|
data = this.generateMockProvider(overrides);
|
|
break;
|
|
case 'prescription':
|
|
data = this.generateMockPrescription(overrides);
|
|
break;
|
|
case 'appointment':
|
|
data = this.generateMockAppointment(overrides);
|
|
break;
|
|
case 'medical_record':
|
|
data = this.generateMockMedicalRecord(overrides);
|
|
break;
|
|
default:
|
|
throw new Error(`Unknown data type: ${dataType}`);
|
|
}
|
|
|
|
// Add HIPAA compliance metadata
|
|
data.hipaaMetadata = {
|
|
accessLevel: this.getAccessLevel(userRole),
|
|
encryptionStatus: 'encrypted',
|
|
auditTrail: {
|
|
created: new Date().toISOString(),
|
|
createdBy: `mock_${userRole}_user`,
|
|
lastAccessed: new Date().toISOString(),
|
|
accessCount: 1
|
|
},
|
|
dataClassification: 'PHI', // Protected Health Information
|
|
retentionPolicy: {
|
|
retainUntil: new Date(Date.now() + 7 * 365 * 24 * 60 * 60 * 1000).toISOString(), // 7 years
|
|
autoDelete: true
|
|
}
|
|
};
|
|
|
|
return data;
|
|
}
|
|
|
|
/**
|
|
* Get access level based on user role
|
|
* @param {string} userRole - User role
|
|
* @returns {string} Access level
|
|
*/
|
|
getAccessLevel(userRole) {
|
|
const accessLevels = {
|
|
provider: 'full',
|
|
patient: 'own_data_only',
|
|
partner: 'business_data_only',
|
|
affiliate: 'limited',
|
|
network: 'network_data_only'
|
|
};
|
|
|
|
return accessLevels[userRole] || 'none';
|
|
}
|
|
|
|
/**
|
|
* Validate HIPAA compliance for mock data
|
|
* @param {Object} data - Data to validate
|
|
* @param {string} userRole - User role requesting access
|
|
* @returns {Object} Validation result
|
|
*/
|
|
validateHIPAACompliance(data, userRole) {
|
|
const validation = {
|
|
isCompliant: true,
|
|
violations: [],
|
|
warnings: []
|
|
};
|
|
|
|
// Check if data has HIPAA metadata
|
|
if (!data.hipaaMetadata) {
|
|
validation.isCompliant = false;
|
|
validation.violations.push('Missing HIPAA metadata');
|
|
}
|
|
|
|
// Check access level
|
|
const requiredAccessLevel = this.getAccessLevel(userRole);
|
|
if (data.hipaaMetadata && data.hipaaMetadata.accessLevel !== requiredAccessLevel) {
|
|
validation.warnings.push(`Access level mismatch: expected ${requiredAccessLevel}, got ${data.hipaaMetadata.accessLevel}`);
|
|
}
|
|
|
|
// Check for PHI in logs
|
|
if (data.hipaaMetadata && data.hipaaMetadata.dataClassification === 'PHI') {
|
|
validation.warnings.push('PHI data detected - ensure proper handling');
|
|
}
|
|
|
|
return validation;
|
|
}
|
|
|
|
/**
|
|
* Reset all healthcare data mocks
|
|
*/
|
|
reset() {
|
|
this.patientData.clear();
|
|
this.providerData.clear();
|
|
this.prescriptionData.clear();
|
|
this.appointmentData.clear();
|
|
this.medicalRecords.clear();
|
|
}
|
|
}
|
|
|
|
// Export singleton instance
|
|
export const healthcareDataMockManager = new HealthcareDataMockManager();
|