The unit that matters is the workflow, not the interface
Most integration conversations happen at the level of the interface: system A sends to system B, here is the message specification, here is the mapping document. That framing is why so much integration work is invisible until it breaks. An interface tells you a message moved. It does not tell you whether the thing the organisation actually cared about happened.
A workflow is the larger unit. It starts when something occurs in a clinical or operational system, and it ends when every consequence of that event has been handled: validated, transformed, delivered, confirmed, and logged. We have written before about why that distinction matters architecturally in point-to-point integrations vs an orchestration layer. This piece is the view from inside a single flow.
WeHub Studio is built around that unit. What follows describes its parts in order, but the parts are generic: any integration platform worth the description has to answer the same questions somewhere.
The trigger: one entry point per flow
Every workflow has exactly one trigger. It is the entry point that starts a run the moment data arrives.
That constraint is deliberate and worth defending. A flow with several possible entry points is a flow whose behaviour depends on which door the data came through, and that is the class of integration nobody can reason about two years later. One trigger means one answer to the question of what started this run.
In practice the trigger is usually one of three things: a listener waiting on an inbound message stream, such as HL7 v2 over MLLP from a departmental system; a scheduled poll against a file drop or an API; or an inbound API call from another service. The transport differs, the principle does not.
Processors: the work that happens in flight
Processors transform and route data while it is moving. This is where the actual integration logic lives, and where the difference between a platform and a message router shows up.
The common operations are worth naming individually, because teams often assume some of them belong elsewhere:
- Validate. Check the message against a structural definition and, where relevant, a profile. A message that fails here should never reach a live system.
- Map. Convert between representations, most often HL7 v2 to FHIR or the reverse. If the standards themselves are unfamiliar, NHS integration standards, mapped covers how they relate.
- Enrich. Add what the message did not carry: a resolved identifier, a mapped code, a lookup against a reference source.
- Route. Decide, on the content of the message, where it goes and what happens next.
Data modelling sits underneath all four. Reusable, versioned models that validate inputs and outputs mean the same definition is enforced everywhere it is used, rather than re-implemented per interface.
The temptation in a constrained estate is to push this logic back into the endpoints: let the receiving system cope with the variation, let the sending system do the mapping. That works until either system changes, at which point the logic has to be found in a place nobody documented.
Integrations: reading from and writing to real systems
Integrations are the plugins that read from and write to external systems. They are the least interesting part conceptually and the part that consumes the most time in practice, because real systems are inconsistent in real ways: partial acknowledgements, rate limits, undocumented required fields, error codes that mean something other than what they say.
The property worth insisting on is that delivery behaviour is configured rather than coded. Retry on a server error, a defined number of attempts, a defined action when attempts are exhausted. When that behaviour is a setting rather than a code path, you can change it in response to what a downstream system actually does, instead of raising a change request against your own integration.
The test run, which is the part that changes how teams work
This is the stage that alters how integration teams operate, and it is the one most often missing.
Before anything is live, you send a sample payload through the workflow and check the output of every node: succeeded, failed or skipped, with the actual data at each step. Not a unit test of a mapping function. The whole flow, with a real message shape, showing what each stage did to it.
The effect is that integration stops being a deployment and becomes an edit. A mapping question that would otherwise be answered by a specification, a build, a release and a regression test gets answered in a few minutes by running a message through and looking at the output. That is the difference between a change latency measured in quarters and one measured in days, which is the measure we argue matters most in the hidden cost of keeping a legacy PAS alive.
Publishing, versioning and what happens after go live
When a flow is ready it is promoted to a published version. One version is live at a time.
That single constraint removes a familiar category of incident: the one where two variants of the same integration are running, nobody is sure which is authoritative, and the behaviour depends on which instance picked up the message. Draft freely, publish deliberately, keep exactly one live.
After go live, three things matter and all three are the same requirement in different forms. Execution history, so every run of every workflow is on record. Failure diagnostics, so any failed run can be opened for its logs rather than reconstructed. Alerting, so the team that owns the pathway finds out from the platform rather than from a clinician. The whole workflow also exports as a file and imports elsewhere, which is what makes moving between environments a transfer rather than a rebuild.
Workflows can run on WeHub's environments or on your own infrastructure, depending on what the organisation's information governance requires.
A worked example: lab results into an EPR
Put together, a routine flow looks like this.
A laboratory system emits an ORU result message over MLLP. The trigger is a listener on that stream. The first processor validates the message structure and rejects anything malformed before it can travel further. The second maps it to a FHIR DiagnosticReport, with the coded elements resolved against governed terminology rather than passed through as free text. An integration writes the resulting resource to the EPR's FHIR API, retrying on a server error. A second integration posts a notification to the channel owned by the pathology team.
Before any of that ran against a live EPR, a sample result was sent through the same flow and the output of every node inspected. After go live, every run is on record, and a failure opens to its logs rather than to a question.
None of these steps is exotic. The point is that they are one configured artifact rather than five loosely related pieces of work, which is what makes the flow changeable six months later by someone who did not build it.



