feat: Intelligent Order Allocation Engine — engine-agnostic, core FleetOps integration#217
Open
feat: Intelligent Order Allocation Engine — engine-agnostic, core FleetOps integration#217
Conversation
…etOps integration ## Backend ### Allocation Engine Architecture (server/src/Allocation/) - AllocationEngineInterface: defines the allocate()/getName()/getIdentifier() contract - AllocationEngineRegistry: singleton service-locator; engines register via resolving() hook - AllocationPayloadBuilder: engine-agnostic normalizer — builds jobs/vehicles arrays from Order/Vehicle models, reads custom fields for skill codes, injects driver shift time_windows from Driver::activeShiftFor() (prerequisite: PR #216 driver scheduling integration) - VroomAllocationEngine: default VROOM implementation; maps normalized payload to VROOM VRP wire format, handles integer ID mapping, parses routes/unassigned back to public_ids ### AllocationController (server/src/Http/Controllers/Internal/v1/) - POST fleet-ops/allocation/run — run engine against unassigned orders + online vehicles - POST fleet-ops/allocation/commit — commit assignments via Order::firstDispatchWithActivity() - GET fleet-ops/allocation/preview — preview without side effects - GET fleet-ops/allocation/engines — list registered engines (for settings dropdown) - GET fleet-ops/allocation/settings — get allocation settings - PATCH fleet-ops/allocation/settings — save allocation settings ### ProcessAllocationJob (server/src/Jobs/) - Queueable, idempotent background job for auto-allocation on order creation or re-allocation - Reads active engine from Setting::lookup('fleetops.allocation_engine', 'vroom') ### HandleDeliveryCompletion (server/src/Listeners/) - Listens on OrderCompleted; dispatches ProcessAllocationJob when auto_reallocate_on_complete is enabled — closes the re-allocation loop ### Provider/Route wiring - FleetOpsServiceProvider: registers AllocationEngineRegistry singleton + VroomAllocationEngine - EventServiceProvider: adds HandleDeliveryCompletion to OrderCompleted listeners - routes.php: adds /allocation group with 6 endpoints under internal v1 fleet-ops prefix ## Frontend ### Engine Registry Pattern (addon/services/) - allocation-engine-interface.js: abstract base class with allocate() contract - allocation-engine.js: registry service — register()/resolve()/has()/availableEngines - vroom-allocation-engine.js: VROOM adapter — delegates to backend AllocationController - order-allocation.js: orchestration service — run/commit/loadSettings/saveSettings tasks ### Instance Initializer (addon/instance-initializers/) - register-vroom-allocation.js: registers VroomAllocationEngine into the allocation-engine registry at app boot — identical pattern to register-osrm.js for route optimization ### Dispatcher Workbench (addon/components/) - order-allocation-workbench.js: three-panel workbench with Order Bucket, Proposed Plan view, Vehicle Bucket; runAllocation/commitPlan/discardPlan tasks; handleDrop for drag-and-drop override; planByVehicle computed groups assignments by vehicle for the plan view - order-allocation-workbench.hbs: full Handlebars template with toolbar, three panels, per-vehicle route cards, unassigned warning banner, override badges, empty states ### Settings UI (addon/controllers/settings/ + addon/templates/settings/) - order-allocation.js controller: loadSettings/saveSettings tasks, engineOptions from registry - order-allocation.hbs template: engine selector (PowerSelect from registry), auto-allocate toggles, max travel time input, balance workload toggle ### Route/Navigation wiring - routes.js: adds operations.allocation and settings.order-allocation routes - routes/operations/allocation.js: ability-guarded route - routes/settings/order-allocation.js: ability-guarded route with setupController hook - templates/operations/allocation.hbs: renders OrderAllocationWorkbench - extension.js: adds Allocation shortcut tile + fleet-ops:template:settings:order-allocation registry - layout/fleet-ops-sidebar.js: adds Allocation to operations nav, Order Allocation to settings nav Closes #214
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Overview
Implements the Intelligent Order Allocation Engine as described in issue #214. This PR integrates the feature directly into core FleetOps (not as a separate extension) and introduces a fully engine-agnostic architecture that allows any third-party solver to register itself alongside the default VROOM implementation.
Architecture: Engine-Agnostic Registry Pattern
The allocation engine architecture mirrors the existing
route-optimizationregistry pattern already in FleetOps:RouteOptimizationInterfaceServiceAllocationEngineInterfaceServiceroute-optimizationserviceallocation-engineserviceregister-osrm.jsinitializerregister-vroom-allocation.jsinitializerAllocationEngineInterfacePHP contractAllocationEngineRegistryPHP singletonA third-party engine integrates by:
AllocationEngineInterface(PHP) andAllocationEngineInterfaceService(JS)->register(new MyEngine())in a service provider (PHP)allocationEngine.register('my-engine', myEngineService)in an instance initializer (JS)Backend Changes (server/)
New:
server/src/Allocation/Contracts/AllocationEngineInterface.phpallocate(),getName(),getIdentifier()AllocationEngineRegistry.phpregister(),resolve(),has(),available()Support/AllocationPayloadBuilder.phpEngines/VroomAllocationEngine.phpNew:
server/src/Http/Controllers/Internal/v1/AllocationController.phpSix endpoints under
/int/v1/fleet-ops/allocation/:POST run— run engine against unassigned orders + online vehiclesPOST commit— commit assignments viaOrder::firstDispatchWithActivity()GET preview— preview without side effectsGET engines— list registered enginesGET settings— get allocation settingsPATCH settings— save allocation settingsNew:
server/src/Jobs/ProcessAllocationJob.phpQueueable, idempotent background job. Reads active engine from
Setting::lookup('fleetops.allocation_engine', 'vroom'). Used for auto-allocation on order creation and re-allocation on delivery completion.New:
server/src/Listeners/HandleDeliveryCompletion.phpListens on
OrderCompleted. Whenauto_reallocate_on_completeis enabled, dispatchesProcessAllocationJob— closing the re-allocation loop so drivers are automatically assigned the next batch of orders as they complete deliveries.Modified:
server/src/Providers/EventServiceProvider.phpAdds
HandleDeliveryCompletionto theOrderCompletedlistener array.Modified:
server/src/Providers/FleetOpsServiceProvider.phpAllocationEngineRegistryas a singleton inregister()VroomAllocationEngineviaresolving()hook inboot()Modified:
server/src/routes.phpAdds
/allocationroute group with 6 endpoints under the internal v1 fleet-ops prefix.Frontend Changes (addon/)
New Services
services/allocation-engine-interface.jsallocate()contractservices/allocation-engine.jsregister(),resolve(),has(),availableEnginesservices/vroom-allocation-engine.jsAllocationControllerservices/order-allocation.jsrun,commit,loadSettings,saveSettingstasksNew Instance Initializer
instance-initializers/register-vroom-allocation.js— registers VROOM into the allocation-engine registry at app boot. Identical pattern toregister-osrm.js.New: Dispatcher Workbench
components/order-allocation-workbench.{js,hbs}— three-panel UI:New: Allocation Settings Page
controllers/settings/order-allocation.js— engine selector (from registry), auto-allocate toggles, max travel time, workload balancingtemplates/settings/order-allocation.hbs— settings form with ContentPanel layoutRoute/Navigation Wiring
routes.jsoperations.allocationandsettings.order-allocationroutes/operations/allocation.jsroutes/settings/order-allocation.jssetupControllerhooktemplates/operations/allocation.hbsOrderAllocationWorkbenchextension.jsfleet-ops:template:settings:order-allocationcomponents/layout/fleet-ops-sidebar.jsHow Third-Party Engines Register
PHP (service provider):
JavaScript (instance initializer):
The engine then appears in the FleetOps allocation settings dropdown automatically.
Closes #214
Depends on #216