A patient books a therapy session. To do that, they hand over their name, their contact details, the fact that they are seeing a therapist at all, and often a short note about why. That last part — the reason for the appointment — is health-adjacent data, and in the EU it sits under a stricter regime than an email address or a shipping label. Most clinics run this through a booking widget hosted somewhere in another jurisdiction, a separate invoicing tool, a messaging app that was never designed for patient contact, and a spreadsheet to tie it together. Every one of those is a place the data lives, a company that processes it, and a line item on a records-of-processing document that nobody wants to write.

This article walks through building the alternative: a single self-hosted portal for a private clinic or an independent therapist, where appointments, intake, billing, and patient messaging run on infrastructure you control, in a data centre you choose. It is not a magic compliance button. It is an architecture that makes the compliance conversation shorter and more honest.

Why data residency matters more here

For an e-commerce store, the location of the server is mostly a latency and cost question. For anything touching health, it becomes a legal and trust question. Special-category data under GDPR Article 9 — which includes data concerning health — carries extra obligations, and every third-party service that touches it is a processor you must name, contract with, and account for.

The practical problem with the typical SaaS stack is not that any single vendor is careless. It is accumulation. A hosted booking service, a hosted invoicing service, a hosted analytics tag, and a consumer chat app each add a processor, a data-transfer question, and a sub-processor list you inherit but do not control. When a patient asks "who can see that I have an appointment on Thursday," the honest answer for many clinics is a list they have never fully assembled.

Self-hosting inverts that. The clinic runs the software; the clinic chooses the host. If that host is an EU provider, the data is EU-resident by construction, and the processor list shrinks to the ones you actually decided to use. That is the entire point of the exercise.

What you actually build

VBWD is a source-available, self-hosted platform — Python and Flask on the backend, PostgreSQL for storage, Vue 3 on the front end, packaged with Docker. It is built as an agnostic core with a plugin system: the core knows nothing about clinics, and the clinic-specific behaviour lives in plugins you enable. You can read how that separation is enforced on the architecture page, which matters here because it is the reason the same platform can be a shop, a membership site, or a clinic portal without forking it.

The fastest way to see the shape of it is to import the doctor/clinic demo instance. That gives you a running portal with the relevant plugins already wired together, so you are evaluating a real system rather than reading a feature list. From there, the pieces you assemble are:

Appointments. The booking plugin handles the calendar: available slots, practitioner assignment, a patient picking a time, and the confirmation flow around it. This is the front door of the portal and usually the first thing a clinic wants working.

Patient accounts and portals. Each patient gets an account and a portal view — their upcoming appointments, their history, their invoices — rather than a shared inbox where staff manually match emails to people. The account is the anchor that everything else attaches to.

Billing and invoicing. Sessions produce invoices. The billing and invoice layer generates them, tracks what is paid, and keeps the financial record next to the appointment record instead of in a separate tool that has its own copy of the patient list. You can see the broader billing and subscription capabilities on the features page.

Secure patient-provider messaging. The chat plugin gives patients and providers a channel to exchange messages inside the portal — rescheduling, a question before a session, a document — instead of pushing that conversation onto a consumer messaging app that was built for something else entirely. Read carefully on what this is and is not, below.

The full set of available plugins, including booking and chat, is listed on the plugins page. You enable what a given clinic needs and leave the rest off.

The GDPR-by-architecture angle

The interesting claim is not "VBWD is GDPR software." No software is. The claim is narrower and more defensible: the architecture removes several of the things that make GDPR compliance hard, so what remains is your own paperwork rather than a tangle of other people's systems.

Three properties do the work.

Data residency by deployment, not by promise. Because you host it, the data sits where you put it. Choose an EU host and EU residency is a fact about your deployment, not a checkbox in someone's dashboard that you have to trust. There is no separate booking cloud holding a second copy of the appointment book.

A short, explicit processor list. A self-hosted portal that does booking, accounts, billing, and messaging in one place collapses four or five processors down toward one or two — your host, and whatever payment provider you genuinely need for card settlement. A record of processing activities you can hold in your head is a record you can actually keep accurate.

The clinic is unambiguously the data controller. There is no ambiguity about who decides the purposes and means of processing, because you run the system. Granular role-based access control makes that concrete rather than notional. VBWD ships three distinct role systems, and for a clinic they map naturally: front-desk staff who manage the calendar and see contact details, practitioners who see clinical context for their own patients, and patients who see only their own record. "Who can see this appointment" stops being an awkward question and becomes a permission you configured. The mechanics of that RBAC model are documented in the docs.

None of this is exotic. It is the predictable consequence of running one system you control instead of stitching together several you don't.

Honest limits — read this part twice

A tool that touches health data attracts optimistic claims, so here is the deliberately unglamorous version.

This does not make you HIPAA-certified. VBWD is not HIPAA-certified, and running it does not certify you. HIPAA is a US framework; certification, where it is even a meaningful concept, is about your whole operation, not a piece of software. If a vendor tells you their software makes you HIPAA-compliant, that is a marketing sentence, not a legal one.

This is not a certified medical-records or EHR system. VBWD is a booking, billing, and portal platform. It is not a certified electronic health record, and it is not a clinical records system. If your jurisdiction has specific regulations governing how clinical records are stored, retained, or exported, meeting them is your responsibility and may require software built and certified for exactly that purpose.

The messenger is secure communication, not clinical tooling. The chat plugin is general secure messaging between a patient and a provider. It is not a telemedicine platform, not a clinical decision system, and not a substitute for whatever documentation your practice is required to keep. Treat it as a private channel, not a medical device.

The paperwork is still yours. Lawful basis for each processing purpose, a data protection impact assessment where one is required, retention schedules, staff training, patient-facing privacy information, and any sector-specific clinical-records rules — all of that remains the operator's job. The architecture makes several of these easier to reason about. It does not do them for you, and no honest description would say otherwise.

One more practical note on licensing, because it affects the business case. VBWD is source-available under BSL 1.1: free to use commercially while annual VBWD-attributable sales stay below the value of 6.7 BTC per year, with a commercial license required above that. It is emphatically not public-domain or CC0 — you get the source and broad free-use rights, not an abandonment of the licence. For a single clinic or a small practice, that ceiling is well above where you will operate, so in practice the platform is free to run.

Takeaway

If you run a private clinic, a therapy practice, or an agency that builds portals for one, the value here is not a feature you couldn't find elsewhere. Booking tools exist. Invoicing tools exist. The value is consolidation onto infrastructure you control, which turns a sprawling processor list and a vague data-residency story into a short, defensible one. You still own the DPIA, the retention policy, and the training. You just stop owning the problem of not knowing where your patients' data lives.

Start by importing the doctor/clinic demo instance and clicking through it as a front-desk user, then as a practitioner, then as a patient. The three different views are the fastest way to understand what the RBAC model buys you, and whether the honest limits above are limits you can live with. For most small practices, they are.

Next step: import the doctor/clinic demo instance and read the RBAC model in the docs before you decide — the three role views tell you more in ten minutes than any feature list.