W transporcie i travel tech prawie nigdy nie zaczynasz od czystej kartki. Masz działającą platformę, która sprzedaje bilety, planuje trasy albo spina rezerwacje, i to ona przynosi pieniądze. Wyzwaniem nie jest więc napisanie aplikacji od zera, tylko rozwój i utrzymanie aplikacji transportowych, które muszą działać bez przerwy, a jednocześnie co kwartał dostawać nowe funkcje. Jeśli jesteś CTO, head of platform albo dyrektorem IT, znasz to napięcie: biznes chce szybciej, a dług techniczny i ryzyko awarii ciągną w drugą stronę.
Z naszego doświadczenia najtrudniejsze jest utrzymanie ciągłości - dokładać wartość, nie przewracając tego, co już działa. Dla dostawcy technologii dla lotnictwa i podróży robimy dokładnie to: rozwijamy nowe funkcje jego istniejących aplikacji, utrzymujemy systemy i prowadzimy migracje do chmury w modelu cloud-to-cloud, opierając się na Javie, mikroserwisach i GCP. Poniżej rozkładamy to na części.
Dlaczego rozwój i utrzymanie aplikacji transportowych to jedna całość?
Bo w produkcie, który działa latami, nie da się ich rozdzielić bez strat. Zespół, który tylko „gasi pożary”, nie rozumie, dokąd zmierza architektura. Zespół, który tylko dowozi nowe funkcje i nie dba o to, co już stoi, po roku zostawia platformę, której nikt nie chce dotykać.
Dlatego patrzymy na jeden strumień pracy: rozwój nowych funkcji i utrzymanie systemów prowadzi ten sam zespół, który zna kod, zależności i historię decyzji. Dzięki temu każda nowa funkcja wpina się w istniejącą architekturę świadomie, a nie na doklejkę, a drobne poprawki utrzymaniowe stają się okazją do spłacania długu technicznego. W transporcie, gdzie integracji z systemami zewnętrznymi jest mnóstwo, ta ciągłość jest szczególnie cenna.
Jak rozwijamy nowe funkcje w istniejących systemach transportowych?
Nie przepisujemy produktu, tylko rozwijamy go przyrostowo. Wchodzimy w działający kod, odczytujemy jego logikę i dokładamy funkcje tak, żeby reszta platformy nadal działała.
- czytamy istniejącą architekturę i zależności, zanim cokolwiek zmienimy,
- projektujemy nową funkcję jako element większej całości, nie wyspę,
- osłaniamy zmianę testami, żeby regresja nie zabiła tego, co już stoi,
- wdrażamy małymi krokami, z możliwością wycofania.
To podejście sprawdza się tam, gdzie produkt obsługuje realny ruch pasażerski czy rezerwacyjny i nie wolno go zatrzymać na tydzień „bo przebudowa”.
Jak budujemy backend w transporcie: Java, Spring i mikroserwisy?
Sercem większości platform transportowych jest backend w Javie. Stawiamy go na Springu i rozbijamy na mikroserwisy, bo w tej branży różne części systemu żyją w różnym tempie: silnik wyszukiwania połączeń zmienia się inaczej niż moduł płatności czy integracja z dostawcą.
Taki podział daje nam niezależne wdrożenia poszczególnych usług, czytelne granice odpowiedzialności i możliwość skalowania tylko tego, co faktycznie obciążone. Do tego dochodzi warstwa danych: projektujemy i utrzymujemy procesy ETL/ELT, które zasilają raporty, analitykę i integracje. W transporcie dane o trasach, cenach i dostępności są produktem samym w sobie, więc ich przepływ traktujemy równie poważnie jak logikę aplikacji.
Jak wygląda frontend aplikacji transportowych w React i Angular?
Po stronie użytkownika pracujemy głównie w React i Angular. Wybór zależy od tego, w czym napisany jest istniejący produkt - dopasowujemy się do stacku klienta, zamiast narzucać własny.
Rozwijamy interfejsy, które muszą udźwignąć sporą złożoność: wyszukiwarki połączeń, kalendarze dostępności, panele rezerwacyjne i widoki operacyjne. Dbamy o to, żeby pod rosnącą liczbą funkcji frontend się nie rozsypał - porządkujemy komponenty, pilnujemy wydajności renderowania i spójności z resztą ekosystemu. Front i backend rozwija u nas jeden zespół, więc nowa funkcja powstaje od API po ekran bez przerzucania odpowiedzialności między firmami.
Kiedy w transporcie sięgamy po komponenty w C++?
Wtedy, gdy liczy się surowa wydajność. Część systemów transportowych ma fragmenty, w których milisekundy i zużycie pamięci robią różnicę - przetwarzanie dużych wolumenów danych, wymagające obliczeniowo algorytmy, komponenty blisko sprzętu lub infrastruktury. Tam sięgamy po C++ w standardzie C++17.
Nie jest to domyślny wybór do całej aplikacji, lecz narzędzie do konkretnych, krytycznych wydajnościowo elementów, które następnie spinamy z resztą platformy opartą o Javę i mikroserwisy. Dzięki temu produkt zyskuje wydajność tam, gdzie trzeba, bez komplikowania całości.
Jak prowadzimy migrację aplikacji transportowych do chmury (GCP, cloud-to-cloud)?
Migrację do chmury traktujemy jak operację na żywym organizmie, a nie jednorazowe „przełożenie plików”. Dla dostawcy technologii lotniczej i podróżniczej prowadzimy migracje cloud-to-cloud do GCP, przenosząc działające systemy między środowiskami chmurowymi tak, żeby biznes tego nie odczuł.
- konteneryzujemy aplikacje (Docker) i orkiestrujemy je w Kubernetes,
- opisujemy infrastrukturę jako kod w Terraform, żeby środowiska były powtarzalne,
- automatyzujemy wdrożenia w CI/CD na Jenkinsie,
- migrujemy etapami, z kontrolą nad tym, co i kiedy przełączamy.
Taka infrastruktura daje później to, po co się migruje: szybsze i bezpieczniejsze wdrożenia, przewidywalne środowiska i skalowanie pod realny ruch.
Jak zapewniamy jakość: QA i automatyzacja testów?
W systemie, który ciągle się zmienia, ręczne testy nie nadążą. Dlatego automatyzujemy to, co się da. Budujemy testy end-to-end interfejsu w Selenium i testy API w REST Assured, i wpinamy je w pipeline CI/CD, żeby każda zmiana była sprawdzana, zanim trafi dalej.
Dzięki temu rozwój nowych funkcji nie oznacza ciągłego ryzyka regresji - zespół może dokładać wartość szybciej, bo siatka testów łapie błędy wcześnie. To jeden z warunków, żeby rozwój i utrzymanie dało się prowadzić równolegle, a nie na zmianę.
Jakie kompetencje dostarczamy do projektu transportowego?
Skład dobieramy pod konkretny system i etap, na jakim jest, a nie według gotowego szablonu. Zwykle łączymy kilka ról:
- backend developerzy (Java/Spring) rozwijający mikroserwisy i logikę domenową,
- frontend developerzy (React/Angular) odpowiadający za interfejsy,
- inżynierowie C++ tam, gdzie liczy się wydajność,
- DevOps / inżynierowie chmury prowadzący konteneryzację, Kubernetes, Terraform i CI/CD,
- inżynierowie QA budujący automatyzację testów,
- specjaliści od danych utrzymujący procesy ETL/ELT.
Nie obsadzamy wszystkich tych ról na zapas - uruchamiamy te, których projekt realnie potrzebuje.
Jak robimy to w RITS?
Robimy to jako partner nearshore z Polski, z realnym doświadczeniem w transporcie i travel tech. Dla dostawcy technologii dla lotnictwa i podróży rozwijamy, utrzymujemy i migrujemy jego aplikacje do chmury: dokładamy nowe funkcje do istniejących systemów, utrzymujemy je i prowadzimy migracje cloud-to-cloud do GCP.
Pod spodem pracuje spójny stack: Java, Spring i mikroserwisy w backendzie, React i Angular na froncie, C++17 w komponentach wydajnościowych, a do tego Docker, Kubernetes, Terraform i Jenkins w warstwie chmurowej oraz Selenium i REST Assured w automatyzacji testów. Taki zespół traktuje rozwój i utrzymanie jako jedno zadanie, więc platforma rośnie, zamiast się sypać.
Od czego zacząć rozwój i migrację aplikacji transportowej?
Zacznij od uczciwej mapy tego, co masz: które systemy przynoszą wartość, gdzie siedzi dług techniczny i co blokuje dokładanie nowych funkcji. Dopiero to podpowiada, czy pilniejszy jest rozwój, utrzymanie czy migracja do chmury - i jakich kompetencji potrzebujesz. Różnice między modelami współpracy opisaliśmy w artykule o modelach współpracy IT.
Rozwijasz, utrzymujesz albo migrujesz do chmury aplikacje transportowe? Porozmawiajmy - dobierzemy zespół i stack pod Twój system.