HH/EXPLANATION_REQUEST_WORKFLOW_IMPLEMENTATION.md

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