HU.b runs fleet operations at Hartselle Utilities — vendor invoices, preventive maintenance, purchase approvals, parts inventory, and shop scheduling in one place. I designed the data model, built the backend, and shipped it to six kinds of user who each needed something different from it.
Each of these was a real process before it was a feature.
Typed by hand, fifteen to twenty minutes each, and the cost never reached the truck.
Now the PDF goes in and comes back as structured line items, with parts and labor separated and each one tied to the repair task it belongs to. A person still verifies it before signing, because I'd rather a tech catch a wrong part number than have the system quietly book it.
Schedules lived on paper. Nobody could say what was due without walking the yard.
Each schedule fires on whichever comes first, a calendar interval or a meter threshold, so equipment that works hard gets serviced sooner and equipment that sits doesn't get over-serviced. When an operator reports something a PM already planned to fix, the two resolve into one work order instead of two.
The fuel card report arrived monthly as hundreds of rows tied to nothing.
The import matches each transaction to a unit and a driver, then checks the odometer against the last known reading. Readings that run backward or jump too far get held for review instead of quietly corrupting the fuel numbers.
Paper requests, and a $50 part followed the same approval path as a $50,000 one.
Approvals route by dollar amount, with signatures captured in the app and the PDF generated on the way out. Revising an approved request sends it back for re-approval, which was the point — the audit trail has to survive someone changing their mind.
No schedule. Work got picked up roughly in the order it was remembered.
The week is a board of two-hour blocks you drag work onto. When a critical repair lands, lower-priority jobs cascade to later days on their own, except the ones locked to a hard deadline.
What a vendor said on the phone lived in somebody's memory until it didn't.
Call summaries get pasted in and matched against open requests, jobs, and equipment, with suggested follow-ups an admin approves or discards. Nothing files itself — the suggestion is the useful part, not the automation.
Views from the live system. Click any image to enlarge it.
Nobody types this number in. Equipment status flips when a repair order goes in progress, and this bar reads from that, so it's current as of the last wrench turn.
Open operator reports, parts below their minimum, and recall campaigns matched against VIN-decoded equipment. Every count is a live query.
Each line shows both triggers, the interval and the meter, so you can see why something came due. Create RO turns it into a scheduled work order with that unit's parts already attached.
Two-hour blocks, drag to schedule, and a backlog panel pulling from both unscheduled repairs and PMs without a work order yet. Usable on a phone in the bay.
This is what comes back before anyone edits it: task segments carrying the vendor's own complaint, cause, and correction text, plus typed line items and part numbers. Verification is a read, not a re-type.
One record per asset: decoded specs and assigned operator up top, then tabs for repairs, parts, inspections, PM schedules, and fuel history. Parts link to PM schedules, so a due service already knows what it needs and whether it's on the shelf.
The parts worth explaining are the tradeoffs, not the feature list.
I first tried serving every role from a single dashboard with permission flags. Operators spent their time scrolling past approvals they had no ability to act on. A dashboard per role is more surface area to maintain, but adoption went up because nobody has to work out which half of the screen belongs to them.
The invoice extraction is good enough that skipping review would be tempting. I didn't. Corrections get logged so I can see which vendor formats need attention, which means accuracy improves when I do that work — not on its own.
A job stays open until every invoice is signed, the purchase request has gone out, and all line items are accounted for. That friction is deliberate. The alternative is a closed job with a missing invoice, which is the exact failure the system exists to prevent.
The purchase timeline counts elapsed time between 7:00 AM and 3:30 PM on weekdays only. Calendar time made every weekend look like a bottleneck and hid the real ones.
Counts from the live application, not a roadmap.