Wstecz
Marcin, ze strony Forte jesteś najlepiej obeznany z projektem dla naszego duńskiego klienta. Powiedz na początek - jakie wersje .NET wykorzystujecie i dlaczego?
Celujemy w najnowsze wersje LTS .NET, choć obecnie korzystamy z wersji STS. Gdy tylko pojawi się nowa wersja LTS, planujemy migrację. Nowe komponenty budujemy od zera w nowoczesnych technologiach, jednak pewne decyzje są ograniczane przez stan zastany w systemie legacy. Migracja do nowego stosu oznacza również konieczność przejęcia wielu istniejących problemów technicznych.
Czy korzystacie z konkretnych wzorców projektowych?
Tak – podstawą naszej architektury jest wzorzec CQS (Command Query Segregation), który zakłada rozdzielenie operacji modyfikujących stan aplikacji (Command) od operacji tylko odczytujących dane (Query). Dzięki temu struktura kodu jest bardziej przejrzysta i łatwiejsza w utrzymaniu. Staramy się projektować system modułowo, z zachowaniem równowagi między czytelnością, wydajnością a skalowalnością – to jedna z naszych kluczowych zasad projektowych.
Z jakich bibliotek i frameworków korzystacie poza .NET?
Do zaimplementowania wzorca CQS wykorzystujemy MediatR, który pozwala nam zachować czytelny podział pomiędzy operacjami zapisu i odczytu. W przyszłości planujemy zastąpić go innym rozwiązaniem, ponieważ MediatR przechodzi na model komercyjny. W backendzie korzystamy również z Entity Framework oraz Azure Graph API. Po stronie frontendu opieramy się na Next.js oraz React Query, które zapewniają efektywną komunikację z API i zarządzanie stanem danych.
Jak podchodzicie do CI/CD?
Wdrożyliśmy procesy CI/CD z wykorzystaniem Azure Pipelines, które są integralną częścią platformy Azure DevOps. Obecnie rozwijamy infrastrukturę w podejściu Infrastructure as Code, wykorzystując Bicep – dedykowany przez Microsoft framework do zarządzania zasobami w chmurze. W zakresie ciągłego wdrażania (CD) opieramy się na wzorcu Landing Zones, który umożliwia porządkowanie zasobów w ramach wielu Azure Subscriptions i pozwala nam utrzymać zgodność ze standardami enterprise w zakresie bezpieczeństwa, zarządzania i skalowalności.

Jakie narzędzia i praktyki pomagają Wam utrzymać wysoką jakość kodu?
Naszym codziennym standardem jest code review. Nie korzystamy obecnie z narzędzi takich jak SonarQube. Tworzymy testy jednostkowe dla nowych komponentów, a w kodzie legacy dopisujemy je przy okazji refaktoryzacji – choć bywa to trudne ze względu na jego złożoność.
Czy stosujecie TDD lub inne podejścia do testowania?
Nie pracujemy ściśle według TDD, ale testy jednostkowe są obowiązkowe. Mamy QA w zepole.
Jakie narzędzia wykorzystujecie do monitoringu i logowania?
Bazujemy na Azure Application Insights, który pozwala monitorować stan systemu i definiować alerty.
Jak wygląda proces deploymentu?
Stosujemy klasyczny Git Flow. Programiści pracują na feature branchach, z których zmiany trafiają do głównej gałęzi developerskiej i są wdrażane na środowisko developerskie. Następnie, przez dedykowaną gałąź testową, przechodzą na staging, skąd wypuszczamy releasy. W razie potrzeby jesteśmy elastyczni i dostosowujemy proces.
Czy jako developer masz wpływ na decyzje architektoniczne i technologiczne?
Zdecydowanie tak. Nie mamy formalnie wyznaczonego architekta – decyzje podejmujemy wspólnie, słuchając każdego członka zespołu. To kolektywne podejście dobrze się u nas sprawdza.

Jakie są największe wyzwania techniczne w projekcie?
Największym wyzwaniem jest komunikacja między naszą chmurową infrastrukturą a systemem klienta on-premise. Współpracujemy z zespołem IT klienta oraz jego doradcami technologicznymi. To trójstronne partnerstwo wymaga dobrej koordynacji i wysokich standardów bezpieczeństwa. Nasza Product Ownerka odgrywa tu kluczową rolę – doskonale spina wszystkie wątki i skutecznie wywalcza potrzebne decyzje. Klient to duża korporacja, ale świadomie podchodzi do współpracy i zna swoje potrzeby.
Jak podejmowane są decyzje techniczne?
Większość decyzji inicjujemy wewnętrznie. W przypadku potrzeby formalnej zgody – np. na zakup licencji czy pluginów do Umbraco – komunikujemy się przez Product Ownerkę, która koordynuje ustalenia z zespołem klienta w Danii.
Jakie były najważniejsze zmiany techniczne ostatnio?
Największym osiągnięciem było skonfigurowanie i uruchomienie środowiska chmurowego wraz z pełną infrastrukturą DevOps. To był wymagający etap, ale dzięki niemu mamy teraz solidne fundamenty pod dalszy rozwój.
Czy projekt ma wysokie wymagania wydajnościowe?
Tak. W określonych momentach miesiąca – np. przy masowym pobieraniu faktur – system jest intensywnie wykorzystywany. Komunikacja z lokalnymi bazami danych klienta potrafi wtedy generować przeciążenia, dlatego optymalizacja zapytań i reagowanie na timeouty to nasze priorytety.

Jakie macie podejście do optymalizacji?
Stawiamy na profilowanie, cache’owanie oraz optymalizację zapytań do baz danych. Staramy się reagować szybko i wdrażać zmiany tam, gdzie widać realny zysk. Nie korzystamy z automatycznych narzędzi do profilowania, tylko analizujemy konkretne przypadki.
Czy projekt obejmuje przetwarzanie dużych ilości danych?
Aktualnie nie zajmujemy się bezpośrednio przetwarzaniem dużych wolumenów danych, choć źródła, z których korzystamy, są intensywnie obciążone. W przyszłości przewidujemy wejście w te obszary.
Czego nauczyłeś się technicznie podczas pracy w tym projekcie?
Na pewno pracy z legacy code – to wymaga nie tylko umiejętności technicznych, ale też cierpliwości i zaufania do siebie. Poza tym pogłębiłem wiedzę na temat CMS-a Umbraco oraz architektury enterprise z wykorzystaniem chmury Azure i B2C.
Dzięki za rozmowę, mam nadzieję, że za jakiś czas gdy zakres projektu się poszerzy będziemy mogli opowiedzieć o nim jeszcze więcej ciekawych rzeczy!
