ziecina.dev
← Wszystkie projekty
Na produkcjiPrawdziwy klient2026 – obecnie

Stajnia Lauden

Aplikacja produkcyjna, na której opiera się codzienna praca pensjonatu dla koni z ponad 60 boksami.

Rola
Wszystko: wymagania, UX, backend, frontend, wdrożenie
Użytkownicy
Właściciele (administratorzy), personel, trenerzy, właściciele koni, dzierżawcy
Urządzenia
Telefony, tablety, ekrany na ścianach
Linki
stajnialauden.pl ↗Kod jest prywatny

Problem

Stajnia z ponad 60 boksami, personel i wielu właścicieli koni. Każda prośba („dodatkowe siano dla boksu 12”, „jutro wyprowadzić o 10”) szła przez komunikatory w mediach społecznościowych i pamięć. Dodatkowe usługi rozliczano ręcznie na koniec miesiąca.

Moja rola

Wszystko: zbieranie wymagań z właścicielką, UX, backend, frontend, wdrożenie i utrzymanie. Regularnie spotykałem się z klientką, zamieniałem uwagi w małe iteracje i często wypuszczałem nowe wersje na produkcję.

Co zbudowałem

Jedna aplikacja dla pięciu ról

Administrator, personel, trener, właściciel konia i dzierżawca. Każda rola widzi tylko to, czego potrzebuje, a uprawnienia (RBAC) są pilnowane po stronie API.

Zamówienia usług

Właściciele koni zamawiają usługi jednorazowe lub w abonamencie, na dziś albo na jutro. Personel widzi je na tablicy zadań odświeżanej na bieżąco, gdzie je przyjmuje, wykonuje lub odwołuje.

Komunikaty o karmieniu i wyprowadzaniu

Właściciele wybierają gotowe komunikaty z katalogu, a personel widzi plan dnia dla każdego boksu. Personel może zmienić godziny tylko na bieżący dzień.

Rozliczenia

Pensjonat, kamery i dzierżawy co miesiąc, usługi jednorazowe i abonamentowe, ceny netto/brutto z VAT ustawiane dla boksu (koń „na firmę”), osobne salda gotówki i przelewów. Cena zapisuje się na zamówieniu, więc późniejsza zmiana cennika nie zmienia historii.

Zadania cykliczne (cron)

Codzienne zadania z abonamentów, comiesięczne opłaty i przypomnienia o płatnościach.

Powiadomienia Web Push

Z licznikiem na ikonie aplikacji, dla personelu i właścicieli, działające także przy zamkniętej aplikacji.

Zaprojektowane dla prawdziwych użytkowników

Wśród użytkowników jest wiele osób starszych, więc interfejs trzyma się ścisłych zasad: tekst ma co najmniej 18 px, przyciski i inne elementy do dotknięcia co najmniej 48 px, a status jest zawsze opisany słowami, nigdy samym kolorem. W paszarni i przy wyjściu na padoki wiszą ekrany, które bez dotykania pokazują plan na dziś.

Inżynieria

  • REST API w NestJS + Prisma/PostgreSQL z weryfikacją e-mail, resetem hasła i bezpiecznym przesyłaniem zdjęć.
  • Ponad 130 testów jednostkowych i ponad 100 testów end-to-end (Jest, Supertest), które sprawdzają też uprawnienia („dzierżawca nie zobaczy cudzych opłat”).
  • CI/CD w GitHub Actions → Docker Compose na VPS. Caddy daje automatyczny HTTPS, przed każdym wdrożeniem robi się kopia bazy, a migracje nie niszczą danych.
  • Dziennik decyzji: każda istotna zmiana jest zapisana razem z powodem i odrzuconymi opcjami.

Kluczowa decyzja

React Native (Expo)PWA do zainstalowania

PWA zamiast aplikacji natywnej

Zacząłem od aplikacji w React Native (Expo). Po tym, jak zobaczyłem, jak właścicielka naprawdę korzysta z telefonu, przeszliśmy na jedną aplikację webową, którą można zainstalować na ekranie głównym. Jeden kod dla każdego urządzenia, bez sklepu z aplikacjami i z natychmiastowymi aktualizacjami. To była dobra decyzja i podjąłbym ją ponownie.

Ekrany

Zrzuty ze środowiska demo. Imiona, e-maile, imiona koni i kwoty są zamazane.

Tablica zadań personelu z ponumerowanymi boksami i zadaniami
Personel · tablica zadań na tablecie
Ekran w paszarni ze zmianami w karmieniu na śniadanie, obiad i kolację
Paszarnia · ekran ścienny ze zmianami w karmieniu na dziś
Ekran główny właściciela konia z ogłoszeniami, dzierżawami i boksami
Właściciel konia · boksy i ogłoszenia
Zamawianie jednorazowej usługi z katalogu
Właściciel konia · zamawianie usługi
Lista użytkowników w panelu administratora z rolami i saldami
Administrator · użytkownicy i salda
Rozliczenia jednego klienta z saldem i historią wpłat
Administrator · rozliczenia klienta
Następny projektBuild Budget →