# 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.