Spaces:
Sleeping
Sleeping
File size: 6,786 Bytes
101c6eb 061cea4 101c6eb 061cea4 101c6eb be71f67 101c6eb |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 |
# Ticket Actions System - Implementation Summary
## What Was Built
A dynamic ticket action system that calculates available actions based on ticket state, user assignment, and journey progress. The backend determines what buttons to show, and the frontend simply renders them.
## Files Created
1. **`src/app/services/ticket_action_service.py`**
- Core service that calculates available actions
- Method: `get_available_actions(ticket, current_user, db)`
- Returns: actions, current_assignment, team_info, message
2. **`supabase/migrations/20251128112603_rename_unassigned_to_completed.sql`**
- Renames enum value `unassigned` β `completed`
- Better semantic meaning for completed assignments
3. **`docs/agent/frontend/TICKET_ACTIONS_SYSTEM.md`**
- Complete frontend integration guide
- Action flow states
- Example implementation
## Files Modified
1. **`src/app/models/enums.py`**
- Changed `UNASSIGNED = "unassigned"` β `COMPLETED = "completed"`
2. **`src/app/services/ticket_assignment_service.py`**
- Added `AssignmentAction` import
- Updated `complete_assignment()` to set `action = COMPLETED`
- Updated `drop_assignment()` to:
- Set `action = DROPPED`
- Set ticket status to `PENDING_REVIEW`
- Drop all team members if team ticket
- Added `drop_type` parameter
- Updated `self_assign_ticket()` to:
- Set `action = ACCEPTED` (auto-accepted)
- Set `responded_at` timestamp
3. **`src/app/schemas/ticket_assignment.py`**
- Added `drop_type` field to `AssignmentDrop` schema
4. **`src/app/api/v1/tickets.py`**
- Updated `GET /tickets/{ticket_id}/detail` endpoint
- Added `TicketActionService` import
- Added to response: `available_actions`, `current_assignment`, `team_info`, `message`
## Key Business Rules
### Assignment Action States
- `assigned` - Dispatcher assigned, agent hasn't responded
- `accepted` - Agent accepted assignment
- `rejected` - Agent rejected assignment
- `dropped` - Agent dropped mid-work
- `reassigned` - Dispatcher reassigned to different agent
- `completed` - Work finished
### Ticket Status Flow
1. `open` - Available for pickup
2. `assigned` - Agent(s) assigned
3. `in_progress` - Agent started journey
4. `pending_review` - Agent dropped, awaiting PM/dispatcher action
5. `completed` - Work finished
6. `cancelled` - Ticket cancelled
### Drop Behavior
- Agent drops β assignment action = `dropped`
- Ticket status β `pending_review`
- If team ticket β ALL team members dropped
- PM/dispatcher reviews and decides: reopen, cancel, or reschedule
### Team Tickets
- `required_team_size` defines how many agents needed
- Multiple agents can pick until full
- ANY team member can complete
- Completing closes ALL team assignments
- Dropping closes ALL team assignments
### Self-Assignment
- Agent picks ticket β auto-accepted (no accept/reject step)
- Creates assignment with `action = accepted`, `responded_at = now()`
- Agent can immediately start journey
## Action Flow
```
NO ASSIGNMENT (ticket open)
β [pick]
ACCEPTED (auto-accepted for self-assign)
β [start_journey]
IN_TRANSIT (journey started)
β [record_arrival]
ON_SITE (arrived at location)
β [complete]
COMPLETED
At any point after ACCEPTED:
β [drop]
DROPPED (pending_review)
```
## API Endpoints Used
### For Field Agents
- `GET /api/v1/tickets/{ticket_id}/detail` - Get ticket with available actions
- `POST /api/v1/ticket-assignments/tickets/{ticket_id}/self-assign` - Pick ticket
- `POST /api/v1/ticket-assignments/assignments/{assignment_id}/accept` - Accept assignment
- `POST /api/v1/ticket-assignments/assignments/{assignment_id}/reject` - Reject assignment
- `POST /api/v1/ticket-assignments/assignments/{assignment_id}/start-journey` - Start journey
- `POST /api/v1/ticket-assignments/assignments/{assignment_id}/arrived` - Record arrival
- `POST /api/v1/ticket-assignments/assignments/{assignment_id}/complete` - Complete work
- `POST /api/v1/ticket-assignments/assignments/{assignment_id}/drop` - Drop ticket
### For PM/Dispatcher
- `POST /api/v1/ticket-assignments/tickets/{ticket_id}/assign` - Assign to single agent
- `POST /api/v1/ticket-assignments/tickets/{ticket_id}/assign-team` - Assign to team
- Review dropped tickets (status = `pending_review`)
- Decide: reopen, cancel, or reschedule
## Testing Checklist
### Solo Agent Flow
- [ ] Agent picks open ticket
- [ ] Agent starts journey
- [ ] Agent records arrival
- [ ] Agent completes ticket
- [ ] Verify assignment action = `completed`
- [ ] Verify ticket status = `completed`
### Team Flow
- [ ] Agent 1 picks ticket (1/2)
- [ ] Agent 2 picks ticket (2/2)
- [ ] Agent 1 drops ticket
- [ ] Verify Agent 2 also dropped
- [ ] Verify ticket status = `pending_review`
### Drop Flow
- [ ] Agent drops with type "reschedule"
- [ ] Verify ticket status = `pending_review`
- [ ] Verify assignment action = `dropped`
- [ ] PM can see dropped tickets
### Dispatcher Assignment Flow
- [ ] Dispatcher assigns ticket to agent
- [ ] Agent sees accept/reject buttons
- [ ] Agent accepts
- [ ] Agent completes workflow
### View Only States
- [ ] Rejected assignment shows message
- [ ] Dropped assignment shows message
- [ ] Completed assignment shows message
- [ ] Pending review ticket shows message
### Capacity Limits
- [ ] Agent with 4 active tickets can't pick more
- [ ] Agent with 3 active tickets can pick 1 more
### Regional Access (No Restrictions)
- [ ] Agent can pick tickets from any region in their project
- [ ] Region is for filtering/preference, not access control
- [ ] Agents go where the work is to earn a living
## Migration Steps
1. **Run SQL migration:**
```bash
# In Supabase SQL Editor or via migration tool
psql -f supabase/migrations/20251128112603_rename_unassigned_to_completed.sql
```
2. **Deploy backend changes:**
- All Python files compile successfully
- No breaking changes to existing endpoints
3. **Update frontend:**
- Use `available_actions` from ticket detail response
- Render buttons dynamically
- Handle drop modal with `drop_type` field
## Notes
- **No breaking changes** - Existing endpoints still work
- **Backward compatible** - Old clients can still use manual button logic
- **Progressive enhancement** - New clients get dynamic actions
- **Security** - Backend validates all actions, frontend just displays
- **Scalability** - Easy to add new actions (just update calculator)
## Future Enhancements
1. **Action permissions** - Some actions only for certain roles
2. **Action conditions** - "Complete only if expenses approved"
3. **Action metadata** - "Requires GPS", "Requires photo"
4. **Action history** - Track which actions were available when
5. **Action analytics** - Which actions are most used/skipped
|