From 2021 to 2024 I drove vehicles for a delivery company out of Winnipeg. A dealership needs a car moved, dispatch finds a driver, and the driver picks it up and drives it somewhere else, sometimes several provinces away. Along the way there's paperwork, fuel and hotel receipts, and a lot of back and forth with dispatch about the schedule.
I own the portal end to end, from its data model and backend logic to the frontend. It reached a usable state in September 2026 and is undergoing operational testing. A few decisions came straight from having done the job.
The route and the price are different things
A trip estimate has two parts. One is the route, meaning where the car goes, where the driver stops overnight, and how they get back. The other is the pricing, meaning the rates, the overnight costs, and fuel. The two change for different reasons and at different times.
So the app stores route geometry separately from the estimate. Changing a rate re-prices the saved route without another call to the Google Routes API. The preview and the saved estimate use the same calculation, so the number a dispatcher sees before saving is the number that gets saved.
History has to match the trip
When something goes wrong on a delivery, the first question is always who changed what, and when. Convex runs each mutation as a transaction, so the change to the trip, the activity log entry, and the aggregate counts are written together. If one fails, none of them happen.
Drivers are on their phones, in parking lots
Receipt photos get uploaded from a phone with bad signal while the driver is doing something else. An upload can finish long after the driver has moved to a different screen. Each upload keeps a reference to the expense it came from, so a late upload lands in the right place instead of whatever is open.
Documents become reviewed drafts
The portal uses the OpenAI API to classify receipt images and booking PDFs and extract structured facts. Validation turns those facts into editable expense and appointment drafts. A person reviews the information before saving; extraction does not silently create business records.
Live changes should not erase your work
Live updates preserve unsaved drafts. Revision checks reject conflicting expense and deliverable saves, while immutable estimate and rate revisions retain the calculations behind previous quotes.
Who can see what
Agents at a dealership should see their own trips and not another dealership's. Drivers shouldn't see what the company charges. Dispatchers need to see everything, and sometimes need to see exactly what a driver sees to help them. The portal has role checks on every query, role-specific financial fields, and a view-as mode for dispatchers that writes to the audit log.
The separate Trip Estimator is now the business’s primary estimating tool, supporting nearly 100 estimates for deliveries scheduled in September 2026. Its regression tests protect the estimate calculations, and CI runs them on every push. The portal has its own estimate test suite for the same reason. When money is involved, a changed number should fail a test before it reaches a dealership.