In this article
Eighty per cent of this system was ready before the first line of medical logic was written. Login, roles, permissions, database, forms, notifications, audit trail, encryption of patient data, support for multiple entities — all out of the box. But the interesting part is what happened to the rest: the domain modules — patients, consultations, production — weren't built from scratch either.
The starting point: seven apps and one spreadsheet
The company had spent a year on seven low-code apps over a single database. What exactly we found there, and why migrating wasn't an admission of error, is described in our piece on the limits of internal tools. In short: one status described two different processes, medical data sat in plain text, the technician could see the patient's national ID, and production planning escaped into Excel anyway.
The new system was built on Open Mercato — an open platform where you build business modules instead of writing an application from the ground up. What follows is about how the work actually splits in an implementation like that: what is ready, what gets written, and where we deliberately rejected what the platform offers out of the box.
What we got from the platform
Four things you simply don't want to hand-write in a system holding medical data — and which are the most common source of quiet failures in systems built from scratch:
- 1
Accounts, roles and permissions
Centrally controlled: who sees what and who may change it. In the previous system, restrictions had to be written into every app separately — and forgetting in just one made the whole rule void.
- 2
Data encryption and key management
A per-field encryption layer together with key management. That's why GDPR was satisfied from day one, rather than „we'll add it later” — which in practice means never.
- 3
Audit trail, notifications, documents, dictionaries
Change history, notification delivery, consultation attachments and manageable dictionaries (orthosis types, materials, departments). We only had to switch them on and wire them to our own entities.
- 4
Multi-entity support
The system is ready for multiple branches or legal entities from the start — no need to anticipate it in the schema or bolt it on later when a second location appears.
That's the part that's easy to count in weeks of saved work. The second part is harder to count — and it shaped the pace of the implementation more than ready-made login ever did.
Domain modules from the same factories
The platform imposes one way of building every module: the same forms, the same lists, the same API, the same events, the same permission mechanism. A developer doesn't design „what a filtered list should look like” all over again — they fill a ready pattern with the client's business content.
5 modułów dziedzinowych zbudowanych wzorcami platformy: patients kartoteka z szyfrowaniem i wyszukiwaniem po PESEL consultations kreator 6 kroków: wywiad → pomiary L/P → specyfikacja → wycena production tablica etapów warsztatu (kanban) + historia przejść planning kalendarz technik × dzień × etap, z cofaniem zmian compression_garments osobna ścieżka wyrobów uciskowych Komunikacja między modułami: tylko przez identyfikatory i zdarzenia. consultations.confirmed → powstaje zlecenie produkcyjne production.stage_changed → odświeżenie tablicy i kalendarza production.delivered → konsultacja zamknięta
Modules don't call each other directly — they talk through identifiers and events. Confirming a consultation creates a production order, a stage change refreshes the board and the calendar, delivering the product closes the consultation. That way any module can be changed or replaced without taking its neighbours apart — exactly what the previous setup lacked, where every app enforced the rules on its own.
Why we didn't use the ready-made sales modules
This question always comes up, so here's the direct answer. The platform ships with customers, quotes and sales orders. The mapping looks tempting: a patient is a person, a consultation is a quote, production is order fulfilment. We deliberately passed on it — because the core implements the retail flavour of those concepts, and the company needed the clinical-workshop flavour.
- A patient is not a CRM customer. The customers module is built around deals, pipelines and sales interactions. A patient has a national ID looked up by an encrypted value, health data (GDPR art. 9) and hard access control — the technician sees initials and a specification, not a record card. Our own module gave us full control over the encryption map and a UI without sales sections.
- A consultation is not a quote. A quote needs lines pointing at catalogue products, pricing through the sales engine and a rigid status cycle. A consultation is ninety per cent a medical document: about forty measurements per side, a medical history, a layer specification. The price is two manually entered amounts. Forcing that into a quote would mean fake catalogue products and a fight with the pricing engine.
- A production order is not a sales order. A sales order is a commercial document: lines, payments, shipments. A workshop order is an execution document: stages with roll-backs, assigned technicians, fittings. Two different things that happen to have similar names.
The orthosis types, on the other hand, did become catalogue products — because there the mapping holds: each type has a base price and parameters, so the consultation wizard can compute a price and let it be corrected by hand. The clinical specification of a particular piece (measurements, layers) stays with the consultation. The product is a type definition, not a variant configurator.
GDPR from day one, not „we'll add it later”
Health data is a special category under GDPR — it requires encryption at rest. In the previous system, national IDs, medical histories and addresses sat in plain text. Not through negligence: in low-code there simply is no place where such a layer could sit. In the new system, encryption had to be live before we imported a single record — the order is non-negotiable, because data let in unencrypted stays that way in the database.
Encrypting data does break search, though: you can't run an ordinary query against an encrypted column. So alongside the encrypted fields there are fingerprint columns (national ID, e-mail, surname) that let you find a patient without revealing the value. On top of that, four roles, each seeing a different slice:
- Administrator — full access.
- Coordinator — patients, consultations, production and planning, but without the medical history.
- Orthotist — patients and consultations including the medical history, fittings, planning read-only.
- Technician — their own orders only, with no patient personal data: initials and the specification.
The key difference from the previous state isn't that „we added permissions”. It's that there is one set of permissions, in one place, rather than repeated across seven apps — so they can't be bypassed with a query on the side.
Undo as a first-class feature
One thing came out of the conversations with the coordinator that was on nobody's requirements list: what she missed most was undo. In the previous system every status change and every assignment was irreversible and anonymous, and the multi-step form could lose data on a page reload. The team learned to live with it — the worst possible symptom, because it means they stopped reporting.
So in the planning calendar every save goes through an operation that can be undone: a keyboard shortcut, a toast with an „Undo” button, a change-history panel. And the consultation form is a wizard that saves a draft from the first step, so a reload deletes nothing. Both decisions answer a specific human frustration, not a line in a specification.
The technician doesn't use a desktop
The last piece is a tablet app for the workshop technicians. Nobody at a workbench is going to log into an office panel: the technician picks up a tablet, looks at their own orders, moves a stage along and adds a note from the floor. It's a separate view, not a separate system — same database, same permissions, same audit trail.
And what mattered for the pace of the implementation: the API behind that tablet was also built on the platform's patterns, not as a separate integration layer. The side effect we didn't plan for turned out to be the most valuable one for further development: every module looks and behaves the same, so a new developer gets up to speed in hours, not weeks.
Fewer decisions from scratch
If this system were written from the ground up, each of these things would be a separate decision: how to do roles, how to encrypt, how to record change history, what a list looks like, what the events are called. Every one of them is a chance to get it wrong — and in a system carrying a child's national ID and medical history, getting it wrong doesn't end with an ugly screen.
- 1
A platform rather than a framework
A framework speeds up writing code. A platform removes decisions: the foundation (accounts, roles, audit, encryption) and the way further modules are built are already settled.
- 2
Ready-made modules only where the meaning matches
The product catalogue fitted orthosis types; the customers module did not fit patients. Always take the patterns from the reference modules — but take the modules themselves only when you don't have to work around their logic.
- 3
Discovery costs more than the code
Recognising the process took longer than implementing the first modules. For a year in a low-code tool nobody had to name that process — and that convenience comes back with interest at moving time.
If you want to understand the platform itself, start with the introduction to Open Mercato. If instead you're wondering whether your internal tool is still enough, we have a separate piece with the numbers.
Mateusz Kozłowski
Founder of flowbiz · Process automation expert
I implement automations, integrations and AI in mid-sized companies across Pomerania and Kuyavia-Pomerania.



