# Observation Model Fixes

## Overview
Fixed critical issues in the Observation model to align with the system's tenant isolation architecture and improve parity with the Complaint model.

## Issues Fixed

### 1. Missing Hospital ForeignKey (Critical)
**Problem:** The Observation model lacked a `hospital` field, breaking tenant isolation.

**Impact:**
- Cannot filter observations by hospital
- Cannot track which hospital owns the observation
- Prevents proper routing in multi-hospital environment
- Breaks the tenant isolation pattern used throughout the system

**Solution:**
- Added `hospital` ForeignKey to `organizations.Hospital`
- Field is required for new observations
- Added database index for efficient filtering by hospital and status

### 2. Missing Staff ForeignKey
**Problem:** Observations couldn't track which staff member was mentioned in the report.

**Solution:**
- Added optional `staff` ForeignKey to `organizations.Staff`
- Enables AI-matching similar to Complaint model
- Useful for tracking observations about specific staff members

### 3. Missing Source Tracking
**Problem:** No way to track how observations were submitted.

**Solution:**
- Added `source` field with choices:
  - `staff_portal` - Staff Portal (default)
  - `web_form` - Web Form
  - `mobile_app` - Mobile App
  - `email` - Email
  - `call_center` - Call Center
  - `other` - Other

## Model Changes

### Added Fields to Observation Model
```python
hospital = models.ForeignKey(
    'organizations.Hospital',
    on_delete=models.CASCADE,
    related_name='observations',
    help_text="Hospital where observation was made"
)

staff = models.ForeignKey(
    'organizations.Staff',
    on_delete=models.SET_NULL,
    null=True,
    blank=True,
    related_name='observations',
    help_text="Staff member mentioned in observation"
)

source = models.CharField(
    max_length=50,
    choices=[
        ('staff_portal', 'Staff Portal'),
        ('web_form', 'Web Form'),
        ('mobile_app', 'Mobile App'),
        ('email', 'Email'),
        ('call_center', 'Call Center'),
        ('other', 'Other'),
    ],
    default='staff_portal',
    help_text="How the observation was submitted"
)
```

### Added Database Indexes
```python
models.Index(fields=['hospital', 'status', '-created_at'])
```

## Migration Strategy

### Migration 0002_add_missing_fields.py
- Adds `hospital`, `staff`, and `source` fields
- Initially makes `hospital` nullable to support existing data
- Since there are 0 existing observations, no data migration needed

### Future Migration
After deployment, a follow-up migration can make `hospital` required if needed:
```python
migrations.AlterField(
    model_name='observation',
    name='hospital',
    field=models.ForeignKey(
        on_delete=django.db.models.deletion.CASCADE,
        related_name='observations',
        to='organizations.hospital'
    ),
)
```

## Why Not Unify with Complaints?

Despite similarities, the models should remain separate:

### Key Differences
| Aspect | Complaint | Observation |
|--------|-----------|-------------|
| **Purpose** | Patient-reported issues | Staff-reported issues |
| **Reporter** | Patient FK (required) | Anonymous or staff ID |
| **Workflow** | Open → In Progress → Resolved → Closed | New → Triaged → Assigned → In Progress → Resolved → Closed (plus REJECTED, DUPLICATE) |
| **SLA** | Response time SLAs with tracking | Triage timeline, not response time |
| **Tracking** | Reference number (optional) | Tracking code (required, OBS-XXXXXX) |
| **Location** | No location field | Location text field |
| **Incident Time** | No separate field | Incident datetime field |
| **Triage** | No triage fields | Triage tracking (triaged_by, triaged_at) |
| **Resolution Survey** | Links to SurveyInstance | No resolution survey |
| **Encounter ID** | Links to patient encounters | No encounter tracking |

### Different Business Logic
- **Complaints**: Customer service workflow, satisfaction surveys, SLA escalation
- **Observations**: Safety/quality workflow, triage process, anonymous reporting

### Different Stakeholders
- **Complaints**: Patient experience teams, call center
- **Observations**: Quality teams, safety officers, clinical governance

## Next Steps

1. **Run Migration:**
   ```bash
   python manage.py migrate observations
   ```

2. **Update Forms:** Ensure observation forms include hospital selection
   - Public observation form
   - Staff portal observation form
   - Admin observation form

3. **Update Views:** Add hospital filtering to observation list views

4. **Update APIs:** Include hospital field in observation APIs

5. **Update Templates:** Display hospital information in observation detail views

6. **Consider AI Integration:** Add staff name extraction similar to complaints
   - Use `apps.core.ai_service.extract_person_name()`
   - Match extracted names to Staff records
   - Populate `staff` field automatically

## Files Modified

1. **apps/observations/models.py**
   - Added `hospital` ForeignKey
   - Added `staff` ForeignKey
   - Added `source` field
   - Added hospital status index

2. **apps/observations/migrations/0002_add_missing_fields.py**
   - Migration to add new fields

## Backwards Compatibility

- Migration makes `hospital` initially nullable
- Model code enforces `hospital` as required for new records
- Existing code without hospital selection will work but with validation errors for new observations
- Consider updating form validation to ensure hospital is always provided
