906 lines
24 KiB
Markdown
906 lines
24 KiB
Markdown
# SLA System Configuration Analysis
|
|
|
|
## Overview
|
|
|
|
This document explains how the Service Level Agreement (SLA) system is configured and works within the complaint management system.
|
|
|
|
---
|
|
|
|
## 1. SLA Configuration Models
|
|
|
|
### ComplaintSLAConfig Model
|
|
**File:** `apps/complaints/models.py`
|
|
|
|
The SLA configuration is stored in the `ComplaintSLAConfig` model, which allows flexible, hospital-specific SLA settings.
|
|
|
|
**Key Fields:**
|
|
- `hospital`: ForeignKey to Hospital (each hospital can have its own SLA rules)
|
|
- `severity`: Severity level (low, medium, high, critical)
|
|
- `priority`: Priority level (low, medium, high)
|
|
- `sla_hours`: Number of hours until SLA deadline (e.g., 24, 48, 72)
|
|
- `reminder_hours_before`: Hours before deadline to send first reminder (default: 24)
|
|
- `second_reminder_enabled`: Boolean to enable second reminder (default: false)
|
|
- `second_reminder_hours_before`: Hours before deadline for second reminder (default: 6)
|
|
- `thank_you_email_enabled`: Boolean to send thank you email on closure (default: false)
|
|
- `is_active`: Boolean to enable/disable the config
|
|
|
|
**Unique Constraint:**
|
|
- `unique_together`: hospital + severity + priority
|
|
- This means each hospital can have only one SLA config per severity/priority combination
|
|
|
|
**Example Configuration:**
|
|
```python
|
|
# Al-Hammadi Hospital - Medium Severity, Medium Priority
|
|
hospital_id: "uuid-123"
|
|
severity: "medium"
|
|
priority: "medium"
|
|
sla_hours: 48
|
|
reminder_hours_before: 24
|
|
second_reminder_enabled: true
|
|
second_reminder_hours_before: 6
|
|
```
|
|
|
|
---
|
|
|
|
## 2. SLA Calculation in Complaint Model
|
|
|
|
### How Due Date is Calculated
|
|
**File:** `apps/complaints/models.py` - `Complaint.calculate_sla_due_date()`
|
|
|
|
The SLA due date is calculated when a complaint is created:
|
|
|
|
```python
|
|
def calculate_sla_due_date(self):
|
|
"""
|
|
Calculate SLA due date based on severity and hospital configuration.
|
|
|
|
First tries to use ComplaintSLAConfig from database.
|
|
Falls back to settings.SLA_DEFAULTS if no config exists.
|
|
"""
|
|
# Try to get SLA config from database
|
|
try:
|
|
sla_config = ComplaintSLAConfig.objects.get(
|
|
hospital=self.hospital,
|
|
severity=self.severity,
|
|
priority=self.priority,
|
|
is_active=True
|
|
)
|
|
sla_hours = sla_config.sla_hours
|
|
except ComplaintSLAConfig.DoesNotExist:
|
|
# Fall back to settings
|
|
sla_hours = settings.SLA_DEFAULTS["complaint"].get(
|
|
self.severity,
|
|
settings.SLA_DEFAULTS["complaint"]["medium"]
|
|
)
|
|
|
|
return timezone.now() + timedelta(hours=sla_hours)
|
|
```
|
|
|
|
**Fallback Hierarchy:**
|
|
1. **Database Config** (ComplaintSLAConfig) - Checked first
|
|
2. **Settings Defaults** (settings.SLA_DEFAULTS) - Used if no database config exists
|
|
|
|
---
|
|
|
|
## 3. SLA Tracking Fields in Complaint Model
|
|
|
|
### Core SLA Fields
|
|
**File:** `apps/complaints/models.py`
|
|
|
|
```python
|
|
class Complaint(UUIDModel, TimeStampedModel):
|
|
# ... other fields ...
|
|
|
|
# SLA tracking
|
|
due_at = models.DateTimeField(db_index=True, help_text="SLA deadline")
|
|
is_overdue = models.BooleanField(default=False, db_index=True)
|
|
reminder_sent_at = models.DateTimeField(null=True, blank=True, help_text="First SLA reminder timestamp")
|
|
second_reminder_sent_at = models.DateTimeField(null=True, blank=True, help_text="Second SLA reminder timestamp")
|
|
escalated_at = models.DateTimeField(null=True, blank=True)
|
|
```
|
|
|
|
**Field Descriptions:**
|
|
- `due_at`: The calculated SLA deadline (e.g., 48 hours from creation)
|
|
- `is_overdue`: Boolean flag, automatically updated by periodic tasks
|
|
- `reminder_sent_at`: Timestamp when first reminder was sent
|
|
- `second_reminder_sent_at`: Timestamp when second reminder was sent (optional)
|
|
- `escalated_at`: Timestamp when complaint was escalated due to SLA breach
|
|
|
|
---
|
|
|
|
## 4. SLA Workflow
|
|
|
|
### Step-by-Step Process
|
|
|
|
#### 1. Complaint Creation
|
|
```
|
|
User submits complaint
|
|
↓
|
|
Complaint object created with default due_at
|
|
↓
|
|
Celery task triggered: analyze_complaint_with_ai
|
|
↓
|
|
AI analyzes severity and priority
|
|
↓
|
|
Complaint saved with new severity/priority
|
|
↓
|
|
SLA due_at recalculated based on new severity/priority
|
|
```
|
|
|
|
#### 2. SLA Reminder System
|
|
**Task:** `send_sla_reminders` (runs hourly via Celery Beat)
|
|
|
|
```
|
|
Every hour:
|
|
↓
|
|
Check active complaints (OPEN, IN_PROGRESS)
|
|
↓
|
|
For each complaint:
|
|
1. Get SLA config (severity + priority)
|
|
2. Calculate reminder_time = due_at - reminder_hours_before
|
|
3. If now >= reminder_time AND reminder_sent_at is NULL:
|
|
- Send reminder email to assignee/manager
|
|
- Set reminder_sent_at = now
|
|
- Create timeline entry
|
|
- Check reminder_escalation rules
|
|
|
|
4. If second_reminder_enabled AND now >= second_reminder_time:
|
|
- Send URGENT second reminder
|
|
- Set second_reminder_sent_at = now
|
|
- Trigger escalation check
|
|
```
|
|
|
|
#### 3. Overdue Detection
|
|
**Task:** `check_overdue_complaints` (runs every 15 minutes via Celery Beat)
|
|
|
|
```
|
|
Every 15 minutes:
|
|
↓
|
|
Check active complaints (not CLOSED, CANCELLED)
|
|
↓
|
|
For each complaint:
|
|
1. If now > due_at AND is_overdue is False:
|
|
- Set is_overdue = True
|
|
- Trigger automatic escalation
|
|
- Log warning
|
|
```
|
|
|
|
#### 4. Escalation System
|
|
**Task:** `escalate_complaint_auto` (triggered on overdue or reminder escalation)
|
|
|
|
```
|
|
Escalation triggered:
|
|
↓
|
|
Get current escalation level from metadata (default: 0)
|
|
↓
|
|
Find matching EscalationRule:
|
|
- hospital = complaint.hospital
|
|
- escalation_level = current_level + 1
|
|
- trigger_on_overdue = True
|
|
- severity_filter matches (or empty)
|
|
- priority_filter matches (or empty)
|
|
- hours_overdue >= trigger_hours_overdue
|
|
↓
|
|
Determine escalation target:
|
|
- department_manager
|
|
- hospital_admin
|
|
- px_admin
|
|
- ceo
|
|
- specific_user
|
|
↓
|
|
Reassign complaint to escalation target
|
|
↓
|
|
Update metadata: escalation_level + 1
|
|
↓
|
|
Set escalated_at = now
|
|
↓
|
|
Create timeline entry
|
|
↓
|
|
Send notifications
|
|
```
|
|
|
|
#### 5. Reminder-Based Escalation
|
|
**Task:** `escalate_after_reminder` (triggered after reminder)
|
|
|
|
```
|
|
After reminder sent:
|
|
↓
|
|
Check EscalationRule:
|
|
- reminder_escalation_enabled = True
|
|
- escalation_level = current_level + 1
|
|
- hours_since_reminder >= reminder_escalation_hours
|
|
↓
|
|
Trigger regular escalation task
|
|
↓
|
|
Add metadata: reminder_escalation = {...}
|
|
```
|
|
|
|
---
|
|
|
|
## 5. Escalation Configuration
|
|
|
|
### EscalationRule Model
|
|
**File:** `apps/complaints/models.py`
|
|
|
|
```python
|
|
class EscalationRule(UUIDModel, TimeStampedModel):
|
|
"""
|
|
Configurable escalation rules for complaints.
|
|
Supports multi-level escalation with configurable hierarchy.
|
|
"""
|
|
hospital = models.ForeignKey("organizations.Hospital", ...)
|
|
|
|
name = models.CharField(max_length=200)
|
|
description = models.TextField(blank=True)
|
|
|
|
# Escalation level (supports multi-level escalation)
|
|
escalation_level = models.IntegerField(default=1)
|
|
max_escalation_level = models.IntegerField(default=3)
|
|
|
|
# Trigger conditions
|
|
trigger_on_overdue = models.BooleanField(default=True)
|
|
trigger_hours_overdue = models.IntegerField(default=0)
|
|
|
|
# Reminder-based escalation
|
|
reminder_escalation_enabled = models.BooleanField(default=False)
|
|
reminder_escalation_hours = models.IntegerField(default=24)
|
|
|
|
# Escalation target
|
|
escalate_to_role = models.CharField(..., choices=[
|
|
("department_manager", "Department Manager"),
|
|
("hospital_admin", "Hospital Admin"),
|
|
("px_admin", "PX Admin"),
|
|
("ceo", "CEO"),
|
|
("specific_user", "Specific User"),
|
|
])
|
|
|
|
escalate_to_user = models.ForeignKey("accounts.User", ...) # For specific_user
|
|
|
|
# Conditions
|
|
severity_filter = models.CharField(...) # Optional: only escalate specific severity
|
|
priority_filter = models.CharField(...) # Optional: only escalate specific priority
|
|
|
|
order = models.IntegerField(default=0)
|
|
is_active = models.BooleanField(default=True)
|
|
```
|
|
|
|
**Multi-Level Escalation Example:**
|
|
|
|
```python
|
|
# Level 1: Escalate to Department Manager after 24 hours overdue
|
|
EscalationRule(
|
|
hospital=hospital,
|
|
name="Level 1: Department Manager",
|
|
escalation_level=1,
|
|
trigger_on_overdue=True,
|
|
trigger_hours_overdue=24,
|
|
escalate_to_role="department_manager"
|
|
)
|
|
|
|
# Level 2: Escalate to Hospital Admin after 48 hours overdue
|
|
EscalationRule(
|
|
hospital=hospital,
|
|
name="Level 2: Hospital Admin",
|
|
escalation_level=2,
|
|
trigger_on_overdue=True,
|
|
trigger_hours_overdue=48,
|
|
escalate_to_role="hospital_admin"
|
|
)
|
|
|
|
# Level 3: Escalate to PX Admin after 72 hours overdue
|
|
EscalationRule(
|
|
hospital=hospital,
|
|
name="Level 3: PX Admin",
|
|
escalation_level=3,
|
|
trigger_on_overdue=True,
|
|
trigger_hours_overdue=72,
|
|
escalate_to_role="px_admin"
|
|
)
|
|
```
|
|
|
|
---
|
|
|
|
## 6. Celery Beat Configuration
|
|
|
|
### Scheduled Tasks
|
|
**File:** `config/celery.py`
|
|
|
|
```python
|
|
app.conf.beat_schedule = {
|
|
# Check overdue complaints every 15 minutes
|
|
'check-overdue-complaints': {
|
|
'task': 'apps.complaints.tasks.check_overdue_complaints',
|
|
'schedule': 900.0, # 15 minutes in seconds
|
|
},
|
|
|
|
# Send SLA reminders every hour
|
|
'send-sla-reminders': {
|
|
'task': 'apps.complaints.tasks.send_sla_reminders',
|
|
'schedule': 3600.0, # 1 hour in seconds
|
|
},
|
|
|
|
# Check overdue explanation requests every 15 minutes
|
|
'check-overdue-explanation-requests': {
|
|
'task': 'apps.complaints.tasks.check_overdue_explanation_requests',
|
|
'schedule': 900.0,
|
|
},
|
|
|
|
# Send explanation reminders every hour
|
|
'send-explanation-reminders': {
|
|
'task': 'apps.complaints.tasks.send_explanation_reminders',
|
|
'schedule': 3600.0,
|
|
},
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 7. AI Integration with SLA
|
|
|
|
### Complaint Type Detection
|
|
**File:** `apps/core/ai_service.py` - `AIService._detect_complaint_type()`
|
|
|
|
```python
|
|
@classmethod
|
|
def _detect_complaint_type(cls, text: str) -> str:
|
|
"""
|
|
Detect if text is a complaint or appreciation using sentiment and keywords.
|
|
|
|
Returns: 'complaint' or 'appreciation'
|
|
"""
|
|
# Keywords for appreciation (English and Arabic)
|
|
appreciation_keywords_en = [
|
|
'thank', 'thanks', 'excellent', 'great', 'wonderful', ...
|
|
]
|
|
appreciation_keywords_ar = [
|
|
'شكرا', 'ممتاز', 'رائع', 'بارك', 'مدهش', ...
|
|
]
|
|
|
|
# Keywords for complaints
|
|
complaint_keywords_en = [
|
|
'problem', 'issue', 'complaint', 'bad', 'terrible', ...
|
|
]
|
|
complaint_keywords_ar = [
|
|
'مشكلة', 'مشاكل', 'سيء', 'مخيب', ...
|
|
]
|
|
|
|
# Count keyword matches
|
|
# Get sentiment analysis
|
|
# Determine complaint_type
|
|
|
|
return 'complaint' or 'appreciation'
|
|
```
|
|
|
|
### Impact on SLA
|
|
|
|
**For Complaints:**
|
|
- SLA tracking is enabled
|
|
- `due_at` is calculated based on severity/priority
|
|
- Reminders are sent before deadline
|
|
- Escalation triggered if overdue
|
|
- PX Action is automatically created
|
|
|
|
**For Appreciations:**
|
|
- SLA tracking is **SKIPPED**
|
|
- `due_at` can be None
|
|
- No reminders sent
|
|
- No escalation
|
|
- No PX Action created
|
|
- Timeline note: "Appreciation detected - No PX Action or SLA tracking required"
|
|
|
|
### AI Analysis Task
|
|
**File:** `apps/complaints/tasks.py` - `analyze_complaint_with_ai()`
|
|
|
|
```python
|
|
@shared_task
|
|
def analyze_complaint_with_ai(complaint_id):
|
|
"""
|
|
Analyze a complaint using AI to determine:
|
|
- Type (complaint vs appreciation)
|
|
- Severity
|
|
- Priority
|
|
- Category
|
|
- Department
|
|
- Staff mentions
|
|
- Emotion
|
|
"""
|
|
|
|
# Get AI analysis
|
|
analysis = AIService.analyze_complaint(...)
|
|
|
|
# Extract complaint_type
|
|
complaint_type = analysis.get('complaint_type', 'complaint')
|
|
|
|
# Update complaint
|
|
complaint.severity = analysis['severity']
|
|
complaint.priority = analysis['priority']
|
|
complaint.complaint_type = complaint_type
|
|
|
|
# Skip SLA for appreciations
|
|
is_appreciation = complaint_type == 'appreciation'
|
|
|
|
if not is_appreciation:
|
|
# Recalculate SLA due date based on new severity/priority
|
|
complaint.due_at = complaint.calculate_sla_due_date()
|
|
complaint.save(update_fields=['due_at'])
|
|
|
|
# Create PX Action (mandatory for complaints)
|
|
create_px_action(...)
|
|
else:
|
|
# Create timeline entry for appreciation
|
|
ComplaintUpdate.objects.create(
|
|
complaint=complaint,
|
|
update_type='note',
|
|
message="Appreciation detected - No PX Action or SLA tracking required"
|
|
)
|
|
```
|
|
|
|
---
|
|
|
|
## 8. Explanation SLA System
|
|
|
|
### ExplanationSLAConfig Model
|
|
**File:** `apps/complaints/models.py`
|
|
|
|
```python
|
|
class ExplanationSLAConfig(UUIDModel, TimeStampedModel):
|
|
"""
|
|
SLA configuration for staff explanation requests.
|
|
Defines time limits and escalation rules for staff to submit explanations.
|
|
"""
|
|
hospital = models.ForeignKey("organizations.Hospital", ...)
|
|
|
|
# Time limits
|
|
response_hours = models.IntegerField(default=48)
|
|
reminder_hours_before = models.IntegerField(default=12)
|
|
|
|
# Escalation settings
|
|
auto_escalate_enabled = models.BooleanField(default=True)
|
|
escalation_hours_overdue = models.IntegerField(default=0)
|
|
max_escalation_levels = models.IntegerField(default=3)
|
|
|
|
is_active = models.BooleanField(default=True)
|
|
```
|
|
|
|
### Explanation Request Workflow
|
|
|
|
```
|
|
Complaint filed against staff
|
|
↓
|
|
PX Admin requests explanation
|
|
↓
|
|
ComplaintExplanation created with token
|
|
↓
|
|
Send explanation request email to staff
|
|
↓
|
|
Set sla_due_at = now + response_hours (default: 48 hours)
|
|
↓
|
|
Staff receives email with unique link
|
|
↓
|
|
Staff submits explanation via link
|
|
↓
|
|
is_used = True, responded_at = now
|
|
```
|
|
|
|
### Explanation Overdue Workflow
|
|
|
|
```
|
|
Task: check_overdue_explanation_requests (every 15 minutes)
|
|
↓
|
|
Find unsubmitted explanations past due_at
|
|
↓
|
|
If auto_escalate_enabled:
|
|
- Check escalation level
|
|
- Find staff manager (report_to field)
|
|
- Create new explanation request for manager
|
|
- Link to original explanation (escalated_to_manager)
|
|
- Send email to manager
|
|
- Increment escalation_level
|
|
↓
|
|
Repeat until max_escalation_levels reached
|
|
```
|
|
|
|
---
|
|
|
|
## 9. Threshold-Based Actions
|
|
|
|
### ComplaintThreshold Model
|
|
**File:** `apps/complaints/models.py`
|
|
|
|
```python
|
|
class ComplaintThreshold(UUIDModel, TimeStampedModel):
|
|
"""
|
|
Configurable thresholds for complaint-related triggers.
|
|
Defines when to trigger actions based on metrics (e.g., survey scores).
|
|
"""
|
|
hospital = models.ForeignKey("organizations.Hospital", ...)
|
|
|
|
threshold_type = models.CharField(..., choices=[
|
|
("resolution_survey_score", "Resolution Survey Score"),
|
|
("response_time", "Response Time"),
|
|
("resolution_time", "Resolution Time"),
|
|
])
|
|
|
|
threshold_value = models.FloatField() # e.g., 50 for 50%
|
|
|
|
comparison_operator = models.CharField(..., choices=[
|
|
("lt", "Less Than"),
|
|
("lte", "Less Than or Equal"),
|
|
("gt", "Greater Than"),
|
|
("gte", "Greater Than or Equal"),
|
|
("eq", "Equal"),
|
|
])
|
|
|
|
action_type = models.CharField(..., choices=[
|
|
("create_px_action", "Create PX Action"),
|
|
("send_notification", "Send Notification"),
|
|
("escalate", "Escalate"),
|
|
])
|
|
|
|
is_active = models.BooleanField(default=True)
|
|
```
|
|
|
|
### Resolution Survey Threshold Check
|
|
|
|
```
|
|
Complaint closed
|
|
↓
|
|
Send resolution survey to patient
|
|
↓
|
|
Patient completes survey
|
|
↓
|
|
Task: check_resolution_survey_threshold
|
|
↓
|
|
Get threshold for hospital
|
|
↓
|
|
Check if survey.score breaches threshold
|
|
↓
|
|
If breached:
|
|
- Create PX Action
|
|
- Send notification
|
|
- Or escalate (based on action_type)
|
|
```
|
|
|
|
---
|
|
|
|
## 10. Notification System
|
|
|
|
### SLA Reminder Emails
|
|
**Templates:**
|
|
- `templates/complaints/emails/sla_reminder_en.txt`
|
|
- `templates/complaints/emails/sla_reminder_ar.txt`
|
|
- `templates/complaints/emails/sla_second_reminder_en.txt`
|
|
- `templates/complaints/emails/sla_second_reminder_ar.txt`
|
|
|
|
**Email Content:**
|
|
- Complaint reference number
|
|
- Complaint title
|
|
- Hours remaining until deadline
|
|
- Direct link to complaint
|
|
- Urgency level (normal vs URGENT for second reminder)
|
|
|
|
### NotificationService Integration
|
|
**File:** `apps/notifications/services.py`
|
|
|
|
```python
|
|
@shared_task
|
|
def send_complaint_notification(complaint_id, event_type):
|
|
"""
|
|
Send notification for complaint events.
|
|
|
|
event_types:
|
|
- created: Notify assignee/department manager
|
|
- assigned: Notify assignee
|
|
- overdue: Notify assignee and manager
|
|
- escalated: Notify assignee and manager
|
|
- resolved: Notify patient
|
|
- closed: Notify patient
|
|
"""
|
|
```
|
|
|
|
---
|
|
|
|
## 11. Configuration Hierarchy
|
|
|
|
### Priority Order for SLA Settings
|
|
|
|
1. **Database Configuration** (Highest Priority)
|
|
- ComplaintSLAConfig (per hospital, severity, priority)
|
|
- ExplanationSLAConfig (per hospital)
|
|
- EscalationRule (per hospital, with conditions)
|
|
|
|
2. **Settings Defaults** (Fallback)
|
|
- settings.SLA_DEFAULTS["complaint"][severity]
|
|
|
|
3. **Hardcoded Defaults** (Lowest Priority)
|
|
- Default hours: 48
|
|
- Default reminder: 24 hours before
|
|
- Default second reminder: 6 hours before
|
|
|
|
---
|
|
|
|
## 12. Key Features
|
|
|
|
### ✅ Configurable SLA
|
|
- Hospital-specific SLA settings
|
|
- Per-severity and per-priority configurations
|
|
- Multiple reminder levels
|
|
- Flexible escalation rules
|
|
|
|
### ✅ Automatic Escalation
|
|
- Multi-level escalation (up to 3+ levels)
|
|
- Role-based targets (manager, admin, CEO, etc.)
|
|
- Conditional escalation (severity, priority filters)
|
|
- Reminder-based escalation (no action after reminder)
|
|
|
|
### ✅ AI Integration
|
|
- Automatic severity/priority classification
|
|
- Complaint type detection (complaint vs appreciation)
|
|
- SLA skipping for appreciations
|
|
- Emotion detection for context
|
|
|
|
### ✅ Real-time Tracking
|
|
- Overdue detection every 15 minutes
|
|
- Reminder checks every hour
|
|
- Timeline updates for all SLA events
|
|
- Audit logging
|
|
|
|
### ✅ Staff Explanation System
|
|
- Token-based access
|
|
- SLA deadlines for responses
|
|
- Automatic escalation to managers
|
|
- Multi-level escalation up hierarchy
|
|
|
|
---
|
|
|
|
## 13. Example Scenarios
|
|
|
|
### Scenario 1: Standard Complaint with SLA Breach
|
|
|
|
```
|
|
1. Complaint created: "Wait time too long"
|
|
- AI analysis: severity=medium, priority=medium, complaint_type=complaint
|
|
- SLA config: 48 hours
|
|
- due_at = now + 48 hours
|
|
|
|
2. 24 hours before deadline:
|
|
- Reminder sent to assigned staff
|
|
- reminder_sent_at = now
|
|
|
|
3. 6 hours before deadline (if second_reminder_enabled):
|
|
- URGENT second reminder sent
|
|
- second_reminder_sent_at = now
|
|
|
|
4. Deadline passes (48 hours after creation):
|
|
- check_overdue_complaints runs
|
|
- is_overdue = True
|
|
- Trigger escalation
|
|
|
|
5. Escalation (Level 1):
|
|
- Reassign to department manager
|
|
- escalation_level = 1
|
|
- escalated_at = now
|
|
- Send notification
|
|
|
|
6. 24 hours after escalation (if still unresolved):
|
|
- Trigger Level 2 escalation to hospital admin
|
|
|
|
7. 48 hours after escalation (if still unresolved):
|
|
- Trigger Level 3 escalation to PX Admin
|
|
|
|
8. Maximum level reached:
|
|
- Stop escalation
|
|
- Log warning
|
|
```
|
|
|
|
### Scenario 2: Appreciation (No SLA)
|
|
|
|
```
|
|
1. Feedback received: "Dr. Ahmed was excellent! Thank you!"
|
|
- AI analysis: sentiment=positive, complaint_type=appreciation
|
|
|
|
2. SLA handling:
|
|
- Skip SLA calculation
|
|
- due_at = None
|
|
- No reminders sent
|
|
- No escalation
|
|
- No PX Action created
|
|
|
|
3. Timeline entry:
|
|
- "Appreciation detected - No PX Action or SLA tracking required"
|
|
|
|
4. Thank you email (if thank_you_email_enabled):
|
|
- Send to patient
|
|
- Express gratitude for feedback
|
|
```
|
|
|
|
### Scenario 3: Staff Explanation Request with Escalation
|
|
|
|
```
|
|
1. Complaint filed against Dr. Ahmed
|
|
- PX Admin requests explanation
|
|
- Explanation created with token
|
|
- Email sent to Dr. Ahmed
|
|
- sla_due_at = now + 48 hours
|
|
|
|
2. 12 hours before deadline:
|
|
- Reminder sent to Dr. Ahmed
|
|
|
|
3. 48 hours deadline passes (no response):
|
|
- Explanation marked as overdue
|
|
- auto_escalate_enabled = True
|
|
|
|
4. Escalation Level 1:
|
|
- Create new explanation for Dr. Ahmed's manager
|
|
- Link to original explanation
|
|
- Send email to manager
|
|
- escalation_level = 1
|
|
|
|
5. If manager doesn't respond in 48 hours:
|
|
- Escalate Level 2: Manager's manager
|
|
|
|
6. Continue until max_escalation_levels (default: 3)
|
|
```
|
|
|
|
---
|
|
|
|
## 14. Configuration Management
|
|
|
|
### Creating SLA Configurations
|
|
|
|
**Via Admin:**
|
|
```python
|
|
from apps.complaints.models import ComplaintSLAConfig
|
|
|
|
# Critical severity, high priority: 24 hours
|
|
ComplaintSLAConfig.objects.create(
|
|
hospital=hospital,
|
|
severity='critical',
|
|
priority='high',
|
|
sla_hours=24,
|
|
reminder_hours_before=12,
|
|
second_reminder_enabled=True,
|
|
second_reminder_hours_before=6,
|
|
is_active=True
|
|
)
|
|
|
|
# Medium severity, medium priority: 48 hours
|
|
ComplaintSLAConfig.objects.create(
|
|
hospital=hospital,
|
|
severity='medium',
|
|
priority='medium',
|
|
sla_hours=48,
|
|
reminder_hours_before=24,
|
|
second_reminder_enabled=True,
|
|
second_reminder_hours_before=6,
|
|
is_active=True
|
|
)
|
|
|
|
# Low severity, low priority: 72 hours
|
|
ComplaintSLAConfig.objects.create(
|
|
hospital=hospital,
|
|
severity='low',
|
|
priority='low',
|
|
sla_hours=72,
|
|
reminder_hours_before=48,
|
|
second_reminder_enabled=False,
|
|
is_active=True
|
|
)
|
|
```
|
|
|
|
### Creating Escalation Rules
|
|
|
|
```python
|
|
from apps.complaints.models import EscalationRule
|
|
|
|
# Level 1: Department Manager
|
|
EscalationRule.objects.create(
|
|
hospital=hospital,
|
|
name="Level 1: Department Manager",
|
|
escalation_level=1,
|
|
max_escalation_level=3,
|
|
trigger_on_overdue=True,
|
|
trigger_hours_overdue=24,
|
|
reminder_escalation_enabled=True,
|
|
reminder_escalation_hours=12,
|
|
escalate_to_role='department_manager',
|
|
severity_filter='', # All severities
|
|
priority_filter='', # All priorities
|
|
order=1,
|
|
is_active=True
|
|
)
|
|
|
|
# Level 2: Hospital Admin
|
|
EscalationRule.objects.create(
|
|
hospital=hospital,
|
|
name="Level 2: Hospital Admin",
|
|
escalation_level=2,
|
|
max_escalation_level=3,
|
|
trigger_on_overdue=True,
|
|
trigger_hours_overdue=48,
|
|
escalate_to_role='hospital_admin',
|
|
order=2,
|
|
is_active=True
|
|
)
|
|
|
|
# Level 3: PX Admin
|
|
EscalationRule.objects.create(
|
|
hospital=hospital,
|
|
name="Level 3: PX Admin",
|
|
escalation_level=3,
|
|
max_escalation_level=3,
|
|
trigger_on_overdue=True,
|
|
trigger_hours_overdue=72,
|
|
escalate_to_role='px_admin',
|
|
order=3,
|
|
is_active=True
|
|
)
|
|
```
|
|
|
|
---
|
|
|
|
## 15. Troubleshooting
|
|
|
|
### SLA Not Calculating
|
|
**Check:**
|
|
1. Does ComplaintSLAConfig exist for hospital+severity+priority?
|
|
2. Is the config `is_active=True`?
|
|
3. Is `settings.SLA_DEFAULTS` defined?
|
|
|
|
### Reminders Not Sending
|
|
**Check:**
|
|
1. Is Celery Beat running?
|
|
2. Is `send_sla_reminders` in beat schedule?
|
|
3. Is complaint status OPEN or IN_PROGRESS?
|
|
4. Is `reminder_sent_at` NULL?
|
|
|
|
### Escalation Not Triggering
|
|
**Check:**
|
|
1. Is EscalationRule configured?
|
|
2. Is rule `is_active=True`?
|
|
3. Does severity/priority match filters?
|
|
4. Has `trigger_hours_overdue` elapsed?
|
|
5. Has escalation level reached max?
|
|
|
|
### AI Not Classifying Correctly
|
|
**Check:**
|
|
1. Is AI service configured (API key)?
|
|
2. Is Celery worker running?
|
|
3. Check logs for AI errors
|
|
4. Verify complaint description quality
|
|
|
|
---
|
|
|
|
## 16. Best Practices
|
|
|
|
### SLA Configuration
|
|
1. **Set realistic deadlines** based on complexity
|
|
2. **Enable second reminders** for high-priority items
|
|
3. **Configure multi-level escalation** for critical issues
|
|
4. **Regularly review** SLA performance metrics
|
|
|
|
### Escalation Rules
|
|
1. **Start with department managers** (Level 1)
|
|
2. **Escalate to admin** for persistent issues (Level 2)
|
|
3. **Final escalation** to CXO/PX Admin (Level 3)
|
|
4. **Set appropriate time gaps** between levels (24-48 hours)
|
|
|
|
### Monitoring
|
|
1. **Monitor overdue rates** monthly
|
|
2. **Track escalation frequency** per department
|
|
3. **Review AI classification accuracy**
|
|
4. **Analyze response times** by severity/priority
|
|
|
|
---
|
|
|
|
## Summary
|
|
|
|
The SLA system is designed to be:
|
|
- **Flexible**: Hospital-specific, severity-based, priority-driven
|
|
- **Automated**: Minimal manual intervention required
|
|
- **Intelligent**: AI-powered classification and escalation
|
|
- **Transparent**: Clear timeline and audit logs
|
|
- **Configurable**: Easy to adjust SLA settings via admin or code
|
|
|
|
The system ensures complaints are addressed within appropriate timeframes, with automatic escalation when deadlines are missed, while intelligently handling appreciations differently to focus resources on actual complaints.
|