HH/docs/HIS_SIMULATOR_COMPLETE.md
2026-01-24 15:27:30 +03:00

495 lines
14 KiB
Markdown

# HIS Simulator - Complete Implementation Guide
## Overview
The HIS (Hospital Information System) Simulator is a comprehensive tool for testing the patient journey tracking system. It simulates real-world patient events from a hospital system and automatically triggers survey invitations when patients complete their journeys.
## What Was Implemented
### 1. HIS Events API Endpoint
**Location:** `apps/simulator/views.py` - `HISEventsAPIView`
A public API endpoint that receives patient journey events from external HIS systems:
- **URL:** `/api/simulator/his-events/`
- **Method:** POST
- **Authentication:** None (public for simulator testing)
- **Request Format:** JSON array of events
### 2. HIS Simulator Script
**Location:** `apps/simulator/his_simulator.py`
A continuous event generator that simulates patient journeys:
- Generates realistic patient data (Saudi names, national IDs, phone numbers)
- Creates complete patient journeys (registration → discharge)
- Sends events to the API endpoint
- Configurable delay and patient count
### 3. Journey & Survey Seeding
**Location:** `apps/simulator/management/commands/seed_journey_surveys.py`
Management command that creates journey templates and surveys:
- EMS journey (4 stages)
- Inpatient journey (6 stages)
- OPD journey (5 stages)
- Survey templates with questions for each journey type
### 4. Event Processing Logic
When events are received:
1. Creates or finds patient records
2. Creates journey instance for new encounters
3. Completes stages based on event type
4. When journey is complete → creates survey instance
5. Sends survey invitation via email and SMS
## How It Works
### Event Flow
```
HIS System → API Endpoint → Event Processing → Journey Tracking → Survey Creation → Notification Delivery
```
### Supported Event Types
#### EMS Events
- `EMS_ARRIVAL` - Patient arrives at emergency
- `EMS_TRIAGE` - Triage completed
- `EMS_TREATMENT` - Treatment completed
- `EMS_DISCHARGE` - Patient discharged
#### Inpatient Events
- `INPATIENT_ADMISSION` - Patient admitted
- `INPATIENT_TREATMENT` - Treatment completed
- `INPATIENT_MONITORING` - Monitoring phase
- `INPATIENT_MEDICATION` - Medication administered
- `INPATIENT_LAB` - Lab tests completed
- `INPATIENT_DISCHARGE` - Patient discharged
#### OPD Events
- `OPD_STAGE_1_REGISTRATION` - Registration completed
- `OPD_STAGE_2_CONSULTATION` - Consultation completed
- `OPD_STAGE_3_LAB` - Lab tests completed
- `OPD_STAGE_4_RADIOLOGY` - Radiology completed
- `OPD_STAGE_5_PHARMACY` - Pharmacy/dispensing completed
## Quick Start
### 1. Seed Journey Templates and Surveys
```bash
cd /home/ismail/projects/HH
uv run python manage.py seed_journey_surveys
```
This creates:
- 3 journey templates (EMS, Inpatient, OPD)
- 3 survey templates with questions
- 18 survey questions total
### 2. Start Django Server
```bash
uv run python manage.py runserver
```
### 3. Run the Simulator
#### Option A: Using the Python Script (Continuous Mode)
```bash
# Simulate 5 patients with 2 seconds between events
uv run python apps/simulator/his_simulator.py --delay 2 --max-patients 5
# Continuous mode (unlimited patients, 1 second between events)
uv run python apps/simulator/his_simulator.py --delay 1 --max-patients 0
```
#### Option B: Using cURL (Single Request)
```bash
curl -X POST http://localhost:8000/api/simulator/his-events/ \
-H "Content-Type: application/json" \
-d '{
"events": [
{
"encounter_id": "TEST-001",
"mrn": "MRN-TEST-001",
"national_id": "1234567890",
"first_name": "Test",
"last_name": "Patient",
"phone": "+966501234567",
"email": "test@example.com",
"event_type": "OPD_STAGE_1_REGISTRATION",
"timestamp": "2026-01-20T10:30:00Z",
"visit_type": "opd",
"department": "Cardiology",
"branch": "Main"
},
{
"encounter_id": "TEST-001",
"mrn": "MRN-TEST-001",
"national_id": "1234567890",
"first_name": "Test",
"last_name": "Patient",
"phone": "+966501234567",
"email": "test@example.com",
"event_type": "OPD_STAGE_2_CONSULTATION",
"timestamp": "2026-01-20T11:00:00Z",
"visit_type": "opd",
"department": "Cardiology",
"branch": "Main"
}
]
}'
```
### 4. Verify Results
Check the Django logs for:
- Patient creation: `Created patient MRN-XXX: Full Name`
- Journey creation: `Created new journey instance XXX with N stages`
- Stage completion: `Completed stage StageName for journey ENC-XXX`
- Survey creation: `Created survey instance XXX for journey ENC-XXX`
- Email sent: `Survey invitation sent via email to email@example.com`
- SMS sent: `Survey invitation sent via SMS to +966XXXXXXXXX`
## API Specification
### POST /api/simulator/his-events/
**Request Body:**
```json
{
"events": [
{
"encounter_id": "string (required) - Unique encounter ID from HIS",
"mrn": "string (required) - Medical Record Number",
"national_id": "string (required) - Patient national ID",
"first_name": "string (required) - Patient first name",
"last_name": "string (required) - Patient last name",
"phone": "string (required) - Patient phone number",
"email": "string (required) - Patient email address",
"event_type": "string (required) - Event code (see supported events above)",
"timestamp": "string (required) - ISO 8601 timestamp",
"visit_type": "string (required) - Journey type: ems, inpatient, or opd",
"department": "string (optional) - Department name",
"branch": "string (optional) - Hospital branch",
"physician_name": "string (optional) - Physician name"
}
]
}
```
**Success Response:**
```json
{
"success": true,
"message": "Processed 5 events successfully",
"results": [
{
"encounter_id": "TEST-001",
"patient_id": "uuid",
"journey_id": "uuid",
"stage_id": "uuid",
"stage_status": "completed",
"survey_sent": false
}
],
"surveys_sent": 1,
"survey_details": [
{
"encounter_id": "TEST-001",
"survey_id": "uuid",
"survey_url": "/surveys/XXXXX/"
}
]
}
```
## Testing Scenarios
### Scenario 1: Complete OPD Journey
Test a full OPD patient journey that triggers a survey:
```bash
curl -X POST http://localhost:8000/api/simulator/his-events/ \
-H "Content-Type: application/json" \
-d '{
"events": [
{
"encounter_id": "OPD-TEST-001",
"mrn": "OPD-MRN-001",
"national_id": "1234567891",
"first_name": "Ahmed",
"last_name": "Al-Rashid",
"phone": "+966501234568",
"email": "ahmed@example.com",
"event_type": "OPD_STAGE_1_REGISTRATION",
"timestamp": "2026-01-20T10:00:00Z",
"visit_type": "opd",
"department": "Cardiology",
"branch": "Main"
},
{
"encounter_id": "OPD-TEST-001",
"mrn": "OPD-MRN-001",
"national_id": "1234567891",
"first_name": "Ahmed",
"last_name": "Al-Rashid",
"phone": "+966501234568",
"email": "ahmed@example.com",
"event_type": "OPD_STAGE_2_CONSULTATION",
"timestamp": "2026-01-20T11:00:00Z",
"visit_type": "opd",
"department": "Cardiology",
"branch": "Main"
},
{
"encounter_id": "OPD-TEST-001",
"mrn": "OPD-MRN-001",
"national_id": "1234567891",
"first_name": "Ahmed",
"last_name": "Al-Rashid",
"phone": "+966501234568",
"email": "ahmed@example.com",
"event_type": "OPD_STAGE_3_LAB",
"timestamp": "2026-01-20T12:00:00Z",
"visit_type": "opd",
"department": "Cardiology",
"branch": "Main"
},
{
"encounter_id": "OPD-TEST-001",
"mrn": "OPD-MRN-001",
"national_id": "1234567891",
"first_name": "Ahmed",
"last_name": "Al-Rashid",
"phone": "+966501234568",
"email": "ahmed@example.com",
"event_type": "OPD_STAGE_4_RADIOLOGY",
"timestamp": "2026-01-20T13:00:00Z",
"visit_type": "opd",
"department": "Cardiology",
"branch": "Main"
},
{
"encounter_id": "OPD-TEST-001",
"mrn": "OPD-MRN-001",
"national_id": "1234567891",
"first_name": "Ahmed",
"last_name": "Al-Rashid",
"phone": "+966501234568",
"email": "ahmed@example.com",
"event_type": "OPD_STAGE_5_PHARMACY",
"timestamp": "2026-01-20T14:00:00Z",
"visit_type": "opd",
"department": "Cardiology",
"branch": "Main"
}
]
}'
```
**Expected Result:**
- Patient created
- Journey instance created with 5 stages
- All 5 stages completed
- Survey instance created
- Survey invitation sent via email and SMS
### Scenario 2: Partial Journey
Test a partial journey that doesn't trigger a survey:
```bash
curl -X POST http://localhost:8000/api/simulator/his-events/ \
-H "Content-Type: application/json" \
-d '{
"events": [
{
"encounter_id": "PARTIAL-001",
"mrn": "PARTIAL-MRN-001",
"national_id": "1234567892",
"first_name": "Sara",
"last_name": "Al-Otaibi",
"phone": "+966501234569",
"email": "sara@example.com",
"event_type": "OPD_STAGE_1_REGISTRATION",
"timestamp": "2026-01-20T10:00:00Z",
"visit_type": "opd",
"department": "Cardiology",
"branch": "Main"
}
]
}'
```
**Expected Result:**
- Patient created
- Journey instance created with 5 stages
- Only 1 stage completed
- No survey created (journey incomplete)
## Database Verification
### Check Journey Instances
```python
from apps.journeys.models import PatientJourneyInstance, StageStatus
# Get all journeys
journeys = PatientJourneyInstance.objects.all()
for j in journeys:
print(f"{j.encounter_id}: {j.status} - {j.get_completion_percentage()}% complete")
# Check a specific journey
ji = PatientJourneyInstance.objects.get(encounter_id='OPD-TEST-001')
print(f"Status: {ji.status}")
print(f"Complete: {ji.is_complete()}")
print(f"Stages: {ji.stage_instances.filter(status=StageStatus.COMPLETED).count()}/{ji.stage_instances.count()}")
```
### Check Survey Instances
```python
from apps.surveys.models import SurveyInstance
from apps.journeys.models import PatientJourneyInstance
# Get all surveys
surveys = SurveyInstance.objects.all()
for s in surveys:
print(f"Survey: {s.id} - Journey: {s.journey_instance.encounter_id}")
print(f"URL: {s.get_survey_url()}")
print(f"Status: {s.status}")
# Get survey for a specific journey
ji = PatientJourneyInstance.objects.get(encounter_id='OPD-TEST-001')
si = SurveyInstance.objects.filter(journey_instance=ji).first()
if si:
print(f"Survey URL: {si.get_survey_url()}")
```
## Monitoring and Debugging
### Django Logs
Watch for these log messages:
**Patient Creation:**
```
Created patient MRN-XXX: Full Name
```
**Journey Creation:**
```
Created new journey instance XXX with N stages
```
**Stage Completion:**
```
Completed stage StageName for journey ENC-XXX
```
**Survey Creation:**
```
Created survey instance XXX for journey ENC-XXX
```
**Email Sending:**
```
[Email Simulator] Email sent successfully to email@example.com
Survey invitation sent via email to email@example.com
```
**SMS Sending:**
```
[SMS Simulator] SMS sent to +966XXXXXXXXX
Survey invitation sent via SMS to +966XXXXXXXXX
```
### Common Issues
#### Issue: "Journey template not found for visit_type"
**Solution:** Run the seed command: `uv run python manage.py seed_journey_surveys`
#### Issue: Survey not created after completing journey
**Solution:** Check that the journey template has `send_post_discharge_survey = True`
#### Issue: Email/SMS not sent
**Solution:** Check that the NotificationService is configured and the simulator endpoints are accessible
## Architecture
### Components
1. **HIS Events API** (`apps/simulator/views.py`)
- Receives events from external systems
- Validates event data
- Processes events sequentially
- Returns detailed response
2. **Event Processor** (`apps/simulator/views.py` - `process_his_event()`)
- Creates/updates patients
- Creates/updates journeys
- Completes stages
- Triggers surveys
3. **HIS Simulator Script** (`apps/simulator/his_simulator.py`)
- Generates patient data
- Creates event sequences
- Sends events to API
- Logs results
4. **Survey Notification Service** (`apps/integrations/services.py`)
- Sends email invitations
- Sends SMS invitations
- Tracks delivery status
### Data Flow
```
HIS System
HIS Events API
Event Processor
Patient Manager (create/find patient)
Journey Manager (create/find journey)
Stage Manager (complete stage)
Survey Manager (create survey if journey complete)
Notification Service (send email & SMS)
```
## Future Enhancements
Potential improvements to the simulator:
1. **Real-time Event Stream:** WebSocket support for live event streaming
2. **Event Replay:** Ability to replay historical events for testing
3. **Error Handling:** Better error recovery and retry logic
4. **Metrics Dashboard:** Real-time metrics on event processing
5. **Batch Processing:** Support for large batch imports
6. **Event Validation:** More robust event data validation
7. **Custom Event Types:** Support for custom journey templates
## Summary
The HIS Simulator provides a complete testing environment for:
✅ Patient journey tracking
✅ Stage completion automation
✅ Survey triggering on journey completion
✅ Email and SMS notifications
✅ Real-time event processing
✅ Database verification
The system is production-ready for integration testing and can be easily extended for real HIS system integration.