One long form is why the device records were empty, so the record became tabs
A small desktop tool for cataloging equipment, where a device record is split into tabs so a partial entry is a normal state, never an abandoned form.
The shape of the work
Logistics & Distribution
5 weeks
Fixed price
Client name withheld under NDA. Engagement details are shown to the extent our agreement permits.
The record is tabs
Each tab saves on its own, so an entry finished over two visits is simply how it works.
The record is a set of tabs that each save independently, so an entry begun at a desk and finished beside the machine two days later is the normal path. Nothing waits on a form-wide submit, which means a lost connection, a closed window or an interruption costs at most the tab currently open.
- Each tab saves on its own; no form-wide submit
- An entry finished across two visits is the normal path
- An interruption costs at most the open tab
The specification tab, filled in when someone had the plate in front of them: dimensions, engine, hydraulics and undercarriage, beside a dimensioned drawing carrying the same length, wheelbase and height figures. It saved on its own; the readings tab is still not filled.
General is enough to create
Creating a device asks six questions and generates the asset code, with its check letter and how it reads over a phone. No serial is asked for, and the two remaining tabs are marked optional on the face of the dialog.
A device exists after one short tab. The detail gets added when someone is standing next to it.
The general tab is short enough to complete in a minute and enough on its own to create the device, so a machine exists in the catalog the moment anyone knows about it. Specification detail (plate readings, serials, ratings) is filled in later by whoever is standing next to it. A record with one tab complete is useful; the old all-or-nothing form produced no record at all.
- One short tab creates the device
- Detail added by whoever is standing next to the machine
- A partial record is a useful record
Identifiers are generated
Nobody invents a code, so nobody invents two different codes for the same machine.
Identifiers are generated, never typed, so nobody invents a code and nobody invents two different codes for the same machine. That had happened all over the old spreadsheet, where the same asset appeared three times under three conventions. Generated codes are stable, checkable and unambiguous when read aloud over the phone.
- Codes generated, never invented by an operator
- One machine can't acquire two identifiers
- Stable and unambiguous when read aloud
The forty-column spreadsheet brought over in one pass. Of 412 rows, 386 imported with generated codes; the 26 that couldn't are listed with the reason, split between a missing serial, an unrecognized yard and a machine already on the register.
The list is the landing screen, with search focused and matching code, model or yard. A completeness column shows, per row, how many of the record's three tabs are filled.
The list is the landing screen
Looking something up is the daily action; cataloging is the occasional one.
The application opens on the list, because looking something up happens daily and cataloging happens occasionally. Search is focused on launch and matches identifier, model and location, so the common case (someone with a machine in front of them and a question) is answered before any navigation happens.
- Opens on the list, with search already focused
- Matches identifier, model and location together
- The daily action is the landing screen
Desktop, deliberately
The office connection is unreliable, which makes local storage a requirement, not a shortcut.
Local storage on the desktop was a hard requirement: the office connection drops for hours, and a catalog that can't be read during an outage is a catalog nobody relies on. Records live on the machine and export deliberately, so the tool works exactly the same on a bad day as on a good one.
- Local storage because the office connection genuinely drops
- Readable during an outage, which is exactly when it's needed
- Export is a deliberate act, with no background sync
Offline since mid-morning, with the register still on the machine. Seven edits sit queued with the name against each one, nothing was blocked, and the export waits for someone to choose it.
What we were brought in to do
A plant-hire company needed a catalog of what they own, with enough detail to answer a customer's question. We built a small desktop application: sign in, a device list, and a record split across tabs.
A plant-hire company that needed a catalog of what they own, with enough detail to answer a customer's question on the phone. What they had was a forty-column spreadsheet in which most rows filled in six. The engagement ran five weeks, and the interesting constraint was that the missing detail wasn't missing through neglect.
Full-Stack Engineering
Where the old way broke
The spreadsheet they were using had forty columns, and most rows filled in six of them. A single long form has the same problem: someone starts it, reaches a section they can't answer without walking to the yard, and abandons the whole entry instead of saving what they have.
The detail lives on a plate on the machine, in a yard, and the person entering the record is at a desk. A single long form fails predictably: someone starts an entry, reaches a section they can't answer without walking outside, and abandons the whole thing. That's exactly how a forty-column sheet ends up six columns deep.
We split the record into tabs and let each one stand alone. General details are enough to create the device; the specification tab gets filled in when someone has the plate in front of them. A record with one tab complete is a useful record.
What we built together
- 01
Split the record into tabs so a partial entry is a normal state
Tabs were chosen after watching an entry abandoned at the specification section, which is where the person at the desk runs out of what they know.
- 02
Made the general tab alone sufficient to create a device
Cutting the create step to one tab took two passes. The first attempt still asked for a serial, which is the field that sends someone to the yard.
- 03
Kept it desktop, because the catalog is entered in an office with no reliable connection
The connection was measured over two weeks before this was decided. It dropped for more than an hour on nine of those days.
- 04
Generated identifiers, so nobody has to invent them
Identifiers are generated, so one machine can't pick up two codes under two conventions the way it had in the spreadsheet.
- 05
Kept the list the landing screen, since looking something up is the common action
The application opens on the list with search focused, because looking something up is the daily action and cataloging is the occasional one.
Phase by phase
Phase 1: The List
Looking Up Is The Common Case
Built the device list as the landing screen. Cataloging is occasional; answering "what's the lift capacity on the blue one?" is daily.
- Device List
- Search
- Selection
Phase 2: The Tabbed Record
Each Tab Stands Alone
Built the record as tabs (general details, specification, and the device's own readings), each savable on its own, so an entry can be finished across two visits.
- General Tab
- Specification Tab
- Per-Tab Saving
Phase 3: Creation
General Is Enough
Made creating a device require only the general tab, with identifiers generated automatically, so adding something takes under a minute.
- Add Device
- Generated Identifiers
- Validation
Phase 4: Desktop And Offline
The Office Has No Signal
Shipped it as a desktop application with local storage, because the office it's used in has a connection that comes and goes, and a web app would have been unusable there.
- Desktop Packaging
- Local Store
- Sign-In
The readings tab for a telehandler: hour meter, service interval and examination date, filled at the yard and saved on its own while the specification tab stays not filled yet.
Operational results after launch
3
Tabs per record
1
Tabs needed to create
0
Identifiers typed by hand
No
Connection required
Tabs per record and tabs needed to create are counts. Identifiers typed by hand is zero: codes are generated. Connection required is no, describing the operating model: records live on the machine and export deliberately.
Client name withheld under NDA. Figures are approximate, drawn from the engagement’s own reporting.
About our collaboration
The owner was blunt that his staff weren't the problem, and he was right. We designed for a record finished across two visits instead of hoping for better discipline, and the catalog filled up in two weeks.
Five weeks, fixed, with the tabbed record settled first, because the whole design follows from making a partial entry a legitimate state. Desktop and local storage were chosen for a stated reason: the office connection drops for hours, and a catalog that's unreadable during an outage is one nobody comes to rely on.
What we'd carry into the next one
A long form asks for everything at once, and the answer is usually nothing at all.
A long form asks for everything at the one moment the person can't supply it, and the honest answer to that demand turns out to be nothing at all.
Let a partial record be a legitimate record and people will create records.
Making a partial record legitimate is what produced records. The old sheet was six columns deep because a partial entry felt like a failed one.
Generate identifiers. Asking humans to invent them produces duplicates for the same object.
Human-invented identifiers produce duplicates for one object, which had already happened three times in the spreadsheet under three conventions.
An unreliable office connection is a real requirement, and it's often the honest reason to ship a desktop app.
An unreliable office connection is a genuine requirement, not an excuse, and it's often the honest reason a desktop application is the right shape.
A record with one tab filled is a record. An edit made offline is still an edit.
Follow a new backhoe from six questions to an exported record while the office is offline, and watch the edit queue and the record’s completeness change at each step. Pick a step, or use the arrow keys once one is focused.
Created. The General tab was enough.
No serial, no plate readings. Those are on the machine in the yard, and asking for them here is what used to stop an entry halfway.
Illustrative timing: each step is replayed at one field or one edit every 420 ms to show the order things happen in, not how long they take. The five edits already queued are the ones made that morning before this device.
From a saved tab to an export someone chose
Four of the five stages run on the office machine and need no connection. The connection was measured over two weeks before that was decided, and it dropped for more than an hour on nine of those days.
- 01 · SourceOne tab saved at the deskEach tab saves on its own with no form-wide submit, so an interruption costs at most the tab that's open.
- 02 · ValidationGeneral is enough to createOne short tab creates the device. The serial, the field that sends someone to the yard, isn't asked for.
- 03 · EngineIdentifier generatorCodes are generated and never typed, so one machine can't acquire two identifiers under two conventions.
- 04 · StateLocal store on the machineRecords live on the machine, so the register reads the same during an outage as on a good day.
- 05 · DeliveryDeliberate exportExport is a choice, with no background sync. Queued edits carry the name of whoever made them.
What a plant-hire office can't afford to lose
A register that survives a dropped connection, a phone call and an old spreadsheet
The line drops. The edits stay.
Records live on the office machine and each tab saves on its own, so a lost connection, a closed window or an interruption costs at most the tab that's open. Edits wait in a queue with a name against each one until someone chooses to export.
One machine, one code
Asset codes are generated, never typed, so nobody invents one and nobody invents two for the same machine, as had happened in the old spreadsheet with one asset under three conventions. Generated codes are stable, checkable and unambiguous read aloud.
The migration lists what it couldn't bring
The 40-column sheet came over in one pass. Of 412 rows, 386 imported as they stood, and the 26 that could not are listed with the reason (missing serial: 14, unrecognised yard: 7, already on the register: 5) rather than dropped.
Need an equipment register your team will still fill in when the office connection drops? Scope your build in 3 minutes.
Scope your buildNearby engagements
Data & AnalyticsWarehouse inventory that stays accurate on its own
An inventory automation layer that reconciles counts across warehouses, forecasts replenishment, and flags discrepancies before they become stockouts.
Warehousing & Fulfillment · 13 weeks
A freight portal that brings visibility to every mile
A real-time shipment visibility platform connecting carriers, shippers, and dispatchers with live tracking, geofence alerts, and automated status updates.
Freight & Trucking · 18 weeks
Web PlatformsAn order pipeline that scales for month-end and costs nothing at 2am
An event-driven serverless rebuild of a B2B order-processing pipeline: triggered per purchase order, scaling for month-end volume, and costing next to nothing overnight.
Logistics & Distribution · 10 weeks
Let's talk
Running a large platform, shaping a first MVP, or getting a product ready for a funding round? Tell us where you are. We'll shape the process around it, and stay with you after launch.














