
Before it became a standalone system for a network of around 150 facilities, its core did not belong to it. Booking, doctor availability and the work of the consulting room all rested on an external platform, and the data that described them lived under someone else’s identifiers. This is the story of cutting that dependency, stage by stage, without stopping the network.
This is one thread of a larger project. If you are looking for the e-health integration story, covering P1, ZUS and NIL plus the fight with electronic sick notes, we described it in the main case study: a medical system for a network of ~150 facilities. This page focuses on the foundation underneath it.
At the start, the system was not self-contained. The data that mattered, covering doctors, availability, visits and appointment slots, came from an external platform. Everything a user would consider "ours" reached into someone else’s source: the doctor search, the calendar, appointment booking, the admin panel and the reports.
For the owner of a clinic network this is convenient at the start and risky in the long run. Any change on the external platform, whether in the data, the API or the rules, could land on the reception desk the next morning. And every new feature we wanted to add had to ask someone else’s system for permission first.
The biggest surprise was not in the interface. It sat deep in the data. Services and consulting rooms were identified by identifiers from the external platform, not by records in our own database. In other words: this was not our data model. It was a shadow of someone else’s.
The consequence is heavier than it sounds. As long as a room or a service "exists" only as a number in a foreign system, you cannot safely build a prescription, a sick note, a patient record or a report on top of it, because everything refers back to meaning that somebody else defines. This is classic vendor lock-in at the data layer, not just in the contract.
So the first real design decision was not "let us add a feature". It was: bring the meaning in-house. Build our own tables for facilities, rooms and services, and only then put everything else on top of them.
Every feature asks a foreign system for the identity of our own data.
The identity of the data is ours. A new feature asks nobody for permission.
We planned the cut-off as a sequence of stages rather than one risky big switch. In the backlog this shows up as transition-stage tasks plus a separate cleanup of the old integration. The network ran the whole time, patients kept booking and doctors kept seeing them, so the migration had to happen under live traffic.
We built the tables and a panel to manage a doctor’s facilities, consulting rooms and services: add, edit, delete. A service can be assigned to a specific room and marked as online or on-site. We also carried over visit statuses so that nothing was lost while switching.
One by one we detached the parts a user sees every day from the external source and pointed them at our own tables:
The last stage was cleanup: refactoring the code, tidying the database and detaching the old API. It is a thankless phase, invisible in the interface, but without it the cut-off exists only on paper while a dependency still hangs in the code, waiting to speak up at the worst possible moment.
Result: doctors and administrators manage facilities, rooms, services and visits in the system’s own panel, with no dependency on the external platform. Only on that foundation could we add integrations with P1, ZUS and NIL, the patient record and the patient portal.
We deliberately do not quote percentage figures here. The project did not measure them in a way we could honestly cite. The proof is that a network of around 150 facilities now runs on its own core, and the meaning of its data belongs to it rather than to an external vendor.
As long as services and rooms were described by foreign identifiers, every feature was a hostage of the external system. Bringing the meaning in-house was the precondition for everything that came later. It is the first question worth asking in any medical data migration: whose identifiers are these, really.
A clinic network cannot "pause for a migration weekend". That is why a cut-off is done in stages, carrying visit statuses across, rather than with a single switch. The risk then spreads across small, controlled steps, and each one can be tested calmly before the next begins.
Detaching the old API and tidying the database is not a nice-to-have at the end. Skipped, it leaves a hidden dependency that undermines the whole point of the cut-off. We treat it as a full stage of the project.
The hardest part of the migration was never visible on screen. It was about making the data finally mean something inside our system, instead of being a shadow of someone else’s. Only then could we build further.
Is your medical system built on an external platform and you want to become independent, or are you planning one from scratch with its own data model? We are happy to point out where to start and where the biggest traps are. Book a free consultation or see our systems for healthcare.