swiftops-backend / docs /api /tickets /WORK-LOCATION-EXAMPLES.md
kamau1's picture
feat: auto-populate and verify ticket work locations from assignment arrival coordinates
f8f7bb6

Work Location Derivation - Real Examples

Example 1: Missing Work Location (Derive)

Before Completion

Ticket: f59b29fc-d0b9-4618-b0d1-889e340da612

work_location_latitude: NULL
work_location_longitude: NULL
work_location_verified: false
status: 'in_progress'

Assignment: a82a3824-f4f1-4283-a2e3-8c348dbb28ce

arrival_latitude: -1.10056144256674
arrival_longitude: 37.0092363654176
arrived_at: '2025-11-30 10:56:11.929093+00'

After Completion

Ticket: f59b29fc-d0b9-4618-b0d1-889e340da612

work_location_latitude: -1.10056144256674  ← Derived from arrival
work_location_longitude: 37.0092363654176  ← Derived from arrival
work_location_verified: true               ← Auto-verified (GPS source)
status: 'completed'
completed_at: '2025-11-30 12:08:38.793534+00'

Log Output:

INFO: Work location update for ticket f59b29fc-d0b9-4618-b0d1-889e340da612: 
  action=derived, 
  success=True, 
  message=Work location derived from arrival coordinates

Example 2: Existing Work Location (Verify - Success)

Before Completion

Ticket: 8f08ad14-df8b-4780-84e7-0d45e133f2a6

work_location_latitude: -1.22005074013012  ← From sales order
work_location_longitude: 36.8772529852395  ← From sales order
work_location_verified: false
status: 'in_progress'

Assignment: b3a83bd0-d287-4cea-a1c8-8bef145c1296

arrival_latitude: -1.22018863567581
arrival_longitude: 36.8775512279948
arrived_at: '2025-11-28 10:45:04.045672+00'

Distance Calculation

distance = haversine_distance(
    -1.22005074013012, 36.8772529852395,  # Work location
    -1.22018863567581, 36.8775512279948   # Arrival
)
# Result: ~52 meters

After Completion

Ticket: 8f08ad14-df8b-4780-84e7-0d45e133f2a6

work_location_latitude: -1.22005074013012  ← Unchanged
work_location_longitude: 36.8772529852395  ← Unchanged
work_location_verified: true               ← Verified (within 100m)
status: 'completed'
completed_at: '2025-11-28 10:45:04.045672+00'

Log Output:

INFO: Work location update for ticket 8f08ad14-df8b-4780-84e7-0d45e133f2a6: 
  action=verified, 
  success=True, 
  message=Work location verified (distance: 52.34m)

Example 3: Existing Work Location (Verify - Failed)

Scenario

Agent went to wrong location or sales order had incorrect coordinates.

Before Completion

Ticket: abc123-example

work_location_latitude: -1.2864  ← Wrong location
work_location_longitude: 36.8172
work_location_verified: false
status: 'in_progress'

Assignment: xyz789-example

arrival_latitude: -1.2921  ← Actual work site (1km away)
arrival_longitude: 36.8219
arrived_at: '2025-11-30 14:30:00+00'

Distance Calculation

distance = haversine_distance(
    -1.2864, 36.8172,  # Work location (wrong)
    -1.2921, 36.8219   # Arrival (actual)
)
# Result: ~750 meters (exceeds 100m threshold)

After Completion

Ticket: abc123-example

work_location_latitude: -1.2864  ← Unchanged
work_location_longitude: 36.8172
work_location_verified: false    ← NOT verified (too far)
status: 'completed'

Log Output:

WARNING: Work location verification failed for ticket abc123-example: 
  distance=750.23m exceeds threshold=100m

Action Required: PM should review this ticket - either:

  1. Sales order had wrong coordinates β†’ Update for future reference
  2. Agent went to wrong location β†’ Investigate

Example 4: No Arrival Coordinates

Scenario

Agent completed ticket without marking arrival (edge case).

Before Completion

Ticket: def456-example

work_location_latitude: NULL
work_location_longitude: NULL
work_location_verified: false
status: 'in_progress'

Assignment: uvw123-example

arrival_latitude: NULL  ← Agent never marked arrival
arrival_longitude: NULL
journey_started_at: '2025-11-30 09:00:00+00'

After Completion

Ticket: def456-example

work_location_latitude: NULL  ← Unchanged (no data to derive)
work_location_longitude: NULL
work_location_verified: false
status: 'completed'

Log Output:

INFO: Work location update for ticket def456-example: 
  action=derived, 
  success=False, 
  message=Assignment has no arrival coordinates

Note: Ticket still completes successfully - location derivation is opportunistic, not required.


Journey Location History

Assignments also track GPS breadcrumbs during journey:

"journey_location_history": [
  {
    "lat": -1.100523333333333,
    "lng": 37.00922666666666,
    "speed": 0.0,
    "battery": 100,
    "accuracy": 64.0,
    "timestamp": "2025-11-30T10:55:40.399050"
  },
  {
    "lat": -1.1005614425667403,
    "lng": 37.009236365417586,
    "speed": 0.0,
    "battery": 100,
    "accuracy": 65.0,
    "timestamp": "2025-11-30T10:56:11.682201"
  }
]

Future Enhancement: Could use journey history for:

  • Better location accuracy (average multiple points)
  • Detect if agent actually traveled to site
  • Geofencing validation

Database Schema Reference

Tickets Table

work_location_latitude    NUMERIC(10,7)  -- GPS latitude where work performed
work_location_longitude   NUMERIC(10,7)  -- GPS longitude where work performed
work_location_accuracy    NUMERIC(10,2)  -- GPS accuracy in meters
work_location_verified    BOOLEAN        -- True if verified against arrival

Ticket Assignments Table

arrival_latitude          NUMERIC(10,7)  -- GPS latitude at arrival
arrival_longitude         NUMERIC(10,7)  -- GPS longitude at arrival
arrival_verified          BOOLEAN        -- Manual verification by admin
journey_location_history  JSONB          -- GPS breadcrumbs during journey

API Response Example

When fetching ticket details, work location info is included:

{
  "ticket": {
    "id": "f59b29fc-d0b9-4618-b0d1-889e340da612",
    "status": "completed",
    "work_location_latitude": -1.10056144,
    "work_location_longitude": 37.00923637,
    "work_location_verified": true,
    "completed_at": "2025-11-30T12:08:38.793534Z"
  },
  "current_assignment": {
    "id": "a82a3824-f4f1-4283-a2e3-8c348dbb28ce",
    "arrival_latitude": -1.10056144,
    "arrival_longitude": 37.00923637,
    "arrived_at": "2025-11-30T10:56:11.929093Z"
  }
}

Frontend can display:

  • Work location on map
  • Verification status badge
  • Distance between expected and actual location