2024–2025Backend, Integration
Engineering change management integration
Keeps a design vault, a process tool and an ERP in agreement about engineering changes — and raises a ticket naming the exact problem when they disagree.
- Role
- Design-data integration
- Timeframe
- 2024–2025
- Discipline
- Backend, Integration
The problem
At a manufacturer of large industrial equipment, a single engineering change had to land in three systems that did not talk to each other: the design vault holding CAD models and part revisions, the process tool where changes are reviewed and approved, and the ERP that tells the factory what to purchase and build. Keeping them aligned was manual work, and the failure mode was quiet — a part gets revised in the vault, the approval record still shows the old revision, and the factory keeps buying the previous version. Nobody notices until physical parts arrive that do not fit. The customer did not want another tool for people to learn; they wanted the systems they already had to stop contradicting each other.
The approach
A service that continuously reconciles the three sources. Each cycle it asks which changes are open, what the design vault actually holds for them, what the ERP believes, and whether those three stories match. Where they clearly agreed, it updated the records automatically. Where they conflicted — or where the underlying design data was incomplete or malformed — it deliberately changed nothing, and instead raised a task in the tool people already worked in, naming the specific problem. That reframed the product: not a sync job quietly making choices on your behalf, but a system that surfaces disagreement and hands it to a human. It is the reason the tool was trusted rather than switched off.
The network constraint
The design vault lived inside the factory's own network and was, correctly, unreachable from outside. Rather than opening it up, we inverted the direction of contact: the component inside the network reaches out to ask whether there is work for it, does the work locally against the vault, and posts the result back. Every connection originates inside the protected network; nothing ever calls in. It is a secure mailroom that admits no visitors but sends someone to the front desk every few minutes to check whether any mail has arrived. Work in progress was persisted on both sides, so a restart or a dropped connection lost nothing.
My contribution
I owned the design-vault side — everything from asking the vault a question through to handing the rest of the system data it can trust. Assembling a complete picture of one engineering change out of a legacy on-premise API meant chaining several dependent calls and stitching the results back together, tracking which piece of design data belonged to which change. The vault exposed its metadata as loose, untyped collections of named values that varied from file to file, so I designed and built the translation layer into the strict model the rest of the system needed — the point where messy external reality gets contained before it spreads. On top of that sat the validation rules deciding whether design data is fit to act on at all: is this identifier well-formed, is a required description present, is this a category we can actually handle. Each failure produced its own specific, human-readable task rather than a generic error, and a failing record was set aside and reported rather than aborting the run.
The contract
I also designed the boundary between my half of the system and my colleagues' half — and in particular the decision to separate “this data is wrong” from “this data is absent.” Those look nearly identical in code and mean completely different things to the business: the first means someone has to go and fix the source data, the second means something was genuinely deleted and the process record should change. Conflating them would have produced a steady stream of false alarms, and a tool that cries wolf gets switched off.
What I took away
The hard part was not the code, it was defining “correct.” Most of the real work went into drawing business rules out of people who knew the domain deeply but had never had to state them explicitly — every validation rule started as a conversation, not a ticket. The second lesson was that a tool which reports its own failures well is the one that gets adopted: routing exceptions into the customer's existing workflow, in their own vocabulary, mattered more than anything in the sync logic itself. And a process that sweeps every few seconds has to be safe to run when nothing has changed — no duplicate records, no repeated notifications — a constraint that touched nearly every decision on my side.
The outcome
Delivered, running in production, and signed off by the client. No before/after measurement was taken, so there is no number to quote here — what changed is that a class of error which used to surface as physical parts arriving on the factory floor now surfaces as a named task, the same day, in the tool the team already had open.
Built with
C# and .NET 8 on ASP.NET Core, Entity Framework Core over SQL Server and SQLite, hosted on Azure with managed identity and managed secret storage, containerised with Docker, logged through Serilog and tested with xUnit. REST integrations against all three third-party systems, including certificate-based mutual TLS to the ERP.