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ą.