Axleward is a fleet management and GPS tracking system you host yourself, built by DEV3 Technologies on Laravel 12 and Filament 4, with a Flutter driver app. One fleet operator runs it across one or more depots. The demo business is a fictional distributor, Harrowgate Distribution, with three depots and 120 vehicles.
No live demo: 36 grouped web screenshots, 16 driver-app screenshots and three video tours show the marketing site, the live map, the admin panel and the driver app. Install it with the bundled demo data to try every role on your own server.
What the fleet office gets
- A live map at
/live: vehicles with heading and state (moving, idle, off, no signal), search by plate or driver, a vehicle panel with its last alerts, and replay of any day with a speed graph and the trips and stops of that day.
- Trips that build themselves from the position stream: start and end places, distance (from the odometer when it is trustworthy, otherwise from the filtered track), duration, idle time and top speed. Late and out-of-order points are replayed into the right trip.
- Geofences as circles or polygons: depots, customers, speed zones and curfew zones. Enter and exit use hysteresis so GPS noise at the edge does not flap, dwell time is kept, and editing a fence recomputes its state quietly.
- Alerts for speeding, harsh events, idling, curfew, dwell, no signal and SOS, with cooldowns so one episode is one alert, recipients notified once, and acknowledge and close from the inbox.
- Driver scorecards with the formula shown: points per event per 100 km, so a score can be explained to the driver.
- Fuel: litres and cost from the app or a fuel-card CSV import (matched to app entries by time and litres), L/100 km between full tanks, cost per km, and flags for consumption well above the vehicle class and for more litres than the tank holds.
- Maintenance by odometer, engine hours or date, whichever comes first, with due jobs created automatically. Inspections (DVIR) from the app: a failed major item opens a job, an unsafe one takes the vehicle off the road until the workshop or the owner verifies the repair.
- Documents for vehicles and drivers (insurance, registration, licences) with an expiry reminder ladder and an optional block on starting a shift with an expired document.
- Dispatch: jobs with stops that arrive and depart by themselves from the geofence, with a manual fallback in the app; messages to a driver.
- Share links: a signed, expiring page that shows one vehicle's latest position to a customer and nothing else.
- Tracker ingest: any platform that can POST signed JSON (HMAC, replay protection, de-duplication, GPS-jump and odometer filters) to
/ingest/{device}; a scoped REST API with keys bound to depots; webhooks for alerts, trips, geofence events, defects, maintenance and documents.
- Depot isolation: staff see only the depots they are granted. Roles: owner, fleet manager, dispatcher, workshop and driver. Settings for every threshold, an audit log, backups and a generated OpenAPI document.
The driver app (Flutter source included)
Sign in, start a shift by choosing a vehicle at your depot, enter the odometer (checked against the last reading) and complete a twelve-line pre-trip check with severity, a note and a photo on a fail. During the shift the driver sees stops, arrives and departs, logs fuel with a receipt photo, sees documents with expiry chips, messages the office, reads the week's trips and the scorecard, and ends the shift with a post-trip check. Changes queue offline and send in order; a change the server refused waits on a Needs attention screen with Retry and Discard. The app runs in demo mode out of the box and points at your site when you set its URL. The fuel preview and the score use the same maths as the server, checked against 74 shared test vectors.
Position sharing: the app shares a position only while a shift is open and only in the foreground. There is no background location in this version. Demo positions are simulated; real device GPS is an opt-in setting that is off by default.
Built for correctness
Pest tests (325 passing, 1,776 assertions) cover ingest, trip segmentation, geofence hysteresis, episodes and cooldowns, fuel maths, maintenance due dates, shifts and defects, share links, depot isolation on every route and the driver app API. A MySQL race suite (10 groups, 22 checks) runs real parallel requests. The driver app has 84 tests. A built-in axleward:check command reconciles trips, odometers, geofence states, alerts, maintenance and fuel totals on the demo data.
The demo data
120 vehicles in 3 depots, 140 drivers, 160 devices (120 simulated trackers and 40 for the app), 85 geofences, 25 alert rules, 40 maintenance schedules, six inspection templates, about 69,000 trips, 32,000 daily vehicle statistics, 29,000 inspections, 12,900 alerts, 10,900 fuel entries and 380 documents across twelve months, plus raw positions for the most recent days. The demo history is a summary of a year for 120 vehicles, loaded in about 35 seconds, not a full-volume data set.
Good to know
- For one fleet operator with one or more depots. It is not a multi-company SaaS.
- Vehicle positions come from the driver app (foreground, during a shift) or from any tracker or telematics platform that can POST JSON to the signed endpoint. No device protocols are built in (Teltonika, Queclink and similar are not included). Demo positions are simulated.
- Speed limits are the limits you configure per vehicle class and speed zone; there is no road-speed database. Estimated arrival uses straight-line distance times a road factor; there is no routing API. Maps use OSM tiles when you configure a tile URL; otherwise the live map draws a plain background.
- Fuel cards are supported through CSV import. Mail, push and maps are simulated until you connect real ones.
- You must tell drivers they are tracked and follow local employee-monitoring law.
- The app was verified in simulator builds, tests and against the live API, not on a real device; push is a buyer add-on. Publishing to the app stores is your step (guide included).
Requires PHP 8.2+, MySQL 8 for a live site (the position table is partitioned by month on MySQL; SQLite is for evaluation) and a cron entry. Flutter 3 is needed only to build the app.