@fleetbase/fleetops-engine 0.6.60 → 0.6.62

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. package/RELEASE.md +21 -17
  2. package/addon/components/ai/route-preview-map.js +1 -5
  3. package/addon/components/customer/orders.js +2 -1
  4. package/addon/components/driver/card.hbs +49 -0
  5. package/addon/components/driver/card.js +30 -0
  6. package/addon/components/map/leaflet-live-map.js +4 -19
  7. package/addon/components/modals/place-details.hbs +1 -1
  8. package/addon/components/modals/point-map.hbs +1 -1
  9. package/addon/components/orchestrator-workbench.js +2 -1
  10. package/addon/components/order/form/route.js +3 -0
  11. package/addon/components/order-tracking-lookup.js +2 -1
  12. package/addon/components/place/details.hbs +1 -1
  13. package/addon/components/positions-replay.js +4 -1
  14. package/addon/components/service-area/details.hbs +1 -1
  15. package/addon/components/widget/live-fleet.js +7 -7
  16. package/addon/components/zone/details.hbs +1 -1
  17. package/addon/controllers/management/drivers/index.js +22 -1
  18. package/addon/controllers/settings/map.js +16 -0
  19. package/addon/helpers/leaflet-tile-url.js +19 -0
  20. package/addon/services/map-settings.js +26 -1
  21. package/addon/templates/management/drivers/index.hbs +67 -33
  22. package/addon/templates/settings/map.hbs +10 -0
  23. package/addon/utils/leaflet-tile-url.js +31 -0
  24. package/addon/utils/prepare-place-for-save.js +13 -0
  25. package/app/components/driver/card.js +1 -0
  26. package/app/helpers/leaflet-tile-url.js +1 -0
  27. package/app/utils/leaflet-tile-url.js +1 -0
  28. package/composer.json +1 -1
  29. package/extension.json +1 -1
  30. package/index.js +11 -0
  31. package/package.json +2 -1
  32. package/server/migrations/2026_09_05_000001_add_unique_indexes_to_fleet_membership_pivots.php +129 -0
  33. package/server/src/Exceptions/PublicRelationNotFoundException.php +47 -0
  34. package/server/src/Http/Controllers/Api/v1/Concerns/ResolvesFleetOpsApiResources.php +42 -7
  35. package/server/src/Http/Controllers/Api/v1/Concerns/ResolvesPublicExpansions.php +187 -0
  36. package/server/src/Http/Controllers/Api/v1/DriverController.php +312 -59
  37. package/server/src/Http/Controllers/Api/v1/EntityController.php +1 -1
  38. package/server/src/Http/Controllers/Api/v1/FleetController.php +370 -33
  39. package/server/src/Http/Controllers/Api/v1/FuelReportController.php +1 -1
  40. package/server/src/Http/Controllers/Api/v1/IssueController.php +1 -1
  41. package/server/src/Http/Controllers/Api/v1/ManifestController.php +250 -0
  42. package/server/src/Http/Controllers/Api/v1/OrderController.php +1 -1
  43. package/server/src/Http/Controllers/Api/v1/ServiceAreaController.php +1 -1
  44. package/server/src/Http/Controllers/Api/v1/TrackingStatusController.php +1 -1
  45. package/server/src/Http/Controllers/Api/v1/VehicleController.php +139 -34
  46. package/server/src/Http/Controllers/Api/v1/ZoneController.php +1 -1
  47. package/server/src/Http/Controllers/Internal/v1/SettingController.php +22 -0
  48. package/server/src/Http/Filter/Concerns/ResolvesPublicRelationUuids.php +54 -0
  49. package/server/src/Http/Filter/DriverFilter.php +71 -15
  50. package/server/src/Http/Filter/FleetFilter.php +32 -33
  51. package/server/src/Http/Filter/FuelReportFilter.php +29 -0
  52. package/server/src/Http/Filter/IssueFilter.php +29 -0
  53. package/server/src/Http/Filter/VehicleFilter.php +57 -19
  54. package/server/src/Http/Requests/Concerns/ScopesPublicRelationRules.php +48 -0
  55. package/server/src/Http/Requests/CreateDriverRequest.php +100 -9
  56. package/server/src/Http/Requests/CreateFleetRequest.php +30 -2
  57. package/server/src/Http/Requests/CreateServiceRateRequest.php +7 -2
  58. package/server/src/Http/Requests/CreateVehicleRequest.php +150 -26
  59. package/server/src/Http/Resources/v1/Concerns/ResolvesPublicRelationFields.php +110 -0
  60. package/server/src/Http/Resources/v1/Driver.php +22 -2
  61. package/server/src/Http/Resources/v1/Fleet.php +38 -25
  62. package/server/src/Http/Resources/v1/Manifest.php +52 -0
  63. package/server/src/Http/Resources/v1/ManifestStop.php +47 -0
  64. package/server/src/Http/Resources/v1/OrderConfig.php +51 -4
  65. package/server/src/Http/Resources/v1/Vehicle.php +46 -4
  66. package/server/src/Models/Driver.php +2 -2
  67. package/server/src/Models/Place.php +1 -1
  68. package/server/src/routes.php +29 -0
  69. package/server/tests/ApiDriverControllerContractsTest.php +317 -13
  70. package/server/tests/ApiDriverPasswordContractsTest.php +457 -0
  71. package/server/tests/ApiEntityControllerContractsTest.php +1 -1
  72. package/server/tests/ApiEquipmentControllerContractsTest.php +2 -2
  73. package/server/tests/ApiFleetControllerContractsTest.php +354 -21
  74. package/server/tests/ApiFuelReportControllerContractsTest.php +1 -1
  75. package/server/tests/ApiIssueControllerContractsTest.php +1 -1
  76. package/server/tests/ApiManifestControllerContractsTest.php +599 -0
  77. package/server/tests/ApiOrderControllerContractsTest.php +1 -1
  78. package/server/tests/ApiPartControllerContractsTest.php +2 -2
  79. package/server/tests/ApiServiceAreaZoneControllerContractsTest.php +2 -2
  80. package/server/tests/ApiTrackingStatusControllerContractsTest.php +1 -1
  81. package/server/tests/ApiVehicleControllerContractsTest.php +210 -8
  82. package/server/tests/CompactResourceSerializationTest.php +13 -7
  83. package/server/tests/ControllerFilterContractsTest.php +132 -13
  84. package/server/tests/ControllerHelperContractsTest.php +6 -3
  85. package/server/tests/DriverFilterExecutionTest.php +130 -6
  86. package/server/tests/ExceptionContractsTest.php +15 -0
  87. package/server/tests/Feature/Http/Api/DeviceControllerContractsTest.php +1 -1
  88. package/server/tests/Feature/Http/Api/DriverControllerSessionHelpersTest.php +61 -0
  89. package/server/tests/Feature/Http/Api/FleetMembershipMigrationTest.php +140 -0
  90. package/server/tests/Feature/Http/Api/FleetMembershipTest.php +333 -0
  91. package/server/tests/Feature/Http/Api/FleetPublicContractTest.php +439 -0
  92. package/server/tests/Feature/Http/Api/FuelTransactionControllerContractsTest.php +2 -2
  93. package/server/tests/Feature/Http/Api/NullRelationshipInputTest.php +191 -0
  94. package/server/tests/Feature/Http/Api/PublicIdentifierFilterTest.php +293 -0
  95. package/server/tests/Feature/Http/Api/SmallApiControllerHelpersTest.php +7 -1
  96. package/server/tests/Feature/Http/Api/VehicleControllerTrackingTest.php +3 -1
  97. package/server/tests/Feature/Http/Api/VehiclePublicContractTest.php +454 -0
  98. package/server/tests/Feature/Http/Api/WorkOrderControllerContractsTest.php +1 -1
  99. package/server/tests/Feature/Http/Internal/PlaceControllerTest.php +45 -0
  100. package/server/tests/FleetHierarchyResourceTest.php +56 -8
  101. package/server/tests/RequestContractsTest.php +105 -7
  102. package/server/tests/SettingControllerContractsTest.php +33 -0
  103. package/server/tests/Unit/Http/Filter/FuelReportFilterTest.php +135 -0
  104. package/server/tests/Unit/Http/Filter/IssueFilterTest.php +43 -0
  105. package/server/tests/Unit/Http/Resources/FleetResourceTest.php +50 -6
  106. package/server/tests/Unit/Http/Resources/ManifestResourceTest.php +129 -0
  107. package/server/tests/Unit/Http/Resources/OrderConfigResourceTest.php +91 -0
  108. package/server/tests/VehicleControllerHelperContractsTest.php +1 -1
  109. package/translations/en-us.yaml +4 -0
@@ -45,3 +45,94 @@ test('order config resource projects empty and invalid flow as an empty list', f
45
45
  expect($payload['id'])->toBe('order_config_public')
46
46
  ->and($payload['flow'])->toBe([]);
47
47
  });
48
+
49
+ test('order config resource publishes the flow graph so consumers can sequence it', function () {
50
+ $request = Request::create('/v1/fleet-ops/order-configs/order_config_public', 'GET');
51
+ FleetOpsOrderConfigResourceRequestState::$request = $request;
52
+ FleetOpsSupportRequestState::$request = $request;
53
+
54
+ // Declared deliberately out of workflow order, which is how flows are
55
+ // stored: `completed` before the step that leads to it, `dispatched` last.
56
+ $config = new OrderConfig();
57
+ $config->setRawAttributes([
58
+ 'id' => 8,
59
+ 'uuid' => 'order-config-uuid',
60
+ 'public_id' => 'order_config_public',
61
+ 'key' => 'transport',
62
+ 'name' => 'Transport',
63
+ 'flow' => [
64
+ ['code' => 'completed', 'status' => 'Order Completed', 'complete' => true, 'activities' => []],
65
+ ['code' => 'created', 'status' => 'Order Created', 'activities' => ['dispatched']],
66
+ ['code' => 'dispatched', 'status' => 'Order Dispatched', 'activities' => ['enroute'], 'sequence' => 2],
67
+ [
68
+ 'code' => 'enroute',
69
+ 'status' => 'Driver Enroute',
70
+ 'activities' => ['completed', 'failed'],
71
+ 'logic' => [['type' => 'and', 'conditions' => []]],
72
+ ],
73
+ ],
74
+ ], true);
75
+
76
+ $flow = (new OrderConfigResource($config))->resolve($request)['flow'];
77
+ $byCode = collect($flow)->keyBy('code');
78
+
79
+ expect($byCode['created']['activities'])->toBe(['dispatched'])
80
+ ->and($byCode['dispatched']['sequence'])->toBe(2)
81
+ ->and($byCode['enroute']['activities'])->toBe(['completed', 'failed'])
82
+ ->and($byCode['enroute']['logic'])->toBe([['type' => 'and', 'conditions' => []]])
83
+ ->and($byCode['completed']['complete'])->toBeTrue();
84
+ });
85
+
86
+ test('order config resource normalises transitions written as objects', function () {
87
+ $request = Request::create('/v1/fleet-ops/order-configs/order_config_public', 'GET');
88
+ FleetOpsOrderConfigResourceRequestState::$request = $request;
89
+ FleetOpsSupportRequestState::$request = $request;
90
+
91
+ // Flows have been authored both ways; a consumer should not have to guess.
92
+ $config = new OrderConfig();
93
+ $config->setRawAttributes([
94
+ 'id' => 9,
95
+ 'uuid' => 'order-config-uuid',
96
+ 'public_id' => 'order_config_public',
97
+ 'key' => 'transport',
98
+ 'name' => 'Transport',
99
+ 'flow' => [
100
+ ['code' => 'created', 'activities' => [['code' => 'dispatched'], 'enroute', ['label' => 'no code here']]],
101
+ // A flow hand-edited down to a single transition can leave a bare
102
+ // string where the list belongs. Publish an empty list rather than
103
+ // letting the shape vary — a consumer iterating the field should
104
+ // never have to type-check it.
105
+ ['code' => 'dispatched', 'activities' => 'enroute'],
106
+ ],
107
+ ], true);
108
+
109
+ $flow = (new OrderConfigResource($config))->resolve($request)['flow'];
110
+
111
+ expect($flow[0]['activities'])->toBe(['dispatched', 'enroute'])
112
+ ->and($flow[1]['activities'])->toBe([]);
113
+ });
114
+
115
+ test('order config resource keeps flow fields absent from a legacy activity null rather than missing', function () {
116
+ $request = Request::create('/v1/fleet-ops/order-configs/order_config_public', 'GET');
117
+ FleetOpsOrderConfigResourceRequestState::$request = $request;
118
+ FleetOpsSupportRequestState::$request = $request;
119
+
120
+ $config = new OrderConfig();
121
+ $config->setRawAttributes([
122
+ 'id' => 10,
123
+ 'uuid' => 'order-config-uuid',
124
+ 'public_id' => 'order_config_public',
125
+ 'key' => 'transport',
126
+ 'name' => 'Transport',
127
+ 'flow' => [['code' => 'created', 'status' => 'Order Created']],
128
+ ], true);
129
+
130
+ $flow = (new OrderConfigResource($config))->resolve($request)['flow'];
131
+
132
+ // Present-and-null is a contract a client can read; absent is one it has to
133
+ // feel for.
134
+ expect($flow[0])->toHaveKeys(['sequence', 'activities', 'logic'])
135
+ ->and($flow[0]['sequence'])->toBeNull()
136
+ ->and($flow[0]['activities'])->toBe([])
137
+ ->and($flow[0]['logic'])->toBeNull();
138
+ });
@@ -39,7 +39,7 @@ class FleetOpsVehicleControllerProbe extends VehicleController
39
39
  return $this->vehicle;
40
40
  }
41
41
 
42
- protected function findDriver(string $id): Driver
42
+ protected function findDriver(?string $id): Driver
43
43
  {
44
44
  $this->driverLookups[] = $id;
45
45
 
@@ -2006,6 +2006,10 @@ settings:
2006
2006
  map-provider: Map Provider
2007
2007
  map-provider-help-text: Choose the map engine used to render the live operations map. Leaflet uses OpenStreetMap tiles and requires no API key. Google Maps requires a valid Google Maps JavaScript API key.
2008
2008
  select-map-provider: Select map provider
2009
+ leaflet-tile-url: Leaflet Tile Provider URL
2010
+ leaflet-tile-url-help-text: Optional custom XYZ tile provider URL template used by the Leaflet map. Leave blank to use the default OpenStreetMap tiles which require no API key. Use this to point Leaflet at your own tile provider, including keyed providers such as CARTO.
2011
+ leaflet-dark-tile-url: Leaflet Dark Mode Tile Provider URL
2012
+ leaflet-dark-tile-url-help-text: Optional tile provider URL used when the console is in dark mode. Leave blank to fall back to the tile provider URL above, or the default OpenStreetMap tiles.
2009
2013
  google-maps-map-type: Map Type
2010
2014
  google-maps-map-type-help-text: The default map style to display when Google Maps is active.
2011
2015
  select-map-type: Select map type