
To był system dla sieci placówek medycznych: rejestracja, karta pacjenta, wizyty online i stacjonarne oraz pełna integracja z e-zdrowiem — P1, ZUS i NIL. Pokazujemy, jak wyglądało to od środka: od odcięcia systemu od zewnętrznej platformy, przez własny model danych, po kilkutygodniową walkę z e-ZLA.
Projekt objął około 150 placówek, blisko 100 gabinetów i 40 lekarzy. W Jira zamknęliśmy 457 zadań, a całość zajęła około półtora roku — z czego sama faza deweloperska to blisko rok, a projekt UX/UI 3–4 miesiące. To nie był zwykły „system do rejestracji": najtrudniejsze okazały się integracje z systemami państwowymi, gdzie o wyniku decydują detale specyfikacji i obsługa błędów.
Ten materiał opisuje integracje z systemami państwowymi — P1, ZUS i NIL — oraz to, co wyszło przy nich z pola. Jeśli szukasz raczej tego, jak wcześniej przebudowaliśmy fundament i uniezależniliśmy system od zewnętrznej platformy, opisaliśmy to osobno: migracja i budowa własnego modelu danych.
Na starcie system nie był samodzielny. Obsługa rejestracji i pracy gabinetu opierała się na zewnętrznej platformie — to z niej pobierane były dane o lekarzach, dostępności, wizytach i terminach. Wyszukiwarka, kalendarz, panel administratora i raporty sięgały do cudzego źródła.
Największa niespodzianka siedziała w danych: usługi i gabinety identyfikowane były po identyfikatorach z tej zewnętrznej platformy, a nie po własnych rekordach. Dopóki tak było, każda nowa funkcja — recepta, zwolnienie, zdarzenie medyczne — musiałaby oglądać się na cudzy system. Pierwszą realną decyzją projektową było więc jedno: przenieść logikę do siebie. Rozłożyliśmy to na osobny wątek — odcięcie od zewnętrznej platformy i budowa własnego modelu danych.
Zbudowaliśmy własny model danych: tabele i panel do zarządzania placówkami, gabinetami i usługami lekarza (dodawanie, edycja, usuwanie), z przeniesionymi statusami wizyt. Wyszukiwarka lekarzy, kalendarz i zamawianie wizyty zaczęły czytać z naszych tabel, nie z zewnętrznego portalu. Usługa może być przypisana do konkretnego gabinetu i oznaczona jako online albo stacjonarna.
Rezultat tej warstwy: lekarz zarządza swoimi placówkami, gabinetami i usługami w panelu systemu — bez zależności od zewnętrznej platformy. To był warunek, żeby cokolwiek dołożyć nad spodem.
Na tym rdzeniu stanęły moduły, które składają się na codzienną pracę placówki: Grafik (dostępność lekarzy i przydzielanie pacjentów do terminów), Gabinet (placówki, gabinety, usługi), Karty — osobno karta wizyty i karta pacjenta — oraz obsługa lekarza w trybie online i stacjonarnym. Grafik okazał się przy tym mniej oczywisty, niż wygląda: dostępność to nie jeden kalendarz, tylko krzyżówka lekarza, gabinetu i usługi, gdzie każda z tych trzech rzeczy może zniknąć niezależnie od pozostałych.
Na tym fundamencie dołożyliśmy integracje z trzema systemami e-zdrowia. Każdy wymaga osobnej umowy lub wniosku, testu technicznego i — co istotne — umowy na podmiot leczniczy, a nie na firmę IT:
Całość spięliśmy podpisem w standardzie WS-Security, z certyfikatem przypisanym do konkretnego lekarza, na infrastrukturze spełniającej twarde wymogi: stały publiczny adres IP (białe listy CeZ, ZUS i NIL), szyfrowanie bazy i dysków, logi dostępu, kopie zapasowe dokumentacji trzymane zgodnie z wymaganym okresem, hosting w Unii Europejskiej i DPIA. To warstwa, którą widać dopiero wtedy, gdy jej zabraknie.
O integracjach łatwo napisać w jednym zdaniu — „spięliśmy z ZUS". W praktyce e-ZLA zajęło około trzech tygodni ponad plan, a najwięcej pracy poszło nie w samo wysłanie dokumentu, lecz w obsługę tego, co dzieje się, gdy coś jest nie tak. Kilka przykładów wprost z backlogu:
Lekarz mógł wystawić zwolnienie i je anulować — ale przy anulowaniu wyszły dwa realne problemy. Opisy przyczyn anulowania w naszym portalu nie zgadzały się co do słowa ze słownikiem ZUS PUE, przez co dokument bywał odrzucany. Drugi: anulowanie docierało do ZUS jako dokument bez danych. Rozwiązaniem było pobieranie najnowszego słownika powodów anulowania wprost z ZUS i pokazywanie aktualnych wartości w oknie anulowania — zamiast trzymać własną kopię, która po cichu się rozjeżdża.
Rzecz z pozoru błaha, a będąca sednem wygody: po wpisaniu PESEL-u pacjenta system pobiera z ZUS PUE NIP i nazwę płatnika. Pacjent może mieć kilku pracodawców — wtedy lekarz zaznacza checkboxem, komu wysłać zwolnienie, zamiast przepisywać NIP-y z pamięci. Dane pacjenta (PESEL, adres) zaciągają się z karty pacjenta.
Dołożyliśmy też sygnał, którego brakuje w wielu systemach: jeśli płatnik nie ma aktywnego profilu PUE, ZUS — zgodnie ze swoimi regułami — nie dostarczy mu zwolnienia elektronicznie, więc pokazujemy informację, że trzeba wydrukować kopię e-ZLA i przekazać ją pacjentowi.
„Zwolnienie po ustaniu zatrudnienia" to nie kosmetyczny checkbox — to osobny przypadek, gdy pacjent zakończył pracę, ale wciąż jest na zwolnieniu rozpoczętym w trakcie zatrudnienia; wtedy — zgodnie z regułami ZUS — dokument idzie tylko do ZUS, nie do płatnika. Uzasadnienie zwolnienia wstecznego pokazujemy dopiero wtedy, gdy w kalendarzu faktycznie cofniemy okres o więcej niż trzy dni. A miejsce wystawienia — przy lekarzu pracującym w kilku placówkach — daje się wybrać na formularzu, zamiast być zaszyte na sztywno. Z formularza wyrzuciliśmy pola, które w praktyce nie były używane, i ułożyliśmy go pionowo, w kolejności realnej pracy lekarza.
Osobno naprawiliśmy drobiazg, który potrafi zepsuć wrażenie z całości: przy druku zwolnienia lub recepty z poziomu wizyty na koncie pacjenta pojawiał się komunikat „Brak uprawnień". Dziś pacjent bez przeszkód wydrukuje własne ZLA, recepty i skierowania.
W projekcie medycznym bezpieczeństwo nie jest ostatnim etapem „do domknięcia przed odbiorem". To osobna warstwa, która rośnie równolegle z funkcjami — i w naszym backlogu miała własne, ponumerowane miejsce obok integracji:
| Zadanie | Co obejmowało |
|---|---|
| Szyfrowanie | dane pacjenta w bazie i na dyskach |
| Logi | rejestr dostępu do dokumentacji — kto, kiedy, do czego |
| CSRF | ochrona formularzy w panelu lekarza i pacjenta |
| Podpis elektroniczny | standaryzacja WS-Security, certyfikat per lekarz |
| RODO / DPIA | polityka bezpieczeństwa i ocena skutków — dokument dla klienta |
Do tego doszła dwuetapowa autoryzacja dla kont lekarzy oraz Consent Mode po stronie części publicznej. Osobno pilnowaliśmy retencji, bo w medycynie ona nie jest umowna: dokumentację trzeba przechowywać przez min. 20 lat, a logi dostępu przez min. 5 lat. To wprost przekłada się na architekturę backupów i koszt utrzymania — a także na wybór hostingu, który musi zostać w UE.
Najbardziej niedoceniany detal całej tej warstwy to konwersja certyfikatu z p12 do pem. Brzmi jak przypis, a jest warunkiem, żeby podpis w ogóle zadziałał w komunikacji z usługami państwowymi — obok osobnego certyfikatu TLS do portalu integratorów. Więcej rozkładamy w tekście o bezpieczeństwie systemu medycznego.
To jest część, która zaskakuje najczęściej — bo nie jest o programowaniu. Zanim system wyśle pierwszą e-receptę, muszą zadziać się rzeczy, na które firma IT nie ma wpływu i których nie da się przyspieszyć pieniędzmi:
Praktyczny wniosek z tego wdrożenia: formalności zaczynaj równolegle z projektem, nie po nim. Kod bywa gotowy szybciej niż papier, a wtedy gotowy system czeka bezczynnie na wniosek. Rozkładamy to szerzej przy integracji z P1 i w tekście o tym, ile trwa wdrożenie systemu dla przychodni.
System działa jako samodzielny produkt: lekarz prowadzi placówki, gabinety, usługi, wizyty, karty pacjenta i dokumentację po naszej stronie, a dokumenty e-zdrowia trafiają tam, gdzie trafić powinny. Świadomie nie podajemy tu wskaźników procentowych — projekt nie mierzył ich w sposób, który moglibyśmy uczciwie zacytować. Dowodem jest skala i zakres: ~150 placówek, 457 zamkniętych zadań, trzy działające integracje państwowe.
Sam „happy path" — wyślij dokument — to ułamek pracy. Wartość powstaje tam, gdzie ZUS albo P1 odpowiada błędem: w kolejce, ponowieniach i widoczności tego, co się nie udało.
Trzy tygodnie obsunięcia na e-ZLA nie wzięły się z trudnego programowania, tylko z zawiłej specyfikacji i testów zgodności szablonu XML.
Dopóki usługi i gabinety były opisane cudzymi identyfikatorami, każda funkcja była zakładnikiem zewnętrznego systemu. Przeniesienie tego do siebie było warunkiem wszystkiego, co przyszło potem.
Projekt zamknęliśmy tak, jak uważamy, że powinno się zamykać każde wdrożenie dedykowane: protokolarnym przekazaniem kodu zlecającemu, po wcześniejszej refaktoryzacji. Klient nie jest zakładnikiem wykonawcy — dostaje to, za co zapłacił, w stanie, w którym może z tym pójść dalej. Warto o to zapytać każdą firmę, z którą rozmawiasz o systemie medycznym, zanim podpiszesz umowę.
Najwięcej nauczyły nas nie te dni, gdy wszystko działało, tylko te, gdy ZUS odsyłał pusty dokument albo błąd walidacji. Dobry system medyczny poznaje się po tym, jak zachowuje się właśnie w takich momentach.
Planujesz system dla placówki albo sieci gabinetów — z integracją P1, ZUS lub NIL? Chętnie podpowiemy, od czego zacząć i gdzie są największe pułapki. Umów bezpłatną konsultację albo zobacz ofertę systemów dla medycyny.