Client & Project Snapshot
| Industry | Commercial refrigeration & HVAC-R field service (multi-branch, fleet-based) |
|---|---|
| Engagement type | Custom mobile web application plus legacy system integration |
| Core constraint | Existing FSM platform could not be replaced, migrated, or exposed via API |
| ACT360’s role | Design, build, test, and integrate a companion inventory system |
| Systems involved | Client’s existing internal platform plus incumbent field service management (FSM) software |
| Author | Jeffrey Bowles, Partner & Director of IT Services, ACT360 |
The Problem: An FSM Platform That Couldn’t See Inventory
The client’s field service management platform is the system of record for work orders, customer history, vendor orders, and job costing, and it does that job well. What it doesn’t do is track inventory anywhere below the company level. It has no concept of a truck, a job site, or a warehouse station as a place stock can sit. It doesn’t track serialized parts as individual units. And it has no workflow built for a technician standing on a roof or under a compressor.
So the business ran on a workaround. Technicians used parts on jobs, and someone re-entered them into work orders later, from memory or from a scrap of paper, at the end of the day. Every re-entry was a chance for a part to get forgotten. And a forgotten part is a part that never gets billed.
Why This Mattered
Unbilled materials directly reduced margin, and the gap recurred every day, across every technician, growing as the fleet grew.
Nobody could answer a simple question: what’s on that truck right now. Stock was tracked at the company level, not the truck level.
High-value serialized components, like compressors, were counted the same way as a box of screws. There was no chain of custody for the parts that actually mattered.
The constraint that shaped the entire project: replacing the FSM platform was never on the table. It’s embedded in customer records, scheduling, and financial reporting. The job was to close the gap without touching the foundation the business runs on.
The Real Complexity Wasn’t the App, It Was the Bridge
Most of the difficulty in this project had nothing to do with building an inventory app. Bulk parts and serialized parts, multiple technicians drawing from the same truck at once, a location model that matches how the business actually operates: those are solvable problems.
The harder problem was that the FSM platform exposes no public API. The only way in or out is a human logging into a web interface, or a spreadsheet import and export. Any automated connection between the two systems had to be built on top of an interface that was never designed to be automated, and it had to write correctly to the platform the client invoices from, every time, with no exceptions.
The two systems disagreed on what a “part” even is. Reconciling that was framed as a business decision for the client to make, not something ACT360 assumed on their behalf.
Existing inventory data used location names based on truck license plates, included decommissioned locations, and carried no category or serial data to migrate from.
A browser automation defect doesn’t throw an error the way a failed API call does. It writes silently wrong data into the platform the client bills from.
How ACT360 Approached It
Every technical decision below exists to reduce one specific business risk. None of them were made for their own sake.
Decision
Business Risk It Removes
All inventory movement flows through one code path, wrapped in database transactions with row-level locking
Stops stock from going negative and prevents two technicians corrupting the same balance at once
Every movement is recorded on an append-only ledger
Gives the client a defensible audit trail for job-costing disputes and monthly counts
Bulk and serialized parts are modelled separately
Lets a specific compressor be traced from purchase to the job it was installed on
The FSM platform stays the system of record for work orders
No duplicated workflow, no second source of truth on jobs
The sync layer runs in dry-run mode by default, with retry limits and a monitored failure queue
The client could validate the entire pipeline against their live system before a single record was written for real
The integration is isolated behind a job queue rather than woven into the app
When the FSM vendor eventually ships an API, ACT360 swaps the bridge without touching the inventory logic underneath
What Changed
The clearest result is what stopped happening: the daily habit of re-entering used parts into work orders from memory, which had been the single largest source of unbilled materials.
Truck-, station-, and job-site-level stock visibility that didn’t exist in any system before this project.
A complete, traceable history for serialized components, from purchase through to the job they were installed on.
An audit trail for every inventory movement, tied to a named technician and a timestamp, that can’t be edited after the fact.
Negative stock, partial writes, and two-technicians-at-once conflicts are now prevented at the database level, rather than caught during review.
Integration risk stayed contained through dry-run defaults, retry limits, and a monitored failure queue. There was never a silent gap between the two systems.
These outcomes are described directionally. Baseline metrics on time spent re-entering parts, or on the dollar value of previously unbilled materials, weren’t captured before the project began, so we’re not going to invent a percentage or a dollar figure to make the story tidier. What we can say plainly is that the manual step is gone, and the risk it created went with it.
The Bigger Picture
The client kept the FSM investment they already had and removed its worst operational limitation. There was no migration, no retraining anyone on scheduling or customer workflows, and no disruption to financial reporting.
More importantly, ownership of the inventory model moved to a system the client can actually change. Category structures, unit types, and reporting now live in code built for this specific business, instead of being limited to whatever a third-party vendor decided to support. And because the FSM vendor’s identifiers are already stored against every record, the day that vendor ships a real API, the bridge gets replaced. Not the app, and not the years of inventory history sitting underneath it.
Jeffrey’s Take
When a core system can’t be replaced but can’t do the job either, the instinct is usually to either fight it or rip it out. Neither is the right move. The better one is to build the missing piece alongside it, be explicit about where the old system’s authority ends, and treat the bridge between the two as something disposable by design.
The engineering discipline that mattered most here wasn’t the feature list. It was insisting that inventory could only ever change through one audited path, and that anything touching the live system stayed in dry-run mode until the client said otherwise. That’s what makes a system trustworthy enough to invoice from.