239 lines
8.1 KiB
Markdown
239 lines
8.1 KiB
Markdown
# Explanation Request Workflow Implementation
|
|
|
|
## Overview
|
|
Modified the explanation request system with the following workflow:
|
|
1. **Initial Request**: Link sent to staff, informational notification to manager
|
|
2. **Escalation**: If staff doesn't respond within SLA, manager gets a link to respond
|
|
3. **Manager Response**: Manager can submit their perspective when escalated
|
|
|
|
## Workflow Diagram
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────────────┐
|
|
│ EXPLANATION REQUEST FLOW │
|
|
└─────────────────────────────────────────────────────────────────────┘
|
|
|
|
INITIAL REQUEST
|
|
│
|
|
├──► Staff receives: Link to submit explanation
|
|
│ (can respond immediately)
|
|
│
|
|
└──► Manager receives: Informational email only
|
|
(no link - just notification)
|
|
│
|
|
│
|
|
┌──────────────┴──────────────┐
|
|
│ │
|
|
[Staff responds] [No response]
|
|
│ │
|
|
▼ ▼
|
|
Explanation saved After SLA deadline
|
|
System notifies (e.g., 48 hours)
|
|
assigned user │
|
|
▼
|
|
ESCALATION TRIGGERED
|
|
│
|
|
▼
|
|
Manager receives:
|
|
Link to submit explanation
|
|
as escalation response
|
|
│
|
|
▼
|
|
[Manager responds]
|
|
│
|
|
▼
|
|
Manager explanation saved
|
|
Linked to staff explanation
|
|
```
|
|
|
|
## Changes Made
|
|
|
|
### 1. Backend API (`apps/complaints/views.py`)
|
|
|
|
#### `request_explanation` method
|
|
**Behavior:**
|
|
- Creates ONE explanation record (for staff only)
|
|
- Sends link to staff member
|
|
- Sends informational email to manager (no link, no token)
|
|
|
|
**Staff Email:**
|
|
- Subject: "Explanation Request - Complaint #..."
|
|
- Contains: Link to submit explanation
|
|
- SLA deadline applies
|
|
|
|
**Manager Email:**
|
|
- Subject: "Staff Explanation Request Notification - Complaint #..."
|
|
- Contains: Complaint details for awareness
|
|
- States: "If no response is received within the SLA deadline, you will receive a follow-up request with a link to provide your perspective as the manager."
|
|
- NO link/token included
|
|
|
|
**API Response:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"results": [
|
|
{
|
|
"recipient_type": "staff",
|
|
"recipient": "Dr. Ahmed Smith",
|
|
"sent": true,
|
|
"explanation_id": "..."
|
|
},
|
|
{
|
|
"recipient_type": "manager",
|
|
"recipient": "Dr. Sarah Johnson",
|
|
"sent": true,
|
|
"informational_only": true,
|
|
"note": "Manager will receive link if staff does not respond within SLA"
|
|
}
|
|
],
|
|
"staff_explanation_id": "...",
|
|
"manager_notified": true
|
|
}
|
|
```
|
|
|
|
#### `resend_explanation` method
|
|
**Behavior:**
|
|
- Only resends to staff member (regenerates token)
|
|
- Manager informational email is NOT resent (they already received it)
|
|
|
|
### 2. Celery Tasks (`apps/complaints/tasks.py`)
|
|
|
|
#### `check_overdue_explanation_requests` task
|
|
**Behavior:**
|
|
- Runs every 15 minutes
|
|
- Finds staff explanations that are overdue (past SLA deadline)
|
|
- Creates NEW explanation record for manager with:
|
|
- Unique token/link
|
|
- Fresh SLA deadline
|
|
- Escalation metadata
|
|
- Sends email to manager with link
|
|
|
|
**Manager Escalation Email:**
|
|
- Subject: "Explanation Request: Complaint #..."
|
|
- Contains: Link to submit explanation
|
|
- Message: "ESCALATED: [Staff Name] did not provide an explanation within the SLA deadline..."
|
|
|
|
**Escalation Linkage:**
|
|
```python
|
|
staff_explanation.escalated_to_manager = manager_explanation
|
|
staff_explanation.escalated_at = now
|
|
```
|
|
|
|
### 3. UI Template (`templates/complaints/complaint_detail.html`)
|
|
|
|
**Before Request:**
|
|
- Shows staff as primary recipient (with link)
|
|
- Shows manager as "Notification Only"
|
|
- Note: "Will receive link only if staff doesn't respond within SLA"
|
|
|
|
**After Request:**
|
|
- Shows staff explanation status
|
|
- Shows manager escalation status (when applicable)
|
|
- Distinguishes between:
|
|
- "Explanation from Staff" / "Pending Staff Explanation"
|
|
- "Explanation from Manager (Escalated)" / "Pending Manager Explanation"
|
|
|
|
## Data Model
|
|
|
|
### Staff Explanation Record
|
|
```python
|
|
{
|
|
"id": "uuid",
|
|
"staff": staff_id,
|
|
"token": "secure_token_for_staff",
|
|
"is_used": false/true,
|
|
"sla_due_at": "2026-02-12T10:00:00Z",
|
|
"escalated_to_manager": null or manager_explanation_id,
|
|
"escalated_at": null or timestamp,
|
|
"metadata": {
|
|
"escalation_level": 0 // Staff is level 0
|
|
}
|
|
}
|
|
```
|
|
|
|
### Manager Explanation Record (Created on Escalation)
|
|
```python
|
|
{
|
|
"id": "uuid",
|
|
"staff": manager_id, // The manager
|
|
"token": "secure_token_for_manager",
|
|
"is_used": false/true,
|
|
"sla_due_at": "2026-02-14T10:00:00Z", // Fresh SLA
|
|
"escalated_to_manager": null, // Manager can also escalate up
|
|
"metadata": {
|
|
"escalated_from_explanation_id": "staff_explanation_id",
|
|
"escalation_level": 1,
|
|
"original_staff_id": "staff_id",
|
|
"original_staff_name": "Staff Name",
|
|
"is_escalation": True
|
|
}
|
|
}
|
|
```
|
|
|
|
## API Endpoints
|
|
|
|
### `POST /api/complaints/{id}/request_explanation/`
|
|
Send initial explanation request to staff + informational notification to manager.
|
|
|
|
### `POST /api/complaints/{id}/resend_explanation/`
|
|
Resend explanation request to staff only (new token).
|
|
|
|
### `GET /complaints/{complaint_id}/explain/{token}/`
|
|
Public form for submitting explanation (works for both staff and manager tokens).
|
|
|
|
## Escalation Hierarchy
|
|
|
|
```
|
|
Level 0: Staff (initial request with link)
|
|
↓ (if no response within SLA)
|
|
Level 1: Manager (receives link via escalation)
|
|
↓ (if no response within SLA)
|
|
Level 2: Manager's Manager (receives link via escalation)
|
|
↓
|
|
Level 3+: Continue up hierarchy...
|
|
```
|
|
|
|
## Benefits of This Approach
|
|
|
|
1. **Staff Priority**: Staff gets first chance to respond with direct link
|
|
2. **Manager Awareness**: Manager is informed immediately but not burdened with link
|
|
3. **Clear Escalation Path**: Manager only gets involved if staff doesn't respond
|
|
4. **Audit Trail**: Clear record of escalation from staff to manager
|
|
5. **Fresh SLA**: Manager gets their own SLA deadline when escalated
|
|
6. **Parallel Visibility**: Both explanations visible in complaint detail
|
|
|
|
## Testing Scenarios
|
|
|
|
### Scenario 1: Staff Responds Immediately
|
|
1. Request explanation → Staff gets link, Manager gets notification
|
|
2. Staff clicks link and submits explanation
|
|
3. System shows "Explanation from Staff" as submitted
|
|
4. Manager escalation never triggered
|
|
|
|
### Scenario 2: Staff Doesn't Respond
|
|
1. Request explanation → Staff gets link, Manager gets notification
|
|
2. Staff doesn't respond within SLA (e.g., 48 hours)
|
|
3. Escalation task runs → Manager gets link
|
|
4. Manager submits explanation
|
|
5. System shows:
|
|
- Staff: "Pending Explanation (Overdue)"
|
|
- Manager: "Explanation from Manager (Escalated)"
|
|
|
|
### Scenario 3: No Manager Assigned
|
|
1. Request explanation → Only staff gets email
|
|
2. System shows warning "No manager assigned"
|
|
3. If staff doesn't respond, no escalation possible
|
|
|
|
## Files Modified
|
|
|
|
1. `apps/complaints/views.py` - `request_explanation` and `resend_explanation` methods
|
|
2. `apps/complaints/tasks.py` - `check_overdue_explanation_requests` task
|
|
3. `templates/complaints/complaint_detail.html` - UI updates
|
|
|
|
## Backward Compatibility
|
|
|
|
- Existing staff explanations work as before
|
|
- Manager escalation creates new explanation record
|
|
- No database migrations required
|
|
- API endpoints remain at same URLs
|