Healthcare SaaS Compliance in Europe: EHDS, MDR, and What Engineers Must Actually Build

#healthcare SaaS compliance
Sandor Farkas - Founder & Lead Developer at Wolf-Tech

Sandor Farkas

Founder & Lead Developer

Expert in software development and legacy code optimization

Healthcare SaaS compliance in Europe has a reputation for being a lawyer's topic. It is not. Once you read past the recitals, the European Health Data Space regulation and the Medical Device Regulation are lists of things your engineering team has to build: data export in specific formats, access endpoints, audit trails with defined retention, and technical documentation that describes your architecture in a way a notified body can review. We covered the EHDS at a strategic level in an earlier post. This one goes into the specifics: what the regulations demand at the code and infrastructure level, and how we approach that work on a Symfony and PostgreSQL stack.

The usual disclaimer applies. None of this is legal advice, and classification decisions need a regulatory consultant. The engineering translation below is the part your counsel cannot give you.

What the EHDS expects your product to expose

The EHDS (Regulation 2025/327) entered into force in March 2025 and applies in stages, with most primary-use obligations landing from 2029 and some data categories following later. That sounds far away. It is not, because the obligations touch your data model, and data models are the slowest thing in any codebase to change.

Primary use means patients and clinicians accessing health data through national infrastructure. If your SaaS holds any of the priority categories, such as patient summaries, ePrescriptions, lab results, discharge reports, or medical imaging metadata, you will need to make that data available in the European electronic health record exchange format. In practice that means a reliable export path from your internal schema to structured FHIR resources, plus interfaces the national access services can consume.

Secondary use is the part most SaaS vendors underestimate. Health data holders can be required to make data available to Health Data Access Bodies for research and policy purposes. That implies anonymization or pseudonymization pipelines, a way to answer a data request without shipping your production database, and opt-out handling that survives an audit.

The engineering consequence is simple to state and expensive to ignore: if your canonical data model cannot be mapped to FHIR cleanly, every one of these obligations costs more. Fix the model first.

When your SaaS crosses into medical device territory

MDR classification is where ordinary product decisions quietly become regulatory events. Rule 11 of the MDR covers software: if your software provides information used to make diagnostic or therapeutic decisions, it is at least risk class IIa. It moves up to IIb if those decisions could cause a serious deterioration of health or a surgical intervention, and to class III if they could cause death or irreversible deterioration. The MDCG 2019-11 guidance document is the thing to read here; it is considerably more digestible than the regulation itself.

The line is easy to cross by accident. A dashboard that displays lab values is probably not a device. A feature that flags a value trend as a sign of deteriorating kidney function and suggests a referral almost certainly is. A risk score, a triage suggestion, a dosing calculator: any one of these can pull a module of your product into classification.

Class IIa is the tier that changes your engineering life. It triggers notified body involvement, clinical evaluation under Article 61, technical documentation per Annexes II and III, a quality management system (in practice ISO 13485), and post-market surveillance. For the codebase this means requirements traceability, a documented software lifecycle (IEC 62304 is the reference standard), risk management records, and change control that can prove why each release is safe.

The advice we give clients: draw the device boundary deliberately. Isolate the clinical-decision feature into its own module with its own release cycle and its own documentation, so the notified body reviews that module rather than your entire SaaS. This is an architecture decision, and retrofitting it later is painful. Our code quality consulting engagements in healthtech often start exactly here: assessing whether the current architecture can support a defensible device boundary at all.

The data standards you will not get around

Three standards families come up in nearly every European healthtech build.

HL7 FHIR R4 is the exchange format. The EHDS pushes it, national infrastructures assume it, and every integration partner will ask for it. Learn the resource types that map to your domain, typically Patient, Observation, Condition, MedicationRequest, and DiagnosticReport, and treat FHIR profiles as contracts rather than suggestions.

Coding systems give the data meaning. SNOMED CT for clinical terms, ICD-10 (ICD-10-GM in Germany) for diagnoses, LOINC for lab observations. SNOMED CT requires a license through the national release center, which surprises teams that assumed it was freely usable. Budget real time for terminology mapping; it moves slower than anyone expects.

DICOM covers imaging. If your product touches radiology at all, you need DICOM ingestion and probably DICOMweb endpoints, and imaging will dominate your storage planning from that day on.

Audit trails: MDR Annex II wants more than your GDPR log

Most SaaS teams already run some audit logging for GDPR accountability: who accessed which record, and when. MDR documentation asks for something different in shape and lifespan. Annex II requires technical documentation covering design information, verification and validation results, and risk management. For software, auditors read this as the ability to trace a released version back to its requirements, its test evidence, and its known anomalies.

So you end up with two audit systems. The GDPR-style access log is high volume, per request, retention limited, and queryable by data subject. The MDR-style record is per release, long lived, and links requirements to code to test results. Do not try to serve both from one table. We implement the access log as an append-only PostgreSQL table, partitioned by month and hash-chained where tamper evidence matters, and generate the release documentation from CI artifacts in the delivery pipeline.

Germany specifically: DiGA and the Telematikinfrastruktur

Germany adds two national layers on top of the EU rules.

DiGA is the reimbursement path for digital health applications. Getting listed through the BfArM fast track requires evidence of a positive care effect, but the engineering gate comes first: security requirements based on BSI technical guidelines, data protection certification, and interoperability requirements including structured data export. Teams routinely underestimate the security documentation. It assumes a maturity level, with penetration tests and working ISMS processes, that a seed-stage product rarely has on day one.

The Telematikinfrastruktur is the national health network. If your product needs to talk to the ePA electronic patient record, handle eRezept prescriptions, or exchange data with medical practices, you connect through Gematik-specified components. Treat this as a project of its own: certified connectors, card-based identity, conformance testing. Check early whether your hosting setup can even reach the TI, because the answer constrains your infrastructure choices. This is one of the reasons we run tech stack strategy work before a healthtech build rather than after it.

Storing FHIR in PostgreSQL, the Symfony way

The pattern we use is document storage inside the relational database. Each FHIR resource lives as JSONB in PostgreSQL, one row per resource version: an internal id, the resource type, the FHIR id, a version number, the JSONB payload, timestamps, and a handful of extracted columns for the fields you query constantly, such as the patient reference and the clinical code. A GIN index on the payload covers ad hoc queries; btree indexes on the extracted columns cover the hot paths. Never update a resource in place. Insert a new version row and track the current version separately. That gives you the version history FHIR expects and an audit-friendly record at the same time.

On the Symfony side, treat FHIR resources as documents, not Doctrine entities. Mapping deeply nested FHIR structures onto relational entities produces a schema nobody can maintain. We keep a thin repository layer that validates incoming resources against the relevant profiles, writes the JSONB rows, and publishes an event through Messenger so downstream consumers, from search indexing to the secondary-use pipeline, stay decoupled from ingestion. Symfony's serializer handles the API layer. API Platform works if you want a broader REST surface, though FHIR's own interaction model of read, search, and history is narrow enough that hand-rolled controllers stay perfectly manageable.

Two hard-earned notes. FHIR search parameters look simple and are not; implement only the ones your integration partners use, and write that list down. And keep your canonical business model separate from the FHIR representation. FHIR is an exchange format. Products that adopt raw FHIR resources as their internal domain model pay for it in every feature that does not look like a FHIR interaction.

Healthcare SaaS compliance is an architecture problem

Everything above rewards teams that decide early where data lives, where the device boundary sits, and which standards the core model must map to. Bolting FHIR export, MDR documentation, and TI connectivity onto a finished product is possible. We have done it. It also costs a multiple of what the same capabilities cost when they are designed in from the start, which is why healthtech is one of the areas where our custom software development practice insists on an architecture phase before anyone writes feature code.

If you want a second pair of eyes on your EHDS exposure, your MDR classification risk, or a FHIR storage design, write to hello@wolf-tech.io or have a look around wolf-tech.io. A one-hour conversation before the architecture freezes is the cheapest compliance measure you will ever buy.