DocumentationSupportCosta Rica · Contact
What the service is for

Replacing the system is not always the answer. Leaving it mute is not either.

The systems that carry clinical operations can rarely be switched off: they hold years of data, processes tied to them, live contracts and users who depend on them working tomorrow at seven. Yet they are increasingly asked to take part in exchanges they were never designed for: expose a result, report to an authority, feed a consolidated view, connect to a network. A FHIR layer resolves that tension by translating between what the system stores and what the ecosystem requires, without touching its database or its operation. Designed well, it buys years of headroom. Designed badly, it becomes the next legacy system: one more box nobody dares to touch.

Starting point

What you are actually starting from

«Legacy systems» says nothing. What defines the work is the real shape of the source and what you find once you open it.

The EHR database

Direct access to the clinical system's relational schema, almost always read-only and against a replica, so it does not compete with operations.

What you run into

Undocumented tables, fields reused for two different things, status flags only their author understands, and business rules that live in the application rather than the model.

HL7 v2 over MLLP

Admission, order and result messaging already flowing between systems, which can be used as a source instead of building a new extraction.

What you run into

Site-specific Z segments, optional fields used creatively, and the fact that a message describes an event, not the patient's current state.

Flat files and batches

CSV, fixed-width or XML the system already generates for reports or for other consumers, processed in batches.

What you run into

Fixed generation windows, partial or repeated deliveries, legacy character encodings, and no mechanism to tell what changed since the previous file.

SOAP services and proprietary APIs

Interfaces the vendor already exposes, built for one specific consumer and with a data model of their own.

What you run into

Granularity that does not match the FHIR resource, undocumented pagination and concurrency limits, and contract changes that arrive without notice.

PACS and DICOM

Imaging studies and reports, where the metadata lives in the equipment and the PACS before it reaches the clinical record.

What you run into

Patient identifiers different from the EHR's, reports as free text inside the study, and volumes that make materializing unworkable without clear criteria.

Spreadsheets and manual catalogs

The catalogs holding real processes together even though they live in no system: services, practitioners, code equivalences.

What you run into

No version control, no formal owner, and the truth spread across several copies that do not agree with each other.

Delivery modes

Translate on the fly or materialize: the decision that shapes everything else

It is the first architectural decision and the one that determines cost, latency and who feels an outage. It is almost never a pure choice.

On the fly

The layer translates each query against the source system, in the moment.

Materialized

Data is transformed and loaded into a FHIR repository that serves the queries.

Data freshness
On the flyAlways the source's current state. There is no staleness window to explain or to defend clinically.
MaterializedAs fresh as the last load cycle. That window has to be defined, communicated and confirmed as clinically acceptable.
Load on the source
On the flyEvery external query hits the system carrying clinical operations. A badly behaved consumer becomes a clinical incident.
MaterializedExtraction is scheduled in low-demand windows and external queries never touch the source.
Coupling to availability
On the flyIf the source goes down or into maintenance, the FHIR API goes with it: its maintenance window becomes yours.
MaterializedThe layer keeps answering while the source is stopped. Its downtime turns into older data, not a dead service.
Query and performance
On the flyEvery FHIR search must translate into a query the source can resolve quickly. What its schema does not index cannot be offered.
MaterializedIndexes follow the search parameters the guide requires, not however the source's schema was left fifteen years ago.
History and reprocessing
On the flyYou see what the source keeps. If it overwrites instead of versioning, the history does not exist and cannot be reconstructed.
MaterializedVersions can be kept one by one, and the full history reprocessed when the mapping changes or an error surfaces.
Writing back
On the flyWriting into the source means honoring its business rules and validations, which are hardly ever documented.
MaterializedWrites are accepted at the layer and propagated later, which forces you to resolve conflicts and declare which version wins.
Governing the copy
On the flyThere is no copy: nothing to decide about who owns the duplicate, how long it is kept or how it is deleted.
MaterializedThere is a copy of clinical data, with everything that entails: owner, retention, access control, audit and right to erasure.
Cost of operating
On the flyLittle infrastructure, but performance depends on a system you do not control and each new consumer changes the load profile.
MaterializedInfrastructure and operations of your own — storage, monitoring, reprocessing — in exchange for predictable behavior.

What actually gets used

Pure extremes are uncommon. Most layers that operate well are deliberate combinations of both.

  • Cache with a declared lifetime: translation happens on the fly, but the response is kept for a defined period documented to the consumer.
  • Event-based change capture: the source announces what changed — through messaging, triggers or CDC — and only that gets transformed.
  • Read on the fly, write deferred: queries go to the source while writes are queued and reconciled, which is where the conflicts live.
  • Partial materialization: only the domain that needs it — results, reports — is materialized, and the rest translates on the fly.
  • A separate index for what the source cannot resolve: searches its schema does not support are served from a structure of their own.
Methodology

How we build the layer

Six stages. The first decides what can be taken out of the source without risking clinical operations.

  1. 01

    Source analysis

    Before mapping anything, we work out what the system really stores and what can be extracted without endangering what already works.

    • Schema, interfaces and available access mechanisms
    • Data profiling and data quality
    • Operational windows and load limits
    • Business rules living in the application
  2. 02

    Model and mapping

    We decide which resource represents each data point, which profile applies and where every element comes from — including the ones the source does not have.

    • Element-by-element mapping
    • Terminologies and ConceptMaps for local codes
    • Identifier and reference strategy
    • What to do with missing data
  3. 03

    Layer design

    Delivery mode, scope per domain, security and the contract with consumers. This is where what is expensive to change later gets settled.

    • On the fly, materialized or hybrid
    • Authentication, authorization and audit
    • Target CapabilityStatement
    • Versioning and compatibility policy
  4. 04

    Build and transformation

    Transformations, exposure and error handling get implemented, with edge cases treated as part of the scope rather than as surprises.

    • Extraction and transformation pipelines
    • Endpoints and search parameters
    • Idempotency and retries
    • A record of what could not be transformed
  5. 05

    Conformance validation

    The layer is tested against the profiles it must meet, with valid examples and with examples that must be rejected.

    • Validation against the applicable guide
    • Search and pagination tests
    • Comparison against the source
    • Load testing in a real window
  6. 06

    Operation and observability

    A layer without monitoring fails silently and is discovered when someone complains about data that never arrived.

    • Latency, error and freshness metrics
    • Alerts on untransformed data
    • Traceability from source to resource
    • A procedure for when the source changes
Conformance

Actually FHIR, not JSON with FHIR names

The difference between a layer that survives a demo and one that holds up an ecosystem is in details that only surface when a third party tries to consume it.

Validation against profiles

The usual shortcut

The JSON is assembled by hand until it «looks right» and tested only against your own client.

What holds up

Every resource is validated against the applicable guide's profile, in continuous integration, with examples that must pass and examples that must fail.

An honest CapabilityStatement

The usual shortcut

A copied CapabilityStatement is published, declaring operations and searches nobody implemented.

What holds up

It declares exactly what the layer supports. A consumer should be able to plan their integration by reading it, not by discovering the hard way what works.

Searches that work

The usual shortcut

Two or three parameters are implemented and the rest are silently ignored, returning everything as if the filter did not exist.

What holds up

Declared parameters are implemented, or they are not declared. And pagination is tested with the source's real volumes, not with test data.

Identifiers, references and codes

The usual shortcut

Internal keys are used as if they were FHIR ids, resources the layer never exposes get referenced, and local codes are sent without saying where they come from.

What holds up

Every reference resolves or is declared logical, business identifiers travel in identifier with their system, and every code carries its own.

Errors you can debug

The usual shortcut

A generic 500 is returned on failure or, worse, a 200 carrying an incomplete resource.

What holds up

Errors come back as an OperationOutcome, with severity, code and a location that tells the consumer what to fix.

The data that does not exist

The usual shortcut

It gets filled with a default value, an invented date or a generic code so the resource will validate.

What holds up

What is absent is represented as absent. Where the guide requires the element, the mechanisms meant for unknown data are used and the gap is documented, rather than fabricating it.

Results

What your organization receives

The layer in operation, plus everything needed to consume it, audit it and evolve it without us.

The FHIR layer in operation

The service deployed, with its endpoints, its security and its configuration documented.

Documented mappings

Element-by-element correspondence between the source and the resources, with decisions recorded.

ConceptMaps and catalogs

Declared equivalences between local codes and the standard terminologies.

CapabilityStatement

What the layer actually supports: resources, operations and search parameters.

Validation suite

Valid examples, examples that must fail, and the tests that run on every change.

Monitoring and alerts

Latency, error and freshness metrics, with alerts on whatever could not be transformed.

Consumer guide

How to authenticate, what to search, what to expect and what limits the layer has.

Evolution path

What gets materialized next, which domains follow, and when to revisit the delivery mode.

Experience

FHIR layers in operation

FHIR infrastructure built over systems and platforms that already existed and kept running.

What the layer solvedReceiving and validating reports

First national FHIR server — EDUS/CCSS

Meddyg implemented and deployed to production the first FHIR server to receive reports of notifiable diseases, vaccines and laboratory results from EDUS/CCSS, later extended to other health providers.

What the layer solvedEntry point for regional reporting

AEFI receiving infrastructure

Part of the Meddyg team acted as a consultant on the design and implementation of the infrastructure that would receive regional AEFI reports, alongside the guide defining their format.

What the layer solvedThe standard over national transport

FHIR transactions over X-Road

Proofs of concept with Costa Rica's National Digital Government Agency to validate FHIR resource transactions over the national X-Road platform, as part of the country's functional interoperability demonstration.

What the layer solvedNon-repudiation at the exchange layer

Digitally signing FHIR resources — BCCR

Technical assistance so the Central Bank of Costa Rica's teams could enable signing of FHIR resources with the JAdES format inside GAUDI, its digital signature and sealing platform.

The cases above are FHIR infrastructure built over systems and platforms that were already running. The same method — source analysis, mapping, choice of delivery mode and conformance validation — is what we apply to a facade over a legacy EHR or departmental system.

Profile

Who is this service for?

They all share one constraint: the source system cannot be stopped or replaced within the timeframe in which they have to interoperate.

Hospitals with a legacy EHR

A clinical system that will not be replaced and is now being asked to expose data, report, or connect to a network.

Health software vendors

Products that must demonstrate FHIR capability to clients and tenders without rebuilding their database.

Laboratories and imaging centers

Results and reports that must reach multiple external receivers with the same structure and the same codes.

Public institutions

Mission-critical systems that must take part in a national ecosystem without opening their database or stopping operations.

Health information exchanges

Ecosystems onboarding participants whose systems do not speak the standard and that need a repeatable connection pattern.

Insurers

Exchange with providers whose systems expose formats of their own and evolve at their own pace.

Self-assessment

Do any of these sound familiar?

We are being asked for a FHIR API and our system has no API at all.
Replacing the EHR is off the table, but interoperating is not.
Every new integration ends up as a bespoke export.
We expose JSON we call FHIR and no validator accepts it.
We do not know whether to translate on the fly or load into a repository.
External queries hit the same database clinical operations run on.
When the source system goes down, everything we exposed goes with it.
Our vendor does not expose what we need and it is not on their roadmap.
A consumer flagged a badly mapped field and we could not tell since when.
We publish a CapabilityStatement that does not match what the API does.
We have no way of knowing which records failed to transform.
We need to connect to a national network and our data cannot leave the system.

If any of these describe your organization, a FHIR layer can solve the exchange without putting at risk what already works.

Is FHIR being asked of a system that does not speak it?

A well-designed layer lets today's systems take part in the ecosystem without touching their operation or mortgaging the modernization path.