Klient chce kalkulator w stronie, którą wygenerował ktoś inny. Triaż w godzinę, zanim podasz cenę
Zapytanie o rozbudowę cudzego projektu z generatora: siedem odczytów z repozytorium, które zamieniają zakład na wycenę, i czego nie obiecywać przed triażem.
„Mamy stronę, zrobił ją nam ktoś w generatorze, trzeba dodać kalkulator i panel zamówień. Ile to będzie?” Pytanie pada w pierwszej rozmowie, odpowiedź pada zwykle w tej samej, a wycenia się wtedy kod, którego nikt z wyceniających nie widział. Repozytorium ma kilka tysięcy linii, autor jest nieosiągalny, a historia gita ma trzy commity z opisem „update”.
Wyceniasz nie zakres, a stan przejmowanego projektu
Przy zleceniu na zmianę w istniejącym projekcie zakres jest najmniejszą niewiadomą. Dodanie kalkulatora to kilka komponentów i jeden endpoint – to się da policzyć z opisu. Niewiadomą jest wszystko, co musisz zrobić, żeby ta zmiana weszła: czy projekt buduje się na czystej maszynie, czy da się bezpiecznie podnieść zależności, czy jest jakikolwiek test, który powie ci, że nie zepsułeś koszyka.
Dlatego liczba podana przez telefon jest zakładem, nie wyceną. Alternatywa nie wymaga wiele: od sześćdziesięciu do dziewięćdziesięciu minut na triaż repozytorium, zanim z twoich ust wyjdzie jakakolwiek kwota. Niżej jest zestaw komend, które w tym czasie dają liczby, oraz tabela przeliczająca te liczby na pozycje w ofercie.
Triaż w godzinę: komendy, które zwracają liczby zamiast wrażeń
Wszystko poniżej uruchamiasz na kopii repozytorium, w katalogu z package.json, bez modyfikowania czegokolwiek. Celem nie jest naprawa projektu, tylko policzenie, ile pracy kosztuje wejście w niego.
#!/usr/bin/env bash
# Triaz przejmowanego projektu. Wynik przepisujesz do tabeli wyceny.
set -u
echo "== silnik i deklaracje =="
node -v
python3 -c "import json; p=json.load(open('package.json')); \
print('engines:', p.get('engines')); \
print('zaleznosci produkcyjne:', len(p.get('dependencies', {}))); \
print('zaleznosci dev:', len(p.get('devDependencies', {}))); \
print('skrypty:', list(p.get('scripts', {})))"
echo "== lockfile =="
ls -1 package-lock.json pnpm-lock.yaml yarn.lock 2>/dev/null || echo "BRAK LOCKFILE"
echo "== czy buduje sie od zera (mierz czas) =="
time npm ci 2>&1 | tail -5
time npm run build 2>&1 | tail -15
echo "== audyt zaleznosci =="
npm audit --json 2>/dev/null | python3 -c "import json,sys; \
d=json.load(sys.stdin); print(d.get('metadata', {}).get('vulnerabilities'))"
echo "== historia i autorzy =="
git log -1 --date=short --format='ostatni commit: %ad, %an'
echo "commitow razem: $(git log --oneline | wc -l)"
git log --format='%an' | sort | uniq -c | sort -rn | head -5
echo "== powtorzenia w kodzie =="
npx -y jscpd@4 --min-lines 5 --reporters consoleFull src 2>/dev/null | tail -12
Interesuje cię siedem odczytów: czy jest lockfile, czy npm ci i build kończą się kodem zero, ile minut zajmuje pierwszy build, ile jest zależności produkcyjnych, co pokazuje audyt, jaka jest data ostatniego commita i czy w scripts istnieje cokolwiek, co uruchamia testy. Brak lockfile i brak testów to dwie najdroższe rzeczy, jakie możesz zobaczyć w tym wydruku – pierwsze oznacza, że nie wiesz, na jakich wersjach projekt kiedykolwiek działał, drugie, że każdą swoją zmianę weryfikujesz ręcznie przez cały czas trwania zlecenia.
Odczyt z triażu przeliczony na pozycję w ofercie
| Co widzisz w triażu | Czym to jest w praktyce | Co robisz z tym w wycenie |
|---|---|---|
| Brak lockfile albo build nie przechodzi na czystej maszynie | Nie ma punktu odniesienia: nie wiesz, czy twoja zmiana coś zepsuła, czy projekt był zepsuty | Osobna pozycja „odtworzenie środowiska i zielony build”, rozliczana po czasie, przed pracą nad zakresem |
Zero skryptów testowych w package.json |
Każda regresja wychodzi u klienta, a nie u ciebie | Albo pozycja na testy krytycznej ścieżki, albo jawne wyłączenie odpowiedzialności za regresje poza zakresem zmiany |
| Kilkadziesiąt zależności produkcyjnych, audyt pokazuje podatności wysokie | Podnoszenie wersji wejdzie w zakres, bo bez tego nie da się wdrożyć | Widełki plus warunek przesuwający do górnej granicy, nazwany wprost w ofercie |
| Ostatni commit starszy niż rok, wersja runtime po końcu wsparcia | Migracja platformy wdrożeniowej doklejona do zlecenia o kalkulator | Rozdzielenie na dwa etapy z osobnymi cenami i osobnym odbiorem |
| Wysoki udział powtórzonego kodu, jedna zmiana w kilku miejscach | Każda poprawka ma wielokrotny koszt, bo logika jest rozsypana | Mnożnik na pozycje „zmiana w istniejącym kodzie”, nie na cały projekt |
| Jeden autor, trzy commity, opisy bez treści | Brak historii intencji: nie dowiesz się, dlaczego coś jest zrobione tak, jak jest | Pozycja na rozpoznanie kodu (czytanie i notatki), zwykle liczona w godzinach, nie w minutach |
Zależności są większością ryzyka, które przejmujesz razem z kodem
Projekt wygenerowany szybko zwykle ma długą listę paczek, bo dołożenie biblioteki jest tańsze niż napisanie funkcji. Ten koszt przechodzi na ciebie w momencie podpisania umowy. W raporcie Veracode z lutego 2026, opartym na 1,6 mln aplikacji i 141,3 mln surowych wyników skanowania, 82 proc. organizacji ma dług bezpieczeństwa, a wśród nich 60 proc. ma dług w kategorii krytycznej. Ten sam raport podaje, że biblioteki zewnętrzne i zależności open source odpowiadają za 66 proc. najgroźniejszych i najdłużej żyjących podatności oraz że liczba luk jednocześnie poważnych i łatwych do wykorzystania wzrosła o 36 proc. rok do roku.
Przełóż to na zdanie w ofercie: podniesienie zależności albo jest wycenione, albo jest wyłączone na piśmie. Trzeciej możliwości nie ma, bo jeśli nie zrobisz żadnej z tych dwóch rzeczy, zrobisz to i tak – przy pierwszej próbie wdrożenia, we własnych godzinach.
Przy wersji środowiska uruchomieniowego sprawdzenie zajmuje minutę i warto je zrobić przed wyceną, nie po. Node 18 i Node 20 są już po końcu wsparcia, co widać w harmonogramie wydań Node.js; projekt stojący na takiej wersji nie jest projektem, w którym dopisuje się kalkulator, tylko projektem, który najpierw trzeba przenieść.
Czego nie obiecywać przy pierwszej rozmowie
Dwie obietnice potrafią zjeść całą marżę zlecenia, a składa się je odruchowo, żeby pokazać kompetencję.
Pierwsza to wydajność. „Przy okazji przyspieszymy stronę” wygląda na gest, a jest zobowiązaniem bez zdefiniowanego progu. Progi są publiczne i mierzalne: dokumentacja Core Web Vitals podaje LCP do 2,5 s, INP do 200 ms i CLS do 0,1, oceniane na 75. percentylu wejść, osobno dla urządzeń mobilnych i desktopu. Zanim zadeklarujesz poprawę, zmierz stan wyjściowy i zapisz w ofercie, które podstrony obejmuje deklaracja i na jakich danych będzie weryfikowana. Bez percentyla i listy adresów jest to deklaracja nie do rozliczenia, a przy odbiorze zawsze rozlicza ją klient.
Przy samym pomiarze wydajności pilnuj jednej rzeczy: stan wyjściowy mierz na danych z przeglądarek użytkowników, jeśli strona ma ruch, a nie tylko w laboratorium na własnym łączu. Wynik z pojedynczego uruchomienia narzędzia na twoim komputerze różni się od tego, co widzi klient na telefonie w sieci komórkowej, a deklaracja w ofercie będzie rozliczana z tego drugiego. Jeśli ruchu nie ma, zapisz wprost warunki pomiaru: narzędzie, urządzenie, przepustowość i listę adresów.
Druga to termin podany przed triażem. Zdanie „to są dwa, trzy dni” wypowiedziane przy telefonie zostaje w pamięci klienta jako wycena, nawet jeśli potem wyślesz ofertę z inną liczbą. Bezpieczniejsza odpowiedź jest krótsza: masz stawkę za rozpoznanie projektu, po rozpoznaniu dajesz termin i cenę zakresu. Płatny audyt wstępny bywa tu łatwiejszy do sprzedania, niż wygląda, bo klient dostaje z niego własny dokument – listę ryzyk w swoim projekcie, przydatną również wtedy, gdy wybierze innego wykonawcę. To zresztą ta sama zmiana nastawienia, którą przechodzą osoby zaczynające sprzedawać własną pracę jako usługę, a nie jako godziny.
Trzy sytuacje, w których lepiej zaproponować przepisanie
- Projekt nie buduje się ze źródeł i nie ma lockfile. Odtworzenie działającego środowiska może kosztować więcej niż napisanie tej części od nowa, a po odtworzeniu nadal nie wiesz, czy dostałeś to, co jest na produkcji.
- Logika biznesowa siedzi w komponentach interfejsu, bez żadnej warstwy pośredniej. Dodanie panelu zamówień wymaga wtedy przeszycia całego widoku, a każdy taki zabieg dotyka rzeczy, których nie obejmuje zlecenie.
- Dane i sekrety są w repozytorium albo w kodzie klienckim. To nie jest usterka do poprawienia w ramach zlecenia na nową funkcję, bo wymaga rotacji poświadczeń i zmiany sposobu wdrażania. Wycenia się to osobno albo nie wycenia wcale.
Propozycja przepisania nie musi oznaczać utraty zlecenia. Zwykle oznacza podzielenie go na etap pierwszy, który daje klientowi sprawny fundament i działający build, i etap drugi, w którym dopiero powstaje zamówiona funkcja. Klient częściej odmawia wtedy, gdy słyszy jedną dużą kwotę bez wyjaśnienia, niż gdy widzi dwie pozycje i rozumie, za co płaci pierwszą.
Lista kontrolna przed podaniem ceny
Triaż ma sens tylko wtedy, gdy wygląda tak samo przy każdym zapytaniu i gdy może go wykonać ktoś inny niż osoba, która potem pisze ofertę. Przy dwóch zapytaniach w tygodniu to jeszcze działa z pamięci, przy pięciu już nie – wtedy opłaca się spisać go jako procedurę, razem z wzorem notatki i miejscem, gdzie ląduje wynik; reguły, które decydują o tym, czy spisany proces faktycznie zostanie wykonany, są tu takie same jak przy każdej innej powtarzalnej czynności w firmie. Poniższa lista jest minimum, które musi być odhaczone, zanim w rozmowie pojawi się liczba.
- Masz kopię repozytorium i wynik triażu zapisany w pliku, a nie w pamięci.
- Wiesz, czy
npm cii build kończą się kodem zero na czystej maszynie i ile to trwa. - Wiesz, czy istnieje lockfile i czy w projekcie jest cokolwiek, co da się uruchomić jako test.
- Masz liczbę zależności produkcyjnych i wynik audytu, a nie wrażenie, że „to standardowy stack”.
- Masz zmierzony stan wyjściowy wydajności, jeśli w ofercie ma pojawić się słowo o szybkości.
- Oferta ma osobne pozycje na rozpoznanie kodu, doprowadzenie do zielonego buildu i dopiero potem na zamówiony zakres.
- To, czego nie bierzesz na siebie, jest wypisane jako wyłączenia, a nie pominięte milczeniem.
Decyzja do podjęcia jest jedna i dotyczy najbliższego zapytania o rozbudowę cudzego projektu: wprowadź stawkę za rozpoznanie i nie podawaj ceny zakresu, dopóki triaż nie przejdzie. Jeśli klient nie zgadza się zapłacić za godzinę rozpoznania własnego kodu, masz odpowiedź, jak będzie wyglądała rozmowa o dodatkowych godzinach w trakcie zlecenia.