Przejmując aplikację mobilną po innym wykonawcy, zaczynam od audytu i dokumentacji, a nie od kodu. Najpierw ustalam, co naprawdę działa, czego oczekuje backend i jakie są ryzyka, potem zapisuję decyzje architektoniczne, a dopiero na końcu przebudowuję aplikację krok po kroku – z testami od pierwszego dnia. Tak przejąłem aplikację we Flutterze dla personelu lokali gastronomicznych i wydałem ją w Google Play, a wersja na iOS czeka na publikację w App Store.
Co zastałem
Aplikacja powstała wcześniej na kupionym szablonie sklepu internetowego. Z zewnątrz wyglądała na prawie gotową, ale w środku:
- zero testów automatycznych,
- dziesiątki nieużywanych ekranów i komponentów z szablonu oraz trasy, które prowadziły donikąd,
- powiadomienia push, które nie działały na urządzeniu,
- brak obsługi wygasłej sesji – aplikacja nie reagowała, gdy backend odrzucał token,
- modele danych bez typów, przez które błąd w odpowiedzi API wychodził dopiero na ekranie.
To typowy obraz aplikacji, która miała „tylko trochę dokończenia”. Właśnie dlatego nie zaczynam od dopisywania funkcji.
Krok 1: audyt i dokumentacja przed pierwszą linią kodu
Pierwsze dwa dni to wyłącznie dokumentacja: opis stanu zastanego, kontrakt API uzgodniony z backendem, rejestr ryzyk bezpieczeństwa, decyzje architektoniczne zapisane jako ADR i lista otwartych pytań do klienta. Implementacja zaczęła się dopiero, gdy było jasne, co budujemy i dlaczego.
Ta inwestycja zwraca się szybko. Każda późniejsza decyzja – jak obsłużyć sesję, skąd brać stan zamówień, co robić przy braku sieci – ma swoje uzasadnienie na piśmie, więc nie wraca w kolejnych rozmowach.
Krok 2: backend decyduje, aplikacja pokazuje
Najważniejsza zasada projektu: aplikacja nie podejmuje decyzji biznesowych. Uprawnienia pracowników, dozwolone zmiany statusu zamówienia i dostęp do lokalu rozstrzyga backend. Jeśli aplikacji brakuje jakiejś informacji, rozwiązaniem jest nowy punkt w kontrakcie API, a nie logika dopisana w telefonie.
Dzięki temu aplikacja mobilna i panel web zachowują się tak samo, a zmiana reguły biznesowej nie wymaga nowego wydania w sklepach.
Krok 3: jeden klient HTTP, który wie, co robić z błędami
Wszystkie zapytania do API przechodzą przez jedno miejsce, które obsługuje typowe sytuacje: wygaśnięcie sesji, brak dostępu do lokalu i przerwę techniczną platformy.
Brzmi jak detal, ale rozwiązało realny problem. Ekran zamówień pobiera każdą kolumnę tablicy osobnym zapytaniem, więc po unieważnieniu tokenu przychodziło kilka odmów naraz i każda chciała wylogować użytkownika. Jedno miejsce obsługi z blokadą przed powtórnym wylogowaniem zamieniło lawinę komunikatów w jedno spokojne „Sesja wygasła”.
Krok 4: czas rzeczywisty i powiadomienia jako sygnał
Zamówienia odświeżają się w czasie rzeczywistym przez WebSocket, a gdy aplikacja jest w tle, o nowym zamówieniu informuje powiadomienie push. W obu przypadkach obowiązuje ta sama reguła: zdarzenie to tylko sygnał, a aktualny stan zawsze pochodzi z API. Dzięki temu zgubione albo spóźnione zdarzenie nie zostawia na ekranie nieaktualnych danych.
Osobno trzeba było obsłużyć sytuację, w której dwóch pracowników zmienia ten sam status w tej samej chwili. Aplikacja wysyła status, który widział użytkownik, a backend odrzuca zmianę, jeśli ktoś go już wyprzedził. Użytkownik dostaje wtedy jasną informację, zamiast cicho nadpisać pracę kolegi.
Krok 5: testy od zera
Aplikacja ma dziś ponad 500 testów automatycznych – jednostkowych i widgetów – napisanych od zera, bez biblioteki do mockowania. Zależności, takie jak klient HTTP czy transport WebSocket, są wstrzykiwane przez konstruktory, więc w testach podmienia się je na wersje bez sieci.
Testy powstawały razem z każdą zmianą, a nie na końcu projektu. Przy przebudowie zastanej aplikacji to jedyny sposób, żeby poprawka jednego ekranu nie zepsuła po cichu innego.
Krok 6: wydanie w Google Play i App Store
Wydanie to osobny etap, a nie „wrzucenie pliku do sklepu”: podpisywanie aplikacji, numeracja kolejnych wersji, konfiguracja powiadomień push i deklaracja danych wymagana przez Google Play. Aplikacja jest już w Google Play, a wersja na iOS czeka na publikację w App Store. W aplikacji pojawia się też informacja o dostępnej nowej wersji, żeby personel nie pracował miesiącami na starej.
Czego świadomie nie zrobiłem od razu
Nie przepisałem wszystkiego na raz. Część pozostałości szablonu i długu technicznego została w kodzie – z zapisaną decyzją, dlaczego teraz nie i co z tym zrobić później. Przejęta aplikacja ma przede wszystkim zacząć działać i być rozwijana bezpiecznie, a porządki idą etapami, przy okazji kolejnych zmian.
Podsumowanie
Przejęcie aplikacji mobilnej to najpierw praca detektywa, a dopiero potem programisty: audyt, kontrakt API i zapisane decyzje, potem jeden klient HTTP, czas rzeczywisty traktowany jako sygnał i testy przy każdej zmianie. Backend i API rozwijałem równolegle po stronie platformy, z której aplikacja korzysta.
Jeśli masz aplikację po innym wykonawcy albo planujesz nową, zobacz, jak wygląda usługa tworzenia aplikacji mobilnych i desktopowych, przeczytaj case study aplikacji do obsługi zamówień albo napisz, co jest nie tak z Twoją aplikacją.