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