Naucz się pisać prompty przewodnika stylu Claude Code, które egzekwują nazewnictwo, warstwowanie, obsługę błędów i logowanie oraz wykrywają naruszenia na wczesnym etapie prostymi checkami.

Naruszenia zasad stylu rzadko pojawiają się jako jeden wielki błąd. Zaczynają się od małych, „wystarczająco dobrych” wyborów w pull requeście, które wyglądają niewinnie, a potem nakładają się aż baza kodu staje się niespójna i trudniejsza do czytania.
Dryf stylu często wygląda tak: w jednym pliku użyto userID, w innym userId, w trzecim uid. Jeden handler zwraca { error: \"...\" }, inny rzuca wyjątek, jeszcze inny loguje i zwraca null. Każda zmiana jest drobna, ale razem tworzą repozytorium, w którym wzorce przestają być przewidywalne.
Szybkie iteracje i wielu współautorów pogarszają sprawę. Ludzie kopiują to, co widzą, szczególnie pod presją czasu. Jeśli najnowszy kod używa skrótu, ten skrót staje się szablonem dla następnej zmiany. Po kilku tygodniach „domyślny styl” to nie jest Wasz zapisany przewodnik. To to, co pojawiło się ostatnio.
Dlatego celem muszą być spójne konwencje, a nie osobiste preferencje. Pytanie nie brzmi „Czy podoba mi się ta nazwa?” lecz „Czy to pasuje do zasad, na które się umówiliśmy, żeby następna osoba mogła z niej skorzystać bez zastanowienia?”.
Wykrywanie naruszeń wcześnie oznacza powstrzymanie złych wzorców zanim staną się paliwem do kopiowania. Skoncentruj się na nowym i zmodyfikowanym kodzie, napraw pierwsze wystąpienie nowej niespójności i blokuj merge'y, które wprowadzają nowy dryf. Gdy zgłaszasz problem, dodaj krótkie preferowane przykłady, które można naśladować następnym razem.
Przykład z życia: deweloper dodaje nowy endpoint API i loguje surowe ciała żądań „tylko do debugowania”. Jeśli to wejdzie, następny endpoint skopiuje zachowanie i wkrótce w logach pojawią się wrażliwe dane. Wykrycie tego w pierwszym PR jest tanie. Wykrycie po rozprzestrzenieniu się jest bolesne i ryzykowne.
Przewodnik stylu działa w przeglądach tylko wtedy, gdy czyta się go jak checklistę, a nie zbiór gustów. Przepisz każdą wskazówkę jako regułę, którą można sprawdzić na diffie.
Zorganizuj reguły w cztery kosze, by były trudne do przeoczenia: nazewnictwo, warstwowanie, obsługa błędów i logowanie. Dla każdego z nich napisz dwie rzeczy: co musi być prawdą i co jest zabronione.
Ustal siłę każdej reguły z góry:
Ustal zakres, żeby przeglądy nie zamieniły się w niekończące się refaktory. Prosta zasada działa dobrze: „nowy i zmodyfikowany kod musi być zgodny; istniejący, nietknięty kod nie jest przepisywany, chyba że blokuje poprawkę”. Jeśli chcesz sprzątania, czasowo je ogranicz jako oddzielne zadanie.
Zdefiniuj też wynik przeglądu, by łatwo było działać: werdykt pass/fail, lista naruszeń z odniesieniami do pliku i linii, sugerowane poprawki zapisane jako konkretne edycje oraz krótka notka o ryzyku, kiedy coś może powodować błędy lub wycieki.
Przykład: jeśli PR loguje surowe tokeny użytkownika, przegląd powinien nie przejść pod „logowanie: nigdy nie logować sekretów” i zasugerować logowanie identyfikatora requestu zamiast tokena.
Prompt stylu zawodzi, gdy brzmi jak preferencja. Dobry prompt do przeglądu czyta się jak kontrakt: jasne rzeczy niepodlegające negocjacji, jasno nazwane wyjątki i przewidywalny wynik.
Zacznij od dwóch krótkich bloków: co musi być prawdą i co można odchylić. Dodaj regułę decyzyjną: „Jeśli niejasne, oznacz jako Needs Clarification. Nie zgaduj.”
Wymagaj dowodu. Gdy narzędzie zgłasza naruszenie, wymagaj, by cytowało dokładny identyfikator i ścieżkę pliku, a nie ogólny opis. To jedno ograniczenie usuwa wiele niepotrzebnych kłótni.
Zachowaj wąski zakres: komentuj tylko zmienione linie i bezpośrednio dotknięte ścieżki kodu. Jeśli pozwolisz na niepowiązane refaktory, egzekwowanie stylu zamieni się w „przepisz plik”, a ludzie przestaną ufać feedbackowi.
Oto struktura, której możesz używać ponownie:
Role: strict style guide reviewer.
Input: diff (or files changed) + style guide rules.
Non-negotiables: [list].
Allowed exceptions: [list].
Scope: ONLY comment on changed lines and directly impacted code paths. No unrelated refactors.
Evidence: Every finding MUST include (a) file path, (b) exact identifier(s), (c) short quote.
Output: structured compliance report with pass/fail per category + minimal fixes.
Wymagaj, aby raport zachował te same sekcje za każdym razem, nawet jeśli niektóre to „No issues found”: Naming, Layering, Error handling, Logging.
Jeśli raport mówi „service layer leaking DB details”, musi zacytować coś jak internal/orders/service/order_service.go i dokładne wywołanie (np. db.QueryContext), żebyś mógł naprawić wyciek bez debat o tym, co autor miał na myśli.
Przewodnik stylu przyjmie się, gdy proces będzie powtarzalny. Celem jest sprawić, by model sprawdzał reguły, a nie dyskutował o smaku, i robił to zawsze w ten sam sposób.
Użyj prostego workflowu dwupasmowego:
Przykład: PR dodaje nowy endpoint. Pass 1 zgłasza, że handler rozmawia bezpośrednio z PostgreSQL (warstwowanie), użyto mieszanych nazw w request structach (nazewnictwo) i loguje pełne adresy e-mail (logowanie). Pass 2 robi minimalne poprawki: przenieść wywołanie DB do serwisu lub repozytorium, zmienić nazwę structa i zamaskować e-mail w logach. Nic więcej się nie zmienia.
Problemy z nazewnictwem wydają się drobne, ale generują realne koszty: ludzie źle rozumieją intencję, wyszukiwania stają się trudniejsze, a „prawie takie same” nazwy się mnożą.
Określ reguły nazewnictwa, które recenzent musi egzekwować w całej zmianie: nazwy plików, typów eksportowanych, funkcji, zmiennych, stałych i testów. Bądź eksplicitny co do stylu zapisu (camelCase, PascalCase, snake_case) i wybierz jedną zasadę dla akronimów (np. APIClient vs ApiClient). Następnie wymagaj jej wszędzie.
Ustandaryzuj też wspólny słownik: typy błędów, pola logów i klucze konfiguracyjne. Jeśli logi używają request_id, nie pozwól reqId w jednym pliku i requestId w innym.
Instrukcja dla recenzenta, która pozostaje praktyczna:
Check every new or renamed identifier. Enforce casing + acronym rules.
Flag vague names (data, info, handler), near-duplicates (userId vs userID), and names that contradict behavior.
Prefer domain language: business terms over generic tech words.
Poproś o krótki raport: trzy najbardziej mylące nazwy, wszelkie near-duplicates i którą z nich zachować, plus nazwy logów/konfigów/błędów, które nie pasują do standardu.
Reguły warstwowania działają najlepiej w prostym języku: handlery obsługują HTTP, serwisy trzymają reguły biznesowe, repozytoria rozmawiają z bazą danych.
Zablokuj kierunek zależności. Handlery mogą wywoływać serwisy. Serwisy mogą wywoływać repozytoria. Repozytoria nie powinny wywoływać serwisów ani handlerów. Handlery nie powinny importować kodu bazy danych, helperów SQL ani modeli ORM. Jeśli używasz pakietów współdzielonych (config, time, IDs), trzymaj je wolne od logiki aplikacji.
Przydziel zadania przekrojowe do jednego miejsca. Walidacja zwykle należy do granicy (kształt requestu) i do serwisu (reguły biznesowe). Autoryzacja często zaczyna się w handlerze (tożsamość, zakresy), ale serwis powinien egzekwować ostateczną decyzję. Mapowanie dzieje się na krawędziach warstw: handler mapuje HTTP na wejście domenowe, repozytorium mapuje wiersze DB na typy domenowe.
Wrzuć to do prompta, by utrzymać przeglądy konkretne:
Check layering: handler -> service -> repository only.
Report any leaks:
- DB types/queries in handlers or services
- HTTP request/response types inside services or repositories
- repository returning DB models instead of domain objects
- auth/validation mixed into repository
For each leak, propose the smallest fix: move function, add interface, or rename package.
W raporcie bądź jawny: podaj plik, warstwę, do której należy, import lub wywołanie łamiące regułę i minimalną zmianę, która powstrzyma rozprzestrzenianie się wzorca.
Najgłośniejsze dyskusje o stylu pojawiają się, gdy coś psuje się w produkcji. Jasna polityka obsługi błędów utrzymuje naprawy w spokoju, bo każdy wie, jak wygląda „dobrze”.
Spisz filozofię i egzekwuj ją. Na przykład: „Owijaj błędy, by dodać kontekst; twórz nowy błąd tylko wtedy, gdy zmieniasz znaczenie lub mapujesz na komunikat użytkownika. Zwracaj surowe błędy tylko na granicy systemu.” To jedno zdanie powstrzyma losowe wzorce przed rozprzestrzenianiem się.
Oddziel teksty dla użytkownika od szczegółów wewnętrznych. Komunikaty dla użytkownika powinny być krótkie i bezpieczne. Wewnętrzne błędy mogą zawierać nazwę operacji i kluczowe identyfikatory, ale nie sekrety.
W przeglądach szukaj kilku powtarzających się błędów: błędy „przełknięte” (zalogowane, ale nie zwrócone), niejednoznaczne zwroty (nil wartość z nil błędem po niepowodzeniu) i komunikaty użytkownika, które wyciekają stack trace, tekst zapytania, tokeny lub PII. Jeśli wspierasz retry lub timeouts, wymagaj, by były jawne.
Przykład: wywołanie checkouta przekracza czas. Użytkownik widzi „Payment service is taking too long.” Wewnątrz owiń timeout i dodaj op=checkout.charge i ID zamówienia, żeby było wyszukiwalne i możliwe do podjęcia akcji.
Logi pomagają tylko wtedy, gdy wszyscy je piszą w ten sam sposób. Jeśli każdy deweloper wybiera własne sformułowania, poziomy i pola, wyszukiwanie zamienia się w zgadywankę.
Uczyń poziomy logów niepodlegającymi negocjacji: debug dla szczegółów deweloperskich, info dla normalnych kamieni milowych, warn dla nieoczekiwanych, ale obsłużonych sytuacji i error gdy akcja widoczna dla użytkownika zawiedzie lub wymaga uwagi. Traktuj „fatal” lub „panic” rzadko i powiąż je z jasną polityką crashu.
Logi strukturalne są ważniejsze niż idealne zdania. Wymagaj stabilnych nazw kluczy, aby dashboardy i alarmy nie przerywały działania. Wybierz mały, stały zestaw (np. event, component, action, status, duration_ms) i trzymaj się go.
Traktuj dane wrażliwe jako twarde zatrzymanie. Bądź eksplicitny, czego NIGDY nie wolno logować: hasła, tokeny autoryzacyjne, pełne numery kart, sekrety i surowe dane osobowe. Wymień rzeczy, które wydają się nieszkodliwe, ale nie są, np. linki do resetu hasła, identyfikatory sesji i pełne ciała żądań.
Identyfikatory korelacji umożliwiają debugowanie przez warstwy. Wymagaj request_id w każdej linii logu powiązanej z zapytaniem. Jeśli logujesz user_id, zdefiniuj, kiedy jest to dozwolone i jak reprezentować brak lub anonimowość użytkownika.
Blok prompta, który możesz używać ponownie:
Review the changes for logging conventions:
- Check level usage (debug/info/warn/error). Flag any level that does not match impact.
- Verify structured fields: require stable keys and avoid free-form context in the message.
- Confirm correlation identifiers: request_id on all request-bound logs; user_id only when allowed.
- Flag any sensitive data risk (tokens, secrets, personal data, request/response bodies).
- Identify noisy logs (in loops, per-item logs, repeated success messages) and missing context.
Return: (1) violations with file/line, (2) suggested rewrite examples, (3) what to add or remove.
Przed mergem zrób szybki „safety pass”: każdy nowy log bez request_id dla pracy w kontekście requestu, każdy nowy klucz zmieniający istniejące nazwy (userId vs user_id), każdy error log bez informacji, co zawiodło (operacja, zasób, status), każdy high-volume log, który odpali na każde żądanie, i każda możliwość pojawienia się sekretów lub danych osobowych w polach lub wiadomościach.
Traktuj dryf stylu jak błąd builda, nie sugestię. Dodaj ścisłą bramę, która uruchamia się przed mergem i zwraca jasne pass lub fail. Jeśli reguła mandatoryjna jest złamana (nazewnictwo, granice warstw, bezpieczeństwo logów, obsługa błędów), brama zawodzi i wskazuje dokładne pliki i linie.
Utrzymaj bramę krótką. Jednym praktycznym trikiem jest wymagać checklisty TAK/NIE dla każdej reguły i odmawiać zatwierdzenia, jeśli jakakolwiek pozycja to NIE.
Lista kontrolna wielkości PR, która łapie większość problemów:
Gdy narzędzie sugeruje poprawki, wymagaj małego, zgodnego fragmentu kodu dla każdej reguły, którą dotyka. To zapobiega niejasnemu feedbackowi typu „zmień nazwę dla jasności”.
Najszybszy sposób, by przewodnik stylu padł, to zostawić miejsce na interpretację. Jeśli dwóch recenzentów może przeczytać tę samą regułę i dojść do różnych wniosków, narzędzie będzie egzekwować gust, a nie standardy.
Nazewnictwo jest tu częstym przykładem. „Używaj czytelnych nazw” nie jest testowalne. Zaostrz to do weryfikowalnego zapisu: „funkcje są czasownikami (np. createInvoice), boole zaczynają się od is/has/can, eksportowane typy są w PascalCase.”
Inna pułapka to prośba o wszystko naraz. Gdy jeden prompt stara się objąć nazewnictwo, warstwy, błędy, logowanie, testy i wydajność, feedback robi się płytki. Dziel przeglądy na skoncentrowane przejścia, gdy potrzebujesz głębi, albo ogranicz bramę do reguł mandatoryjnych.
Problemy, które najczęściej powodują dryf egzekwowania:
Jeśli traktujesz prompt jak testy, dostaniesz przewidywalne egzekwowanie. Jeśli traktujesz go jak poradę, naruszenia wkradną się i pomnożą.
Przeprowadź szybki pass po diffie (nie całym repo) i potwierdź:
Trzymaj mały szablon prompta i wklejaj go przy każdej zmianie:
Review ONLY the changed code against our rules for naming, layering, errors, and logging.
List mandatory violations first (with file + line if available). Then list optional suggestions.
End with either: "no mandatory violations found" or "mandatory violations found".
Przykład: nowa funkcja procUsr() w handlerze, która pisze bezpośrednio do PostgreSQL, powinna nie przejść nazewnictwa i warstwowania, nawet jeśli funkcja działa. Wykrycie tego teraz zapobiega kopiowaniu błędu.
Kolega dodaje endpoint: POST /v1/invoices/{id}/send. Dotyka handlera, serwisu i storage.
W pierwszym przebiegu chcesz raport, nie rewrite:
Pass 1 (report only)
You are a strict style checker. Read the patch.
Rules: naming must match our guide, handlers call services only, services call storage only, no SQL in handlers,
errors must be wrapped with context, logs must be structured and not leak PII.
Output: a numbered list of violations with file:line, rule name, and one-sentence impact. Do not propose fixes.
If a rule might be intentionally broken, ask one clarification question.
Typowe wnioski: SendInvoiceNow() vs SendInvoice mismatch nazewnictwa, handler wywołujący db.QueryRow bezpośrednio, zwracanie surowego err bez kontekstu i hałaśliwe logi typu log.Printf("sending invoice %v", invoice) wypisujące całe obiekty.
Drugi przebieg prosi o minimalne, bezpieczne zmiany:
Pass 2 (minimal fix suggestions)
Using the violations list, propose the smallest code edits to comply.
Constraints: keep behavior the same, no refactors beyond what is needed, show suggested function names and where code should move.
For each fix, include 1-2 lines of example code.
Jeśli złamanie reguły jest dozwolone, powiedz to od razu: „Wyjątki są dozwolone tylko jeśli dodasz krótki komentarz wyjaśniający dlaczego i dodasz follow-up task, by wyjątek usunąć.”
Po poprawce handler staje się cienkim adapterem, serwis zarządza workflow, storage zawiera zapytanie, błędy są fmt.Errorf("send invoice: %w", err), a logi jedną czystą linią z bezpiecznymi polami (ID faktury, nie pełna faktura).
Wybierz jeden, zespołowo zatwierdzony prompt i traktuj go jak wspólne narzędzie. Zacznij od tego, co najbardziej was boli w przeglądach (dryf nazewnictwa, przecieki warstw, niespójne błędy, niebezpieczne logi). Aktualizuj prompt tylko gdy zobaczysz realne naruszenie w rzeczywistym kodzie.
Trzymaj mały blok reguł na górze prompta i wklejaj go do każdego przeglądu niezmieniony. Jeśli każdy będzie edytował reguły za każdym razem, nie będziesz miał standardu. Będziesz miał debatę.
Prosta kadencja pomaga: jedna osoba zbiera najważniejsze błędy stylu z tygodnia i dokładnie jedną regułę lub jeden lepszy przykład dodajecie do listy.
Jeśli pracujesz w flow zbudowanym wokół czatu jak Koder.ai (koder.ai), warto uruchamiać te same bramki w trakcie zmian, nie tylko na końcu. Funkcje takie jak planowanie, snapshoty i rollback pomagają trzymać poprawki stylu małe i odwracalne zanim wyeksportujesz kod źródłowy.