242 lines
8.4 KiB
Markdown
242 lines
8.4 KiB
Markdown
# Multi-Hospital Simulator Support Implementation
|
|
|
|
## Overview
|
|
Enhanced HIS (Hospital Information System) Simulator to support dynamic multi-hospital support by querying hospital codes from the Hospital model. This enables realistic testing scenarios across different hospital branches without hardcoded configuration.
|
|
|
|
## Changes Made
|
|
|
|
### 1. Updated Serializer (`apps/simulator/serializers.py`)
|
|
- Kept `hospital_code` field in `HISJourneyEventSerializer` (max_length=50)
|
|
- Removed `branch` field to simplify schema
|
|
|
|
### 2. Enhanced HIS Simulator (`apps/simulator/his_simulator.py`)
|
|
|
|
#### Added Django Setup
|
|
```python
|
|
import os
|
|
import django
|
|
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'PX360.settings')
|
|
django.setup()
|
|
|
|
from apps.organizations.models import Hospital
|
|
```
|
|
|
|
#### Added Dynamic Hospital Querying
|
|
```python
|
|
def get_active_hospital_codes() -> List[str]:
|
|
"""Query active hospitals from the database and return their codes"""
|
|
try:
|
|
hospital_codes = list(
|
|
Hospital.objects.filter(status='active').values_list('code', flat=True)
|
|
)
|
|
if not hospital_codes:
|
|
# Fallback to default if no active hospitals found
|
|
print("⚠️ Warning: No active hospitals found, using default ALH-main")
|
|
return ["ALH-main"]
|
|
return hospital_codes
|
|
except Exception as e:
|
|
print(f"⚠️ Error querying hospitals: {e}, using default ALH-main")
|
|
return ["ALH-main"]
|
|
```
|
|
|
|
#### Removed Hardcoded Lists
|
|
- **Removed** `BRANCHES` constant list
|
|
- **Removed** `HOSPITAL_CODES` constant list
|
|
|
|
#### Updated Event Generation
|
|
- Each patient journey now dynamically queries active hospitals from the database
|
|
- Randomly selects a hospital code from available active hospitals
|
|
- Hospital code is included in every event generated
|
|
- Removed `branch` field from events (only `hospital_code` remains)
|
|
|
|
#### Enhanced Journey Summary Display
|
|
- Added hospital code display to `print_journey_summary()` function
|
|
- Example output:
|
|
```
|
|
✅ 🚑 Patient Journey Created
|
|
Patient: Ahmed Al-Saud
|
|
Encounter ID: ENC-2026-12345
|
|
Hospital: ALH-north
|
|
Type: EMS - Full Journey
|
|
Stages: 4/4 completed
|
|
API Status: Success
|
|
```
|
|
|
|
#### Added Hospital Statistics Tracking
|
|
- Added `hospital_distribution` dictionary to statistics
|
|
- Tracks number of journeys per hospital
|
|
- Displays hospital distribution in `print_statistics()` function
|
|
- Example output:
|
|
```
|
|
🏥 Hospital Distribution:
|
|
ALH-east: 2 (40.0%)
|
|
ALH-north: 3 (60.0%)
|
|
```
|
|
|
|
### 3. Updated API View (`apps/simulator/views.py`)
|
|
|
|
#### Modified Hospital Lookup
|
|
Dynamic lookup based on hospital_code from event data:
|
|
|
|
```python
|
|
# Get hospital from event data or default to ALH-main
|
|
hospital_code = event_data.get('hospital_code', 'ALH-main')
|
|
hospital = Hospital.objects.filter(code=hospital_code).first()
|
|
if not hospital:
|
|
raise ValueError(f"Hospital with code '{hospital_code}' not found. Please run seed_journey_surveys command first.")
|
|
```
|
|
|
|
#### Updated API Documentation
|
|
- Removed `branch` field from API payload example
|
|
- Only `hospital_code` field is required for hospital identification
|
|
|
|
## Benefits
|
|
|
|
### Dynamic vs. Hardcoded
|
|
1. **Dynamic Hospital Discovery**: Automatically uses all active hospitals in the system
|
|
2. **No Code Changes Required**: Adding new hospitals doesn't require code updates
|
|
3. **Consistent Data**: Uses actual Hospital model data, no duplication
|
|
4. **Cleaner Schema**: Single `hospital_code` field instead of duplicate `branch`
|
|
5. **Realistic Testing**: Reflects actual hospital configuration
|
|
|
|
### Multi-Hospital Support
|
|
1. **Realistic Multi-Hospital Testing**: Simulate patient journeys across multiple hospital branches
|
|
2. **Hospital-Specific Reporting**: Track statistics and metrics per hospital
|
|
3. **Backward Compatible**: Falls back to ALH-main if no hospital_code is provided
|
|
4. **Scalable**: Easy to add more hospitals in the system
|
|
5. **Better Data Distribution**: Random hospital assignment provides balanced testing
|
|
|
|
## Usage
|
|
|
|
### Prerequisites
|
|
Before running the simulator, ensure you have active hospitals in the database:
|
|
|
|
```bash
|
|
# Check existing hospitals
|
|
python manage.py shell
|
|
>>> from apps.organizations.models import Hospital
|
|
>>> Hospital.objects.filter(status='active').values_list('code', flat=True)
|
|
['ALH-main', 'ALH-north', 'ALH-south', 'ALH-east', 'ALH-west']
|
|
```
|
|
|
|
### Run Simulator with Hospital Support
|
|
```bash
|
|
# Run 5 patients with 2-second delay
|
|
python apps/simulator/his_simulator.py --max-patients 5 --delay 2
|
|
|
|
# Run continuously with 5-second delay
|
|
python apps/simulator/his_simulator.py --delay 5
|
|
|
|
# Specify custom API URL
|
|
python apps/simulator/his_simulator.py --url http://localhost:8000/api/simulator/his-events/
|
|
```
|
|
|
|
### API Payload Example
|
|
```json
|
|
{
|
|
"events": [
|
|
{
|
|
"encounter_id": "ENC-2026-12345",
|
|
"mrn": "MRN-54321",
|
|
"national_id": "1234567890",
|
|
"first_name": "Ahmed",
|
|
"last_name": "Al-Saud",
|
|
"phone": "+966501234567",
|
|
"email": "patient@example.com",
|
|
"event_type": "OPD_STAGE_1_REGISTRATION",
|
|
"timestamp": "2024-01-20T10:30:00Z",
|
|
"visit_type": "opd",
|
|
"department": "Cardiology",
|
|
"hospital_code": "ALH-north"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
**Note**: Only `hospital_code` is required. The `branch` field has been removed from the schema.
|
|
|
|
## Testing Results
|
|
|
|
### Test Run: 5 Patients
|
|
```
|
|
Patient 1: Nasser Al-Zahrani - ALH-north - EMS (Partial, 1/4 stages)
|
|
Patient 2: Nora Al-Shammari - ALH-north - INPATIENT (Full, 6/6 stages)
|
|
Patient 3: Khalid Al-Anazi - ALH-east - EMS (Full, 4/4 stages)
|
|
Patient 4: Mona Al-Bakr - ALH-east - EMS (Partial, 2/4 stages)
|
|
Patient 5: Abdulwahab Al-Saud - ALH-north - EMS (Full, 4/4 stages)
|
|
```
|
|
|
|
### Hospital Distribution
|
|
- ALH-north: 3 patients (60%)
|
|
- ALH-east: 2 patients (40%)
|
|
|
|
### API Responses
|
|
All 5 patient journeys processed successfully with hospital codes properly assigned.
|
|
|
|
## Future Enhancements
|
|
|
|
Potential improvements:
|
|
1. Add command-line option to specify specific hospital codes to use
|
|
2. Add hospital-specific journey templates and surveys
|
|
3. Add hospital-specific email/SMS templates
|
|
4. Create multi-hospital dashboards and reports
|
|
5. Add hospital hierarchy support (regional, national levels)
|
|
6. Add hospital-specific SLA configurations
|
|
7. Support for hospital grouping and aggregation
|
|
|
|
## Dependencies
|
|
|
|
- No new external dependencies required
|
|
- Uses Django ORM to query Hospital model from `apps.organizations.models`
|
|
- Compatible with existing journey and survey infrastructure
|
|
- Requires Django settings to be properly configured
|
|
|
|
## Files Modified
|
|
|
|
1. `apps/simulator/serializers.py` - Removed branch field, kept hospital_code
|
|
2. `apps/simulator/his_simulator.py` - Added dynamic hospital querying
|
|
3. `apps/simulator/views.py` - Updated API documentation, removed branch reference
|
|
|
|
## Testing Checklist
|
|
|
|
- [x] Simulator queries hospitals dynamically from database
|
|
- [x] API accepts hospital_code in events
|
|
- [x] Hospital codes are displayed in journey summaries
|
|
- [x] Hospital statistics are tracked and displayed
|
|
- [x] Multiple hospitals can be used in simulation
|
|
- [x] Backward compatibility maintained (defaults to ALH-main)
|
|
- [x] Surveys are sent for completed journeys across hospitals
|
|
- [x] Fallback mechanism works when no active hospitals found
|
|
- [x] Removed duplicate `branch` field from schema
|
|
|
|
## Troubleshooting
|
|
|
|
### Issue: "No active hospitals found"
|
|
**Solution**: Ensure you have active hospitals in the database
|
|
```bash
|
|
python manage.py shell
|
|
>>> from apps.organizations.models import Hospital
|
|
>>> Hospital.objects.all().count() # Check total hospitals
|
|
>>> Hospital.objects.filter(status='active').count() # Check active hospitals
|
|
```
|
|
|
|
### Issue: "Hospital with code 'XXX' not found"
|
|
**Solution**: Run the seed_journey_surveys command to create hospitals
|
|
```bash
|
|
python manage.py seed_journey_surveys
|
|
```
|
|
|
|
### Issue: Simulator uses only ALH-main
|
|
**Solution**: Verify hospital status is set to 'active'
|
|
```bash
|
|
python manage.py shell
|
|
>>> from apps.organizations.models import Hospital
|
|
>>> hospital = Hospital.objects.get(code='ALH-north')
|
|
>>> hospital.status = 'active'
|
|
>>> hospital.save()
|
|
```
|
|
|
|
## Conclusion
|
|
|
|
The multi-hospital simulator support has been successfully enhanced with dynamic hospital querying from the Hospital model. The system now supports realistic testing scenarios across multiple hospital branches without requiring code changes when new hospitals are added. The implementation maintains backward compatibility while providing a cleaner, more maintainable architecture.
|