89 Minutes of Paperwork Before the First Truck Could Legally Move
Rebuilding fleet compliance as a platform, so the clerical cost stopped growing with every vehicle the company bought.
Thirty-seven percent of the fleet was carrying a problem nobody could see
The operation runs 138 vehicles out of five yards with 22 drivers. On a normal morning it carries 149 open compliance and hardware issues. A backlog is not unusual. What made this one expensive is that the system holding it had no opinion about which items mattered and no way to clear more than one at a time.
Three real problems were live in the fleet the morning this work started. A manager opening the old tool would have seen none of them.
Two plates had gone dark
RP-70144 had stopped reporting 52 hours earlier, RP-60012 36 hours in. Both rendered identically to the 136 vehicles that were fine.
A registration had already lapsed
Truck 2210 went overdue three days before anyone looked, with nothing flagging it on the way there. That is a problem an operation learns about from a phone call.
Eleven trucks had not moved in ten days
Three sat in one yard, six also had a renewal due. No column held "has not moved", so this one was not findable even on purpose.
The cost was not the backlog. It was the shape of the cost curve.
A missed row turns into money along a path that runs the same way every time. Nothing ranks a dark plate above a routine plate photo, so it waits for the next manual pass. The fix is retail, one vehicle per trip through the form, so the backlog fills faster than one person clears it. A renewal goes overdue. The truck is no longer street legal and it sits until the paperwork clears.
Every one of those steps scaled with the number of vehicles. Buying a hundred more trucks meant buying the clerical hours to match. That is what moved this from a usability complaint to a company priority, because it capped growth before the market did.
The brief was not "clean up the vehicle table"
Taking the narrow version would have left both expensive problems untouched, because neither one lives in the table. The ranking problem lives in the absence of a layer above it. The batching problem lives in the absence of a selection model underneath it.
So the mandate I set was to make compliance work stop scaling with fleet size, and to make the fleet's real state visible without anyone going looking for it. I owned product design and the front end build: information architecture, interaction design, the design system, and the React and Next.js implementation.
Filings carry legal consequence
Compliance submissions cannot be automated away casually. A wrong automatic filing is worse than a slow correct one, which ruled out the obvious efficiency play.
No behavioural data to tune against
Nothing in the legacy system was instrumented. Any threshold in the new product would be my judgement until real usage could correct it.
Nine modules, one build capacity
The full operational surface is nine modules. Building all nine at shallow depth was possible. Building three properly was the other option.
Success was defined up front as two things that could be checked later: reduce the vehicle days lost to avoidable compliance lapses, and break the link between fleet size and clerical hours. Both are stated again in the measurement plan at the end, because a success definition written after the results is not a success definition.
Eight gaps, severity rated, and only two of them worth building first
The gaps came from working alongside fleet managers and compliance staff running the old system, watching where the workflow actually stalled rather than where people said it did. Auditing the same system against usability heuristics, with every violation severity rated, turned that list into a build sequence.
Two findings rated severity 4, meaning work stops or compliance risk goes unseen: nothing ranked urgency, and nothing could be fixed in bulk. Everything else rated 3 or below. That is the entire justification for shipping three modules instead of nine.
| Gap | Heuristic violated | Sev. | Cost to the user |
|---|---|---|---|
| No urgency signal | Visibility of system status | 4 | A stolen vehicle and a routine plate review carried identical weight, so emergencies surfaced late. |
| No bulk actions | Flexibility and efficiency of use | 4 | One fix per vehicle, repeated, even when the same fix applied to dozens. |
| No overview layer | Visibility of system status | 3 | Fleet health had to be reconstructed by hand from a flat table every shift. |
| No real filters | Recognition rather than recall | 3 | Isolating stolen, overdue, idle or unassigned vehicles meant scanning rather than filtering. |
| No synthesized insight | Recognition rather than recall | 3 | Correlations such as "these six idle trucks also expire this month" stayed invisible. |
| No navigation | Consistency and standards | 3 | No persistent shell, so orientation reset on every jump between areas. |
| No design system | Consistency and standards | 3 | The same status meant different things in different colours on different screens. |
| No assistant | Flexibility and efficiency of use | 2 | Every question required manual table work, even to reach an answer nobody could act on. |
Severity 4 means work stops or risk goes unseen. 3 means a major slowdown with a painful workaround. 2 means real but survivable friction.
Four rules, so nine modules built over time stay one product
-
Lead with the decision, not the data
Every surface opens with what needs doing, ranked. Raw data sits underneath it, never in front.
-
Wholesale by default
Any action that can sensibly apply to many vehicles applies to many by default. One vehicle is the special case.
-
An answer you cannot act on is a report
Anything that surfaces a problem carries the control that resolves it, in place.
-
One system, one vocabulary
A status, a colour and a control mean the same thing on every screen, from one token set and one component library.
Three modules, each one closing a severity 4 finding
The shift now starts with a ranked list instead of a table
The dashboard runs the fleet data through a set of rules and writes each finding as a sentence before anyone arrives. The three problems from that morning are the first three things on the page, in severity order, each carrying the control that resolves it.
One selection now covers twenty-three renewals
Filter, sort and selection state live in the URL, so a dashboard card hands the Vehicles table a pre-filtered, pre-selected batch. Four bulk flows cover every open issue type in the fleet: assign plate, change status, renew registration, and report or cancel a theft.
Answers arrive with the fix attached
Ask returns a structured card rather than prose, and the card carries the same bulk flow the Vehicles page uses. There is one renewal flow and one theft flow in the product, each reachable from two places, instead of a second implementation per surface that drifts.
What I chose not to build, and why
These four decisions shaped wave one as much as anything that shipped in it. Each traces back to a constraint rather than an oversight.
No automatic renewal filing
Filing without a human was the obvious efficiency play and the wrong one. Batching the human decision captured most of the time saving without moving the legal liability.
No language model behind Ask yet
The value in that module is the answer contract, typed cards that carry their own actions, not the parser in front of it. Keyword routing proved the contract cheaply and left the model swappable.
No configurable thresholds
Making idle days and renewal windows tunable would have shipped a settings screen instead of a decision, and there is no behavioural data to tune them against until wave one runs.
No shallow version of the other six modules
Nine modules at surface depth would have closed neither severity 4 finding. The remaining six now inherit a shell and component library that already exist.
The same morning, 89 minutes down to 9
Both tracks below cover the identical morning: triage the fleet, clear the 23 renewals due inside six weeks, deal with the two dark plates. The legacy track is reconstructed from its own workflow at roughly three minutes per record edit. The RFleet track is measured by walking the built product.
Scan 138 rows 10 min, renew 23 registrations one at a time 69 min, chase 2 dark plates 10 min
Never found: the 11 idle trucks. No column held "has not moved".
All three problems handled, including the one the old system could not show.
The metric that matters most: the cost stopped tracking the fleet size
Every minute of legacy compliance work was spent per vehicle, so the daily cost rose in a straight line with the fleet. In RFleet the expensive part is opening a batch, not the size of it. Reviewing one more vehicle inside an open batch takes about 12 seconds against roughly three minutes standalone, which is where the leverage comes from.
That changes the slope, not just the intercept. This is the difference between a faster tool and a tool that lets the company grow without hiring against it.
0.65 to 0.05 minutes of daily compliance work per vehicle.
Daily clerical load at 552 vehicles, projected from the same baseline.
The mechanism behind the slope change.
All 149 open issues map to one of four reusable flows.
Step counts per workflow, and how every figure here was derived
A step is one interaction: a click, a selection, a save. RFleet step counts are measured by walking the built product. Legacy counts are reconstructed from the legacy workflow.
Time figures apply roughly three minutes per manual record edit, conservative for a form based tool with no bulk actions. These are modelled figures rather than production telemetry, because the platform has no usage log yet. The ratios survive a different per edit estimate, since both sides move together.
Plate assignment is the row worth reading closely. Batching the selection saves most of the work, but each vehicle still needs its own plate chosen, so the reduction lands at 78 percent rather than the 97 the renewal flow reaches. Where a decision is genuinely per vehicle, the design does not pretend otherwise.
What is proven, what is modelled, and what is still open
Being precise about this is the difference between a case study that survives an interview and one that does not. The step counts are measured. The time and cost curve figures are modelled from those counts plus one stated assumption. Nothing here is production telemetry, because the platform has no usage log yet.
The walkthrough above is also mine, and I built the product, which makes me the worst available test subject. Nothing in wave one has been put in front of a fleet manager who has never seen it. That is the next thing to fix, and the protocol is written so its results compare directly against the legacy baseline.
- Step counts for all four workflows in the built product
- Issue coverage: four bulk flows against 149 open issues
- Detection: 3 of 3 morning problems surfaced, against 2 of 3 before
- Minutes per morning, from step counts at 3 minutes per edit
- The cost curve slope and the four times fleet projection
- Backlog clearance time at roughly ten grouped batches
- Task success rate with users who did not build the product
- Whether bulk actions cause recoverable mistakes in practice
- Registration lapse rate and vehicle days recovered in production
The usability protocol planned for wave one
| Task | Success criterion | Target |
|---|---|---|
| "Something needs your attention this morning. Handle it." | Finds the highest severity item unprompted and takes the resolving action | 90% unassisted, under 60s |
| "Clear every registration due in the next six weeks." | Uses a bulk flow rather than per-vehicle edits | 80% choose bulk, under 2 min |
| "A truck was stolen overnight. Report it." | Completes the report without entering the wrong status first | 95%, under 45s |
| "Which vehicles in Roseville have no plate assigned?" | Reaches the answer through filters or Ask rather than scanning | 85%, under 60s |
| "You reported the wrong truck stolen. Undo it." | Recovers without help. The guardrail task for bulk actions. | 90%, no data loss |
Moderated, six to eight fleet managers, think aloud, SEQ after each task and SUS at the end against a target of 80. If the recovery task does not test clean, the batching win is not real and wave two waits.
The number the program is accountable to in production
63 percent today, 87 vehicles of 138. It is the number the growth ceiling argument rests on, and the one that says whether compliance work is keeping trucks earning.
Leading indicators, lagging outcomes and guardrails
Leading
- Time from dashboard load to first resolving action
- Share of fixes performed through a bulk flow
- Median age of an open issue when resolved
- Ask sessions ending in an action rather than an answer
Lagging
- Registration lapse rate
- Mean time to report a stolen vehicle once known
- Vehicle days lost to preventable out of service status
- Open issue backlog size week over week
Guardrails
- Bulk actions reversed within ten minutes
- Theft reports cancelled shortly after filing
- Insight cards dismissed with no follow up
- Alert volume per manager per shift
What I would change next
Undo is the missing piece
Bulk actions make mistakes proportionally larger and the product has per item cancel rather than a real undo. That is the next build, and it is why recovery sits in the test protocol as a task rather than an assumption.
The insights are rules, not learning
The dashboard cards are hand written heuristics over live data. Right for a first wave because they stay legible and debuggable, but the thresholds inside them should be tuned against real behaviour rather than my judgement.
The map is doing less work than it could
It shares filter state with the table but does not support selection. A manager looking at a cluster of problems in one yard should be able to select it and run a bulk flow without going back to the list.
Waves two and three are visible in the product
The six unbuilt modules sit in the navigation in an inactive state rather than hidden, so anyone using wave one can see what is coming. Hiding them would have made the platform look finished and left users guessing about scope.
RFleet, Fleet Operations Platform. Wave one. Next.js 16, React 19, Tailwind CSS 4, shadcn/ui, react-leaflet