Audyt kodu to nie ocena programistów. To wycena ryzyka
Rozmowa o audycie kodu źródłowego zaczyna się zwykle od jednego z czterech zdań: „inwestor prosi o due diligence", „przejmujemy projekt po innym software housie", „każda nowa funkcja trwa coraz dłużej" albo „nie wiem, czy to, co mamy, da się w ogóle rozwijać". Cztery różne sytuacje biznesowe, jeden wspólny mianownik — ktoś musi podjąć decyzję finansową, a nie ma danych technicznych, żeby ją podjąć.
I to jest właściwa definicja audytu jakości kodu. Nie jest to konkurs na ładny kod ani recenzja pracy zespołu. To przełożenie stanu repozytorium na język ryzyka, kosztu i czasu: co grozi awarią, co spowalnia rozwój, ile kosztuje naprawa i co można spokojnie zostawić.
W tym tekście opisujemy, jak taki audyt wygląda od środka — co konkretnie sprawdzamy, czego potrzebujemy od klienta, ile to trwa, co dostaje się na wyjściu i kiedy audyt się nie opłaca.
Kiedy audyt kodu ma sens
Przed inwestycją lub przejęciem (technical due diligence)
Najczęstszy scenariusz z twardym deadline'em. Inwestor albo kupujący chce wiedzieć, czy kupuje produkt, czy zobowiązanie. Pytania są konkretne: czy kod da się rozwijać bez przepisywania od zera, czy nie ma bomb licencyjnych i prawnych, czy zespół jest zastępowalny, czy w repo nie leżą sekrety produkcyjne, jak wygląda realny koszt utrzymania na kolejne dwa lata.
Tu audyt zwykle nie zmienia decyzji „kupować / nie kupować" — zmienia cenę i warunki. Znalezione ryzyka lądują w negocjacjach jako obniżka albo jako warunki zawieszające.
Przy przejęciu projektu po innym zespole
Wchodzimy w cudze repozytorium i musimy odpowiedzieć na pytanie, którego nikt nie lubi zadawać na głos: rozwijać czy przepisać. Bez audytu ta decyzja jest podejmowana na przeczuciach — a przeczucia programistów mają silny bias w stronę „przepiszmy to od nowa".
Gdy velocity spada, a nikt nie wie dlaczego
Objawy są charakterystyczne: estymacje rosną przy podobnych zadaniach, każde wydanie ciągnie za sobą regresy, zespół coraz częściej mówi „to trzeba by najpierw uporządkować". Opisaliśmy je szerzej w tekście 5 znaków, że aplikacja mobilna umiera po cichu. Audyt odpowiada, ile z tego spowolnienia to dług techniczny, a ile problem procesu albo braku ludzi.
Przed dużą zmianą — refactorem, migracją, skalowaniem
Jeśli planujesz przepisać frontend, zmienić bazę, wejść na nowy rynek albo przygotować się na dziesięciokrotny ruch, audyt jest baselinem: punktem odniesienia, który pozwala później zmierzyć, czy zmiana faktycznie coś poprawiła.
Po roku pracy z asystentami AI
Nowa, ale już bardzo częsta przyczyna. Kod powstaje szybciej, niż ktokolwiek jest w stanie go przeczytać ze zrozumieniem. Wzorce, które w takich projektach znajdujemy najczęściej — brak walidacji wejścia, sekrety w repo, N+1, martwe testy — zebraliśmy w osobnym tekście: kod pisany przez AI w produkcji.
Co sprawdzamy — sześć obszarów
Dobry audyt nie jest wyliczanką „tu brakuje średnika". Ma stałą strukturę, żeby dało się porównywać projekty i żeby nic nie wypadło przez przypadek.
1. Architektura i granice systemu
Zaczynamy od góry, bo to tutaj leżą najdroższe błędy. Interesuje nas, czy system ma czytelne granice modułów, czy logika biznesowa nie jest rozlana po kontrolerach i komponentach UI, czy zależności idą w jedną stronę, czy da się wyodrębnić kawałek systemu bez rozmontowania reszty.
Praktyczny test: ile plików trzeba dotknąć, żeby dodać typową funkcję. Jeśli odpowiedź brzmi „zależy, ale zwykle kilkanaście w czterech warstwach" — architektura jest kosztem, nie fundamentem.
2. Jakość i czytelność kodu
Tu wchodzą metryki, ale traktujemy je jako wskaźnik, nie wyrok: duplikacja, złożoność cyklomatyczna hotspotów, rozmiar plików i funkcji, spójność konwencji, martwy kod. Do tego przegląd ręczny najgorętszych obszarów — plików, które zmieniają się najczęściej i jednocześnie mają najwyższą złożoność. To zwykle 5–10% repozytorium, które generuje większość bugów.
Osobno sprawdzamy, czy w projekcie w ogóle działa mechanizm utrzymywania jakości: linter w CI, formatowanie, code review z realnymi uwagami, a nie stemplowaniem PR-ów.
3. Bezpieczeństwo
Skan zależności pod kątem znanych podatności, przegląd pod kątem OWASP Top 10, autoryzacja i uwierzytelnianie (najczęstsze znalezisko: sprawdzanie uprawnień w UI zamiast na backendzie), zarządzanie sekretami wraz ze skanem historii Gita, konfiguracja produkcyjna, obsługa danych osobowych.
Warto powtórzyć rzecz, którą wiele zespołów odkrywa za późno: usunięcie sekretu kolejnym commitem go nie usuwa. Klucz zostaje w historii i trzeba założyć, że wyciekł — jedyną poprawną reakcją jest rotacja.
4. Wydajność i koszty
Zapytania do bazy (klasyczny N+1, brakujące indeksy, zapytania bez limitów), czasy odpowiedzi API, rozmiar bundla i Core Web Vitals po stronie webu, cold start i zużycie pamięci w aplikacjach mobilnych. Do tego rachunek za chmurę — zaskakująco często największą pozycją jest coś, czego nikt świadomie nie zaprojektował: nadmiarowe logowanie, transfer między strefami albo instancja zapomniana po migracji.
Większość wąskich gardeł, które w aplikacji mobilnej wyglądają jak „wolny interfejs", leży po stronie backendu i API.
5. Testy i CI/CD
Nie pytamy „ile macie pokrycia", tylko „czy te testy cokolwiek chronią". Czytamy asercje, sprawdzamy, czy testy nie weryfikują wyłącznie mocków, patrzymy na testy krytycznych ścieżek — logowania, płatności, składania zamówienia. Sprawdzamy też czas przejścia pipeline'u i to, czy zespół ufa czerwonemu buildowi, czy nauczył się go ignorować.
Po stronie CI/CD: automatyzacja wydania, powtarzalność środowisk, możliwość rollbacku, czas od merge'a do produkcji.
6. Operacje, dokumentacja i ryzyko ludzkie
Monitoring i alerty (czy o awarii dowiadujecie się z systemu, czy z telefonu klienta), logi, backupy — a przede wszystkim czy backup był kiedykolwiek odtwarzany. Do tego bus factor: ile osób rozumie kluczowe fragmenty systemu, czy onboarding nowego developera jest opisany, czy dostępy da się przekazać bez jednej konkretnej osoby.
W projektach objętych regulacjami dochodzi warstwa zgodności — RODO, a od czerwca 2025 również wymogi dostępności wynikające z Europejskiego Aktu o Dostępności, czyli praktycznie WCAG 2.2 na poziomie AA.
Jak to przebiega i czego potrzebujemy
Typowy audyt techniczny to 1–2 tygodnie. Krócej się nie da zrobić rzetelnie, dłużej zwykle nie ma sensu — po dwóch tygodniach kolejne znaleziska przestają zmieniać obraz.
Przebieg wygląda tak:
- Dzień 0 — zakres. Ustalamy, co jest pytaniem biznesowym. Audyt przed inwestycją i audyt przed refactorem to dwa różne dokumenty.
- Dni 1–2 — dostęp i orientacja. Repozytorium z pełną historią, dostęp do CI, konfiguracja środowisk (bez sekretów produkcyjnych), dokumentacja jeśli istnieje, dostęp do monitoringu.
- Dni 2–4 — rozmowy. 45–60 minut z tech leadem, tyle samo z osobą po stronie biznesu, w miarę możliwości krótkie rozmowy z 2–3 developerami. To najbardziej niedoceniany element audytu: zespół zwykle wie, gdzie leżą trupy, tylko nikt ich o to nie pytał w sposób, który nie brzmi jak szukanie winnego.
- Dni 3–8 — analiza. Narzędzia automatyczne plus przegląd ręczny hotspotów, uruchomienie projektu lokalnie, prześledzenie 2–3 krytycznych ścieżek end-to-end.
- Dni 8–10 — raport i omówienie. Dokument plus spotkanie, na którym przechodzimy przez priorytety i odpowiadamy na pytania.
Czego potrzebujemy od klienta: dostępu do kodu z historią, godziny czasu tech leada i szczerości co do tego, co boli. Czego nie potrzebujemy: dostępu do danych produkcyjnych ani ładnego opowiadania o tym, jak miało być.
Co dostajesz na wyjściu
Raport, który da się przeczytać w dwóch trybach. Zarząd czyta pierwsze dwie strony, zespół techniczny — resztę.
- Streszczenie dla decydenta — stan ogólny, trzy największe ryzyka, rekomendacja jednym zdaniem.
- Lista znalezisk z priorytetami — każde z opisem, dowodem (konkretny plik, zapytanie, zrzut), realnym wpływem biznesowym i estymacją naprawy w osobodniach.
- Mapa priorytetów — co blokuje, co jest pilne, co można zaplanować, co świadomie zostawiamy. Ta ostatnia kategoria jest równie ważna jak pierwsza: audyt bez wskazania, czego nie trzeba robić, zamienia się w listę życzeń.
- Plan naprawczy 30/90 dni — kolejność prac z zależnościami między nimi.
- Odpowiedź na pytanie wyjściowe — rozwijać czy przepisać, kupować czy nie, wystarczy refactor czy potrzebna jest przebudowa.
Czego w raporcie nie ma: ocen ludzi, listy zarzutów wobec poprzedniego wykonawcy i rekomendacji przepisania wszystkiego od zera. To ostatnie jest niemal zawsze najdroższą i najgorszą odpowiedzią — jeśli ją proponujemy, musimy ją obronić liczbami.
Ile to kosztuje — i co realnie decyduje o cenie
Audyt kodu wyceniamy czasem, nie liczbą linii. Punkt odniesienia: jeden do dwóch tygodni pracy doświadczonego inżyniera (przy większych systemach — dwóch), plus czas na raport i omówienie. Dla typowej aplikacji webowej lub mobilnej z backendem daje to koszt porównywalny z 2–4 tygodniami pracy jednego developera.
Na cenę wpływają realnie trzy rzeczy: liczba osobnych systemów w zakresie (aplikacja + backend + panel + integracje to cztery obiekty, nie jeden), głębokość — sam przegląd czy również testy penetracyjne i analiza wydajności pod obciążeniem — oraz forma dostarczenia: sam dokument czy dokument plus warsztat z zespołem.
Porównanie tej kwoty z kosztem błędnej decyzji jest zwykle bezdyskusyjne: nietrafiony refactor to kwartał pracy zespołu, a nietrafiona inwestycja — kwota o rząd wielkości wyższa niż audyt. Podobną logikę stosujemy przy wycenie projektów; opisaliśmy ją w tekście o tym, o co pytać przy wycenie.
Kiedy audyt się nie opłaca
Trzy sytuacje, w których uczciwie odradzamy:
- Decyzja już zapadła. Jeśli przepisujecie system niezależnie od wyniku, audyt jest kosztownym potwierdzeniem. Lepiej wydać te pieniądze na zaprojektowanie migracji.
- Projekt ma mniej niż kilka miesięcy i jedno źródło prawdy. Przy świeżym MVP wystarczy zwykle jednorazowe code review albo konsultacja architektoniczna.
- Problem jest organizacyjny, nie techniczny. Jeśli zespół wie, co naprawić, ale nie dostaje na to czasu, audyt niczego nie zmieni — będzie kolejnym dokumentem, którego nikt nie wdroży. Wtedy sensowniejszy jest stały retainer, który daje argumenty w rozmowie o priorytetach.
W dwóch pierwszych przypadkach warto rozważyć lżejszą formę: kilkugodzinną konsultację zamiast pełnego audytu.
Audyt to początek, nie koniec
Największym marnotrawstwem w tej kategorii jest raport, który po prezentacji trafia do folderu i tam zostaje. Audyt zwraca się dopiero wtedy, gdy jego wynik zamienia się w pozycje w backlogu z właścicielami i terminami.
Dlatego w Mobilesoft audyt zwykle nie kończy się na dokumencie. Bywa wejściem w rescue & refactor — czterotygodniowe do ośmiotygodniowe wejście hands-on w projekt w kryzysie — albo w stałą współpracę: cotygodniowe code review i drugie oczy przed wydaniem. Jeśli chcesz najpierw sam ocenić skalę problemu, przejdź przez naszą checklistę 15 punktów; jeśli wolisz zobaczyć, jak pracujemy w praktyce — zajrzyj do naszych realizacji i tego, jak podchodzimy do budowy aplikacji mobilnych.
A jeśli masz konkretne repozytorium i konkretne pytanie, na które musisz odpowiedzieć w najbliższym miesiącu — napisz do nas albo od razu wyceń projekt. Pierwsza rozmowa zwykle wystarczy, żeby powiedzieć, czy potrzebujesz pełnego audytu, czy wystarczy godzina konsultacji.