Overview
The Tractors API provides endpoints for managing tractor-to-vehicle mappings and fault code synchronization. Tractors represent power units (trucks) that are tracked via Terminal API and matched to McLeod TMS data. Database Table:tractors
Key Columns:
vehicle_id- Terminal API vehicle ID (e.g.,vcl_xxx)mcleod_tractor_id- McLeod tractor ID (e.g.,735)latitude,longitude- GPS coordinatesfault_codes- PostgreSQL TEXT[] array of fault code descriptions
- Terminal API provides vehicles with IDs like
vcl_01D8ZQFGHVJ858NBF2Q7DV9MNC - McLeod TMS uses tractor IDs like
735 - The mapping service connects these two systems by normalizing vehicle names
Sync Tractor Mapping
POST /api/tractors/sync-mapping
Sync tractor-to-vehicle mappings. Only updates tractors that have movements in the database. Use this endpoint when you want to selectively update tractors that are actively assigned to movements. Response:- Fetch Terminal Vehicles: Calls Terminal API
/tsp/v1/vehiclesto get all vehicles - Normalize Names: Extracts tractor numbers from vehicle names:
- “Tractor 735” → “735”
- “TRK-00735” → “735”
- “Truck #0735” → “735”
- Get McLeod Tractors: Queries
movementstable for distinct__tractoridvalues - Match: Compares normalized numbers to McLeod tractor IDs
- Update Database: Calls
update_tractor_mapping()to setmcleod_tractor_idfor matching vehicles - Handle Ambiguity: If multiple Terminal vehicles normalize to the same number, mapping is skipped and logged
- Extracts last contiguous digits from vehicle name
- Removes leading zeros
- Example: “FLEET-TRUCK-00735-WEST” → “735”
Sync All Vehicle Names
POST /api/tractors/sync-vehicle-names
Sync Terminal vehicle names directly tomcleod_tractor_id. Updates ALL tractors regardless of movement assignments.
Use this endpoint when you want to update the entire tractors table with Terminal vehicle names.
Response:
- Fetches all vehicles from Terminal API
/tsp/v1/vehicles - For each vehicle, sets
tractors.mcleod_tractor_id = vehicle.name - Uses
update_tractor_mcleod_id_from_terminal_name()which:- Updates existing tractor if
vehicle_idmatches - Creates new tractor record if not found
- Updates existing tractor if
sync-mapping: Only updates tractors with matching movements (selective)sync-vehicle-names: Updates ALL tractors with Terminal vehicle names (comprehensive)
Get Mapping Stats
GET /api/tractors/mapping-stats
Get aggregate statistics about current tractor mappings. Response:| Field | Description |
|---|---|
total_tractors | Total rows in tractors table |
mcleod_mapped_count | Tractors with non-empty mcleod_tractor_id |
terminal_mapped_count | Tractors with non-empty vehicle_id |
fully_mapped_count | Tractors with both IDs mapped |
unmapped_count | Tractors with neither ID |
needs_sync | true if fully_mapped_percentage < 80% |
- Queries
tractorstable with SQL aggregation - Uses
CASEstatements to count mapping states - Calculates percentages and
needs_syncthreshold - Calls
get_tractor_mapping_count_metrics()andget_tractor_mapping_health()
Sync Fault Codes
POST /api/tractors/fault-codes/sync
Sync fault codes from Motive API to thetractors table.
Comma-separated list of Motive vehicle IDs to filter for
Filter by fault code status (e.g.,
active, closed)Maximum number of fault codes to fetch (max: 1000)
- Calls Motive API
/v1/vehicle_diagnostics/fault_codesviaMotiveClient - For each fault code, extracts description field
- Matches fault codes to tractors via
mcleod_id - Appends descriptions to
tractors.fault_codesPostgreSQL array viaappend_fault_codes_to_tractor() - Deduplicates entries (won’t add same description twice)
LocationPollingService._fetch_and_process_locations().
Get Fault Codes
GET /api/tractors/fault-codes
Get fault codes for a specific tractor byvehicle_id.
Terminal vehicle ID (e.g.,
vcl_01D8ZQFGHVJ858NBF2Q7DV9MNC)- Queries
tractorstable byvehicle_id - Returns
fault_codesarray (PostgreSQL TEXT[]) - Handles backward compatibility with JSON and comma-separated string formats
- Returns 404 if tractor not found
Data Model
Tractors Table Schema
| Column | Type | Description |
|---|---|---|
id | UUID | Primary key |
company_id | VARCHAR | Always “TERM” for Terminal data |
vehicle_id | VARCHAR | Terminal vehicle ID (unique) |
mcleod_tractor_id | VARCHAR | McLeod tractor ID |
latitude | NUMERIC(10,8) | GPS latitude |
longitude | NUMERIC(11,8) | GPS longitude |
fuel_level | NUMERIC | Fuel percentage |
odometer_miles | NUMERIC | Odometer reading |
engine_hours | NUMERIC | Engine hours |
last_located_at | TIMESTAMPTZ | Last location timestamp |
last_location_provider | VARCHAR | ”terminal” or “movement_stop” |
fault_codes | TEXT[] | Array of fault descriptions |
updated_at | TIMESTAMPTZ | Last DB update |
Location Provider Priority
- Terminal GPS (authoritative): Updated by
LocationPollingServiceevery 60 seconds - Movement Stop Fallback: When Terminal GPS unavailable, uses stop coordinates from McLeod movements
last_location_provider column indicates which source provided the current location.
