Case study
Ankiety dla pensjonatu
Aplikacja ankietowa dla recepcji pensjonatu. Bez backendu, offline, eksport do PDF.
Kontekst
Recepcja wypełniała wszystko na papierze. A ankieta gościa nie jest formalnością: to wywiad zdrowotny kwalifikuje masaż jako usługę leczniczą zwolnioną z VAT, więc kartkę trzeba wypełnić, przechowywać, odnaleźć i okazać. Zadaniem aplikacji była cyfryzacja tego procesu — nie zastąpienie dokumentu, tylko koniec z pisaniem go ręcznie.
Co zbudowałem
- Ekran startowy z wyborem rodzaju ankiety (masaż leczniczy / spa i zabiegi) i przełącznikami dostępności.
- Dwukrokowy formularz: dane klienta oraz wywiad zdrowotny z listą przeciwwskazań do zaznaczenia.
- Podgląd ankiety przed wydrukiem, identyczny z tym, co trafia do PDF-u.
- Generowanie PDF-u z oświadczeniem zdrowotnym zwolnionym z VAT, gotowego do archiwizacji.
- Eksport paczek ZIP z PDF-ami, plikiem CSV i backupem JSON do odtworzenia stanu aplikacji.
Sedno
Decyzje techniczne
Dlaczego aplikacja nie ma backendu?
Bo ankieta zawiera wywiad zdrowotny — zakrzepica, ciąża, choroby serca, choroba nowotworowa. To dane o zdrowiu, czyli szczególna kategoria danych osobowych z art. 9 RODO, obwarowana ostrzejszym reżimem niż zwykłe imię i nazwisko.
Brak serwera nie jest tu oszczędnością — jest sposobem na ominięcie całej tej klasy problemów. Ankiety zostają w IndexedDB przeglądarki recepcji, więc dane gości nigdy nie opuszczają urządzenia: nie ma bazy do wycieku, nie ma serwera do zabezpieczania, nie ma powierzenia przetwarzania. Przy okazji aplikacja działa, gdy w pensjonacie padnie internet, a hosting kosztuje zero, bo to pliki statyczne.
Dlaczego PWA, a nie aplikacja natywna?
Recepcja instaluje ją z przeglądarki, bez sklepu i bez konta developerskiego. Aktualizacja wchodzi od razu przy następnym otwarciu — nie czekam na moderację i nie proszę nikogo, żeby coś kliknął.
Dlaczego eksport to ZIP, a nie pojedynczy PDF?
Recepcja archiwizuje ankiety partiami, nie po jednej. Paczka zawiera PDF-y nazwane
nazwiskiem i datą zabiegu, dane.csv do arkusza i backup.json
do odtworzenia stanu aplikacji. Skoro dane żyją tylko w przeglądarce, backup nie jest
dodatkiem — jest warunkiem, żeby ta architektura była uczciwa.
Dlaczego .htaccess musiał dostać AddType dla .mjs?
Apache na OVH nie mapuje typu MIME dla .mjs, więc przeglądarka odmawiała
wykonania workera pdf.js — moduł z pustym MIME jest blokowany. Drugi wpis wyłącza cache
dla sw.js: bez tego aktualizacje PWA nie wchodzą, bo przeglądarka trzyma
starego service workera. Oba to rzeczy, których nie widać na zrzucie, a bez nich
aplikacja po prostu nie działa.
Jak to wygląda
Stack
- Vite
- PWA / Workbox
- IndexedDB (idb)
- pdf.js
- JSZip
- Web Share API
- Arima