Spaces:
Sleeping
Sleeping
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
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
supabase/migrations/20251128112603_rename_unassigned_to_completed.sql- Renames enum value
unassignedβcompleted - Better semantic meaning for completed assignments
- Renames enum value
docs/agent/frontend/TICKET_ACTIONS_SYSTEM.md- Complete frontend integration guide
- Action flow states
- Example implementation
Files Modified
src/app/models/enums.py- Changed
UNASSIGNED = "unassigned"βCOMPLETED = "completed"
- Changed
src/app/services/ticket_assignment_service.py- Added
AssignmentActionimport - Updated
complete_assignment()to setaction = COMPLETED - Updated
drop_assignment()to:- Set
action = DROPPED - Set ticket status to
PENDING_REVIEW - Drop all team members if team ticket
- Added
drop_typeparameter
- Set
- Updated
self_assign_ticket()to:- Set
action = ACCEPTED(auto-accepted) - Set
responded_attimestamp
- Set
- Added
src/app/schemas/ticket_assignment.py- Added
drop_typefield toAssignmentDropschema
- Added
src/app/api/v1/tickets.py- Updated
GET /tickets/{ticket_id}/detailendpoint - Added
TicketActionServiceimport - Added to response:
available_actions,current_assignment,team_info,message
- Updated
Key Business Rules
Assignment Action States
assigned- Dispatcher assigned, agent hasn't respondedaccepted- Agent accepted assignmentrejected- Agent rejected assignmentdropped- Agent dropped mid-workreassigned- Dispatcher reassigned to different agentcompleted- Work finished
Ticket Status Flow
open- Available for pickupassigned- Agent(s) assignedin_progress- Agent started journeypending_review- Agent dropped, awaiting PM/dispatcher actioncompleted- Work finishedcancelled- 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_sizedefines 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 actionsPOST /api/v1/ticket-assignments/tickets/{ticket_id}/self-assign- Pick ticketPOST /api/v1/ticket-assignments/assignments/{assignment_id}/accept- Accept assignmentPOST /api/v1/ticket-assignments/assignments/{assignment_id}/reject- Reject assignmentPOST /api/v1/ticket-assignments/assignments/{assignment_id}/start-journey- Start journeyPOST /api/v1/ticket-assignments/assignments/{assignment_id}/arrived- Record arrivalPOST /api/v1/ticket-assignments/assignments/{assignment_id}/complete- Complete workPOST /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 agentPOST /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
Run SQL migration:
# In Supabase SQL Editor or via migration tool psql -f supabase/migrations/20251128112603_rename_unassigned_to_completed.sqlDeploy backend changes:
- All Python files compile successfully
- No breaking changes to existing endpoints
Update frontend:
- Use
available_actionsfrom ticket detail response - Render buttons dynamically
- Handle drop modal with
drop_typefield
- Use
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
- Action permissions - Some actions only for certain roles
- Action conditions - "Complete only if expenses approved"
- Action metadata - "Requires GPS", "Requires photo"
- Action history - Track which actions were available when
- Action analytics - Which actions are most used/skipped