O czym jest ten film
- Różnica między vibe coderami, którzy wypuszczają realne produkty, a bohaterami memów, to nie talent ani narzędzia — to procesy, których się trzymają, i słownictwo, którym operują.
- Ramą całego materiału jest model „bram i sieci”: bramy mają nie dopuścić błędów do produkcji, sieci — wyłapać to, co się mimo wszystko przedostało.
- Fundamentem jest rozwój sterowany specyfikacją (OpenSpec, GitHub Spec Kit): specyfikacja jako kontrakt dla modelu, podział pracy na małe zadania i pełna identyfikowalność zmian.
- W plikach CLAUDE.md/AGENTS.md warto trzymać antywzorce i wiedzę, której nie da się wywnioskować z kodu; pliki można zagnieżdżać w podkatalogach, a najgroźniejszym wrogiem jest dokumentacja nieaktualna.
- Kontrola wersji to warunek konieczny: atomowe commity z uzasadnieniem, chroniony przepływ gałęzi i plan rollbacku.
- Testy definiują „zrobione” zanim powstanie kod: cykl czerwony–zielony–refaktor, warstwy testów, E2E na ścieżkach krytycznych i testy regresyjne po każdym bugu.
- Uwierzytelnianie i autoryzacja to dwa różne tematy — autoryzację trzeba wynegocjować z modelem i egzekwować w kilku warstwach, w tym w samej bazie (RLS).
- Dalej: obsługa błędów (granice błędów, walidacja wejść, retry), bazy danych (migracje, indeksy, zapytania N+1), bezpieczeństwo (OWASP Top 10, sekrety, luki w logice biznesowej) i hosting (środowiska, koszty).
- Wdrożenia robi się pipeline’em CI/CD na GitHub Actions, migracje według konwencji expand–migrate–contract, a wydania promuje do main dopiero po ręcznym sprawdzeniu podglądu.
- Obserwowalność — logi, metryki i ślady plus alerty — domyka całość: wiecie, co dzieje się w aplikacji na żywo, i naprawiacie, zanim napisze wam użytkownik.
10 najważniejszych takeaways — z kontekstem zastosowania
1.Specyfikacja zamiast improwizacji
Na czym polega: Vibe coding bez procesowych barier to najkrótsza droga do katastrofy. Narzędzia spec-driven development (OpenSpec, GitHub Spec Kit) zamieniają rozmowę z modelem w kontrakt: wymagania są ustalane i dokumentowane z wyprzedzeniem, duże zadania rozpadają się na małe kawałki, a każda zmianę da się prześledzić wstecz.
Jak stosować: Trzymać się przepływu: propozycja → specyfikacja → projekt systemu → zadania → implementacja i weryfikacja. Do generowanych zadań podpiąć skill programowania sterowanego testami. Skille innych autorów (np. Superpowers) można wpleść w oba narzędzia — to nie jest wybór „albo–albo”.
Na co uważać: Sam skill bez otaczającego go procesu nie wystarczy, jeśli nie macie własnych, sprawdzonych nawyków inżynierskich. Modele pójdą na łatwiznę przy zbyt dużym zadaniu — połamią je w połowie i narobią szkód, których może nawet nie zauważycie.
2.Dokumentuj to, czego model nie wywnioskuje z kodu
Na czym polega: W plikach CLAUDE.md (dla Claude Code) i AGENTS.md (dla innych agentów) najcenniejsze są dwie kategorie: znane antywzorce — czego model ma nie robić — oraz wiedza „niewywnioskowalna”, którą zna tylko wasz zespół, albo konwencje, których odkrywanie wymagałoby czytania pół repozytorium.
Jak stosować: Zagnieżdżajcie osobne pliki z instrukcjami w podkatalogach (API, interfejs, poszczególne moduły) — agent wchodzący do katalogu musi je przeczytać. Obszerny kontekst dużych modułów wynoście do osobnych plików i linkujcie z głównego pliku. Narzędzia pokroju Intent Layers potrafią takie mapy wygenerować automatycznie.
Na co uważać: Największa pułapka to dokumentacja zdezaktualizowana — model będzie się nią kierował i nie przyzna się do tego, a wy będziecie bić głową w ścianę. Dokumentacja musi być żywa; pomaga OpenSpec, bo zmiany przechodzą wyłącznie przez ustrukturyzowany proces.
3.Kontrola wersji to warunek konieczny produkcji
Na czym polega: Bez ustrukturyzowanej kontroli wersji nie ma aplikacji, do której użytkownicy wracają: nie wiadomo dokładnie, co zbudowano, zmiany nie powstają w bezpiecznym odosobnieniu i nie ma jak wrócić do stanu sprzed awarii.
Jak stosować: Atomowe commity — jedna logiczna zmiana na commit — z opisem tłumaczącym, dlaczego zmiana powstała. Praca na gałęziach funkcjonalnych lub git worktree, nigdy na main. Chroniony przepływ: zmiana idzie z gałęzi funkcjonalnej do develop, a dopiero develop otwiera pull request do main po przejściu testów.
Na co uważać: Modele z własnej inicjatywy nie robią atomowych commitów — trzeba to wymusić instrukcją lub skillem. „Brak strategii rollbacku” nie jest strategią: na produkcji coś padnie prędzej czy później, nawet w najlepszych firmach.
4.Testy definiują „zrobione”, zanim powstanie kod
Na czym polega: Testy to barierki dla człowieka i dla agenta — powstają przed kodem i mówią modelowi, co znaczy „napisane dobrze”. Fundamentem jest cykl czerwony–zielony–refaktor: najpierw test, który pada, potem minimalny kod, który go zalicza, na końcu refaktoring.
Jak stosować: Warstwy testów: jednostkowe na drobnych, deterministycznych kawałkach; integracyjne na współpracy serwisów; E2E (np. Playwright) na ścieżkach krytycznych dla pieniędzy — rejestracja przez Stripe, podnoszenie planu, główna funkcja produktu. Każdy napotkany bug zamieniajcie w test regresyjny, żeby nie wrócił z kolejnym PR-em.
Na co uważać: Modele bywają leniwe i napiszą test, który nie może paść — taki test niczego nie weryfikuje. Warto używać skilli wymuszających dyscyplinę (sekcja antywzorców testowych w Superpowers). Spory o idealny procent pokrycia są mniej ważne niż zasada: testujcie miejsca krytyczne i dopisujcie testy tam, gdzie mają sens.
5.Autoryzację trzeba wynegocjować i egzekwować w warstwach
Na czym polega: Uwierzytelnianie odpowiada na pytanie „kim jesteś?”, autoryzacja — „co wolno ci robić?”. Model sam z siebie nie ustali, kto może czytać które tabele: publiczną bazę produktów w aplikacji żywieniowej wyłapie, ale prywatnej tabeli przepisów użytkownika już nie.
Jak stosować: Usiądźcie z modelem i przejdźcie przez wszystkie tabele, schematy i interakcje, aż dla każdej encji ustalicie jasny wzorzec dostępu. Egzekwujcie go w kilku miejscach: w API po stronie serwera i dodatkowo w samej bazie — Row Level Security w Supabase zablokuje dostęp nawet wtedy, gdy bug pozwoli komuś ominąć API.
Na co uważać: Jedna warstwa obrony to za mało. W Supabase warto włączyć przełącznik „RLS domyślnie” przy zakładaniu projektu i wyłączać zabezpieczenie punktowo, tylko tam, gdzie jest to świadomie potrzebne.
6.Obsługa błędów projektuje się zawczasu
Na czym polega: Trzeba rozróżnić błędy oczekiwane — dostają czysty komunikat, np. „Nie udało się połączyć z usługą poczty. Kliknij »Spróbuj ponownie«” — od nieoczekiwanych, które przechwytuje globalny handler na granicach modułów, żeby awaria nie zbijała całej aplikacji i nie wyciekała użytkownikowi ze stack trace’em.
Jak stosować: Budujcie granice błędów (error boundaries) na froncie i na backendzie; błędy nie mogą „znikać” — wysyłajcie je do monitoringu typu Sentry. Walidujcie dane na wejściu i odrzucajcie śmieci wcześnie. Wywołania zewnętrznych API, zwłaszcza modeli językowych, owijajcie w timeouty i ponowienia.
Na co uważać: Model piszący kod „z pudełka” projektuje szczęśliwą ścieżkę, czyli scenariusz, w którym wszystko idzie dobrze. Użytkownik spamujący zepsuty endpoint potrafi rozsadzić limity u dostawcy LLM-a i zawiesić dostęp dla całej aplikacji.
7.Baza danych: migracje, indeksy i pułapka N+1
Na czym polega: Każda zmiana struktury bazy — nowe tabele, przemianowania, modyfikacje kolumn — powinna przechodzić przez system migracji, czyli kontrolę wersji schematu, z pełną historią i możliwością cofnięcia. Do tego dwa ciszące tematy wydajnościowe: indeksy na polach używanych do wyszukiwania i sortowania oraz zapytania N+1, czyli mnóstwo zbędnych rundek do bazy.
Jak stosować: Migracje wyłącznie przez narzędzie migracyjne, nigdy „na żywo” na produkcji. Przeglądajcie kod generowany przez agenta pod kątem pętli zapytań — kelner, który po każdym pojedynczym zamówieniu biegnie do kuchni, to dokładnie ten problem. Przy okazji sprawdzajcie, czy nowe zapytania mają indeksy.
Na co uważać: Agent sam nie założy indeksów ani nie usunie N+1 — trzeba go o to wprosc prosić lub użyć skilli. Surowa edycja tabel na produkcji to prosta droga do przestoju i utraty danych.
8.Bezpieczeństwo: gotowe skanery zamiast własnych promptów
Na czym polega: Bezpieczeństwo w vibe codingu załatwia się narzędziami: DeepSack jako nakładka bezpieczeństwa na agenta kodującego i repozytorium wtyczek Trail of Bits (audyty, przeglądy diffów, analiza statyczna). Do tego checklisty: OWASP Top 10 i zarządzanie sekretami.
Jak stosować: Przepuszczajcie aplikację przez głębszy skan cyklicznie — raz w miesiącu wystarczy jako kontrola. Skaner pre-commit niech blokuje commity z zaszytymi na stałe sekretami. Klawymi, służącymi do wyłapywania podatnych API i min projektowych, jest skill „sharp edges” z Trail of Bits.
Na co uważać: Nie budujcie własnego „skilla bezpieczeństwa” przez meta-promptowanie — bierzcie sprawdzone narzędzia. Modele bywają niekonsekwentne: przypominają, żeby nie wklejać sekretów, a same potrafią wczytać wasz plik .env. Pamiętajcie też o lukach w logice biznesowej: awaria może „otworzyć” dostęp do funkcji płatnych i kosztować was pieniądze.
9.Host dobierz pod siebie — i rozdziel środowiska
Na czym polega: Wybór hostingu powinien wynikać z dwóch wymiarów: waszego doświadczenia i modelu kosztowego aplikacji. Dla nie-inżynierów najrozsądniejsza jest platforma jako usługa (np. Vercel), a każdy TYPO zmian powinien być testowany na osobnym podglądzie, zanim trafi na produkcję.
Jak stosować: Wypychajcie wszystko na gałąź develop; po przejściu testów sprawdzajcie link podglądowy, próbujcie coś zepsuć i dopiero potem promujcie do main. Koszty w skali potrafi policzyć model — niech przejrzy kod, oszacuje zużycie tokenów i wywołań przy planowanej liczbie użytkowników i rozpisze rentowność różnych hostów.
Na co uważać: VPS czy AWS „bo przy milionie użytkowników wyjdzie taniej” to klasyczny przepis na katastrofę. Nieskalkulowane wywołania modeli językowych potrafią skończyć się rachunkiem za dziesiątki tysięcy dolarów.
10.Wdrożenia z filtrem CI/CD i obserwowalność z alertami
Na czym polega: Pipeline CI/CD (GitHub Actions: lint, sprawdzenie typów, testy, build) uruchamiany przy każdym pull requeście blokuje wdrożenie wszystkiego, co pada. Migracje wdraża się według konwencji expand–migrate–contract, żeby schemat i kod lądowały bez przestoju. Obserwowalność — logi, metryki i ślady — mówi wam, co dzieje się na żywo.
Jak stosować: W migracjach trzymajcie się kolejności: najpierw rozszerzenie schematu (nic jeszcze go nie czyta), potem wypełnienie danych i kod korzystający z nowych struktur, na końcu sprzątanie starego. W Sentry czy AppSignal ustawcie alert na każdy nowy nieobsłużony błąd złapany przez globalny handler.
Na co uważać: Wypchnięcie schematu bez kodu, który go czyta — albo odwrotnie — kładzie aplikację. A poleganie wyłącznie na screenshotach użytkowników jako źródle wiedzy o awariach to proszenie się o kłopoty.
Redakcyjne tłumaczenie
Wstęp: dwie odmiany vibe codera
Na świecie są dwa rodzaje ludzi kodujących z pomocą AI. Jedni faktycznie wypuszczają działające produkty. Drudzy stali się materiałem źródłowym na memy o vibe codingu — takie, o których internet nie może zamknąć ust. Różnica między nimi to nie talent i nie narzędzia. To procesy, których się trzymają, i słownictwo, którym operują.
(Informacja dodatkowa: „vibe coding” to potoczna nazwa stylu tworzenia oprogramowania, w którym kod pisze głównie model językowy — człowiek rozmawia z nim w narzędziu typu Claude Code, zamiast pisać samemu.)
W tym materiale przechodzę przez jedenaście obszarów, które trzeba opanować, żeby „wywibowana” aplikacja nie kładła się w momencie, gdy pierwszy prawdziwy użytkownik na nią spojrzy. Przy każdym wyjaśniam, o co konkretnie chodzi, i daję dwie–trzy rekomendacje. Jeśli któryś temat chcecie zobaczyć jako osobny film — dawajcie znać w komentarzach. A tak przy okazji: ten materiał, jak zwykle, sponsoruję sam; całość przerabiam szczegółowo w mojej płatnej społeczności.
Model myślowy: bramy i sieci
Zanim ruszymy, jedna rama pojęciowa, która spina całość: brama kontra sieć.
Gdy przenosimy coś do środowiska produkcyjnego, stawiamy bramy — mechanizmy, które w miarę możliwości mają nie dopuścić, żeby złe dane i złe zmiany w ogóle do niego trafiły. A sieci to to, co robimy, gdy coś mimo wszystko przeskoczyło bramę i zmierza już ku naszemu ładnemu domkowi. Potrzebujemy i jednego, i drugiego.
1.Spec-driven development: specyfikacja jako kontrakt
Pierwsza rzecz na liście jest według mnie absolutnym królem, jeśli chcecie budować rzeczy, które nie padają co chwilę, i chcecie mieć odwagę wypchnąć aplikację z nowymi funkcjami bez myśli „ciekawe, czy właśnie zepsułem ją wszystkim użytkownikom”. Tą rzeczą jest rozwój sterowany specyfikacją.
Vibe coding bez procesowych barier to najgorszy z możliwych przepisów na katastrofę. Jeśli używacie wyłącznie jakiejś wtyczki czy skilla i polegacie tylko na artefaktach, które ona tworzy — a nie jesteście inżynierem z własnym, wypracowanym zestawem systemów — będzie bardzo boleśnie. Jesteś vibe coderem w pierwszym rzędzie? Używaj narzędzia do spec-driven development. Będę tego bronił do upadłego w sporze z kimkolwiek.
Sam używam dwóch narzędzi. Pierwsze to OpenSpec — obecnie mój koń roboczy, zdecydowanie najczęściej używany. Drugie to GitHub Spec Kit — pierwsze narzędzie tego typu, jakiego w ogóle próbowałem, i wciąż bardzo solidne. Oba można rozszerzać o skille innych autorów: jeśli podoba wam się coś z biblioteki Superpowers (autor: obra), z bibliotek Matta Pococka czy z projektów z kręgu „compound engineering”, można te umiejętności i polecenia wpleść w sposób, w jaki używacie tych systemów. Nie jest to wybór „albo–albo”.
Dlaczego cenię te narzędzia? Trzy powody.
Po pierwsze, specyfikacja staje się kontraktem, do którego można zobowiązać model. Przechodzicie tam i z powrotem przez wymagania, ustalacie dokładnie, co ma być zrobione, a potem macie bardzo precyzyjne kryteria sprawdzenia, czy model faktycznie zrobił to dobrze — bo wszystko zostało udokumentowane w bolesnym szczególe jeszcze przed napisaniem pierwszej linijki.
Po drugie, specyfikacja pomiera duże zadania na małe, strawne kawałki, a to bezcenne. Większość modeli fatalnie radzi sobie z gigantycznym zleceniem obciążonym masą kontekstu tła — wyjątkiem był dla mnie tylko model Fable 5, którego kiedyś używałem. Zadanie za duże? Model namiesza w połowie, gwarantuję. A potem będziecie rozplątywać szkody — o ile w ogóle zauważycie, że robił też rzeczy, o które go nie prosiliście.
Po trzecie, identyfikowalność. W obu narzędziach wszystko, co budujecie, zostaje udokumentowane. W OpenSpec jest katalog changes: zapisuje artefakty powiązane ze zmianą, powiązane zgłoszenia z GitHuba i commity skojarzone z wykonaną pracą. Powstaje jasny ślad: co zrobiono, dlaczego i jak to przełożyło się na konkretne zmiany. Dwa tygodnie później, gdy odkryjecie buga, wracacie do dokładnie tego punktu — i cały kontekst czeka na miejscu.
Jak wygląda podejście OpenSpec? Mamy akcje, nie fazy. W praktyce proces biegnie tak: generujecie propozycję — pomysł na to, co budujecie. Z propozycji wynikają bardzo konkretne specyfikacje. Ze specyfikacji i propozycji powstaje projekt systemu, czyli co musi się wydarzyć, by te założenia ożyły. To wszystko trafia do kontekstu, z którego generują się zadania, a zadania się implementuje i weryfikuje. Powstaje przejrzysta linia decyzji, do której można wrócić w dowolnej chwili. Ja przy generowaniu zadań podpinam skill programowania sterowanego testami, żeby każde przechodziło przez cykl czerwony–zielony–refaktoring, o którym za chwilę.
GitHub Spec Kit rozwiązuje ten sam problem innym procesem: specify–plan–tasks–implement. Dwa różne rozwiązania, jeden cel: barierki, dzięki którym nie robimy dzikich rzeczy, które trafiają na produkcję, kładą aplikację i sprawiają, że nikt nie chce z niej korzystać.
Ale skąd model ma wziąć najlepszy możliwy kontekst do tych decyzji?
2.Dokumentacja projektu i pliki CLAUDE.md
Druga rzecz, absolutnie konieczna, jeśli chcecie sensownie wypychać kod na produkcję, to naprawdę dobra dokumentacja projektu, spięta poprawnie z plikami CLAUDE.md.
(Informacja dodatkowa: CLAUDE.md to plik z instrukcjami, które Claude Code czyta przed rozpoczęciem pracy nad projektem; analogiczną rolę w innych agentach pełni plik AGENTS.md.)
Od dwóch lat, odkąd vibe koduję, wymyślano mnóstwo wersji tego, co powinno się w takich plikach znaleźć. Modele się poprawiały i część tamtych porad zestarzała się — ale nie wszyscy nadążyli za czasem.
Według mojego doświadczenia najlepiej dokumentować dwie kategorie rzeczy. Pierwsza: znane antywzorce — wszystko, co odkryliście, że model na pewno nie powinien robić. Druga to coś, co nazwałem „niewywnioskowalnymi”: wiedza, której nie da się łatwo wydedukować z samego kodu, bo z jakichś powodów zna ją tylko wasz zespół. Do tego dochodzą rzeczy, które agent co prawda mógłby zrozumieć, ale musiałby w tym celu przeczytać mnóstwo plików — a wy mogliście mu po prostu opisać konwencję w dwóch zdaniach. Temat zasługuje na osobny materiał, ale kierunkowo: antywzorce plus wszystko to, czego agent się nie domyśli, chyba że przeczyta pół repozytorium albo wasze myśli.
Bardzo cenna praktyka — również do umieszczenia w CLAUDE.md — to zawężanie kontekstu i wskaźniki. Niewielu ludzi wie, że pliki tego typu można zagnieżdżać w projekcie. Standardowo każdy myśli o jednym pliku w katalogu głównym. Ale jeśli macie cztery podkatalogi — na endpointy API, na interfejs aplikacji, na resztę — każdy z nich może mieć własny plik CLAUDE.md albo AGENTS.md. Agent wchodzący do pracy w danym katalogu musi go przeczytać; to jak dołączanie kolejnych instrukcji systemowych w momencie wejścia w konkretny obszar. Efekt: ważny kontekst zbieracie w osobnym pliku z opisem, jak wszystko działa, a w pliku głównym dajecie do niego link.
Dobry przykład z dżungli: biblioteka skilli Intent Layers robi dokładnie to. Przeszukuje projekt, znajduje bardzo duże katalogi (granicą jest, o ile pamiętam, 20 tysięcy tokenów), tworzy dla każdego osobny plik z opisem zamkniętych w nim plików, serwisów i logiki, a potem linkuje go w waszym pliku projektu. Skoro agent wie, że musi zaktualizować usługę płatności, wie też dokładnie, gdzie poczytać dokumentację tej warstwy. Przy okazji: część moich widzów donosi, że ten skill już nie działa — mam go sklonowanego na swoim repozytorium, możecie poklikać sami.
Ostatnia rzecz, nieunikniona: projekt rośnie, wypychacie rzeczy do ludzi — i zaczynacie zapominać, co zrobiliście. Jeśli w dokumentacji zostały informacje nieaktualne albo po prostu błędne, a tego nie wyłapiecie, będzie ciężko. Każda zastała notatka o decyzji architektonicznej albo o tym, dlaczego jakiś komponent wygląda tak, a nie inaczej, będzie boleśnie dawać o sobie znać. To jeden z najbardziej wkurzających trybów awaryjnych tych modeli — gwarantuję, że w niego wpadniecie, jeśli nie będziecie na bieżąco aktualizować dokumentacji.
I nie zdajecie sobie sprawy, skąd problem naprawdę bierze się, bo model wam tego nie powie. Nie usłyszycie: „no tak, podejmuję tę decyzję, bo w jednym pliku jest komentarz, że tego nie wolno zmieniać, więc kombinowałem wokół niego”. A to brzmiałoby nawet sensownie — faktycznie mieliście to zapisane. Model jednak milczy, wy bijecie głową w ścianę, a problem rozwiążecie dopiero wtedy, gdy sami wejdziecie i zrozumiecie, jak projekt jest pomyślany. Jeśli tego nie ogarniecie, będzie bardzo brudno.
Dlatego lubię OpenSpec: każda zmiana staje się częścią żywej dokumentacji, a modyfikować można ją wyłącznie przez strukturalne zmiany przechodzące przez proces. Nie zdarza się sytuacja, w której dokumentacja całkiem się zdezaktualizowała i wprowadza model w błąd.
Oddalmy się teraz na moment i spójrzmy z lotu ptaka. Ustaliliśmy, że musimy być bezwzględni w dokumentowaniu tego, jak działa nasz kod, i że budujemy na szynach — mamy system, który przepycha nas przez bardzo ustrukturyzowany, czasem zdeterminowany sposób budowania. Ale jak to konkretnie robić? Następne dziewięć rzeczy to sedno — to, co daje wam pewność, że aplikacja w rękach ludzi nie będzie się sypać.
3.Kontrola wersji
Trzeci obszar: kontrola wersji. Bez ustrukturyzowanego systemu kontroli wersji nigdy — przenigdy — nie będziecie mieli aplikacji, do której realni użytkownicy wracają. Nie zdarzy się. Dlaczego? Bo kontrola wersji daje nam systemy i procesy, żeby wiedzieć, co budujemy, budować w bezpiecznym, odosobnionym środowisku i mieć mechanizmy powrotu do wcześniejszych stanów, gdy coś się jednak zepsuje.
Trzy rekomendacje.
Pierwsza: atomowe commity. Jedna logicznie wyodrębniona zmiana na commit. Model językowy nie zrobi tego z własnej inicjatywy — potrzebny jest skill albo instrukcja. Równie ważny jest dobry opis commita, tłumaczący, dlaczego zmiana powstała. Przydaje się przy przeglądach nastawionych na wyłapywanie błędów i przy fazach weryfikacji w OpenSpec: wracając, chcecie zobaczyć nie tylko co zcommitowano, ale i jaka była intencja.
Druga: strategia gałęzi i przepływu pull requestów. Zawsze pracujcie na gałęziach funkcjonalnych albo git worktree, nigdy nie commitujcie na main. I miejcie udokumentowaną, chronioną strukturę przechodzenia zmian do aplikacji. W jednym z moich projektów obowiązuje zasada: zwykły użytkownik ani agent nie może otworzyć pull requesta bezpośrednio do main. Zmiana przechodzi z gałęzi funkcjonalnej do develop i dopiero develop może otworzyć PR do main, promując wszystkie zmiany po przejściu testów.
Trzecia: rollbacki i odtwarzanie. Coś się zepsuje — na pewno. Psuje się nawet w najlepszych firmach. Musicie wiedzieć, które wersje działały, i umieć przywrócić aplikację do tego punktu. To nie jest temat do odhaczenia jednym skillem, który załatwia kawałek roboty; „nie mieć żadnej strategii” nie jest strategią. Za chwilę powiemy sobie, co konkretnie robić, gdy produkcja już się sypie i jak wykorzystać kontrolę wersji do powrotu do działającego stanu.
4.Testy
Wszyscy wiemy, co to testy: budujecie coś i sprawdzacie, że działa. Jak zaraz omówimy, można je odpalać automatycznie przed każdym wdrożeniem, żeby nic zepsutego nie wyleciało do ludzi. Najlepiej myśleć o nich jak o barierkach — dla was, ale i dla agenta. Testy prowadzą agenta za rękę: definicja „zrobione dobrze” powstaje, zanim agent napisze jakikolwiek kod.
Pierwsza rekomendacja: czerwony–zielony–refaktor. Bardzo popularny cykl. Jeśli lubicie bibliotekę Superpowers — a jestem jej fanem — ma skill programowania sterowanego testami, który gorąco polecam; on właśnie ten proces realizuje. Na czym polega? Najpierw piszecie test, który pada, i upewniacie się, że faktycznie pada. Potem piszecie minimum kodu, żeby go zaliczyć. Na końcu refaktorujecie tak, by nadal był zaliczony, a kod był w najlepszej formie. W projekcie, na którym wam zależy — używajcie. W sprzymierzonym, hobbystycznym gruncie, tylko dla siebie — nie musicie. Ja łączę to z OpenSpec: cykl jest wbudowany w generowane zadania.
Druga: co właściwie testować? Są różne typy testów. Jednostkowe sprawdzają odseparowane kawałki — czy jeden plus jeden to dwa, czyli że nie zepsuliśmy funkcji sumującej. Integracyjne — współpracę kilku serwisów. End-to-end, na przykład z Playwrightem, realnie operują przeglądarką na ścieżkach krytycznych. E2E stawiam na ścieżkach pieniężnych, kluczowych dla biznesu: integracja ze Stripe — czy użytkownik rzeczywiście potrafi się zapisać i podnieść plan; czy najważniejsza, wartościotwórcza funkcja aplikacji działa. Testy jednostkowe są szybkie, bo testują odseparowane, deterministyczne rzeczy. Są bardziej zaawansowane techniki, których tu nie będę omawiać — na przykład mutowanie kodu i sprawdzanie, czy testy dalej padają. Ogólnie: patrzcie, jakich testów używa wasz agent i czy macie sensowne pokrycie projektu. Ile procent pokrycia? Temat dyskusyjny. Jeśli kierunkowo testujecie miejsca krytyczne i dopisujecie testy tam, gdzie mają sens — będziecie w niezłej pozycji.
Trzecia: testy regresyjne. Każdy bug w aplikacji to od dziś nowy przypadek testowy. Piszecie test, który pokazuje, że błąd występuje, poprawiacie — i żaden kolejny PR nie może już tego buga przywrócić, bo test na niego pilnuje. Nabierzcie nawyku: przy każdej poprawce błędu powstaje test. Połączcie to z kontrolą wersji i opisami commitów: gdy test regresyjny kiedyś znowu spadnie, model może wrócić, przeczytać, jak i dlaczego poprawiał ostatnio, zrozumieć, co nowego narobił, i naprawić.
Bonus: modele są leniwe i będą próbowały ten proces omijać. Potrzebujecie skilli, które odpychają je od antywzorców — z tego samego powodu cenię superpowers z sekcją antywzorców testowych. Nie załatwia wszystkiego, ale dużo pomaga. I uwaga na testy, które przechodzą zawsze, bo nie mogą paść — one niczego nie testują.
5.Uwierzytelnianie i autoryzacja
Formalnie to temat bezpieczeństwa, ale uczę ich osobno, bo początkujący mylą te pojęcia. Zresztą autoryzacji modele językowe — w wersji podstawowej, bez nadzoru — nie robią dobrze. Same z siebie nie wiedzą, kto w waszej aplikacji co może.
Różnica jest prosta: uwierzytelnianie odpowiada na pytanie „kim jesteś?”, autoryzacja — „co wolno ci robić?”. Wracając do naszej bramy: uwierzytelnianie to „czy w ogóle możesz wejść przez drzwi do mojego kompleksu”, autoryzacja — „do których pomieszczeń w moim domu możesz wejść”. Do sypialni nie wejdziesz. Do skarbca ze sztabkami również nie.
Konkretny przykład: użytkownik Joe loguje się, potwierdzacie jego tożamość — to Joe, czego chcesz, Joe? — a on odpowiada: „chcę wszystkie dane osobowe Ann”. Powinien móc? Zależnie od kontekstu aplikacji, ale zwykle nie — i model tego sam z siebie nie ustali. Musicie z nim realnie popracować. Przykład z życia: w aplikacji od żywienia może istnieć publiczna baza produktów, z której każdy czyta, obok prywatnej tabeli przepisów, czytelnej wyłącznie dla właściciela. Model tego nie wywnioskuje — trzeba mu powiedzieć.
Pierwsza rekomendacja: przepytywanie. Przechodzę z modelem przez wszystkie tabele, schematy i interakcje, aż dla każdej encji ustalimy jasny wzorzec dostępu: kto może, a kto nie. Druga: egzekwujcie autoryzację w wielu miejscach. W API po stronie serwera — i dodatkowo w samej bazie danych. Jeśli widzieliście w Supabase dyskusje o Row Level Security, o to właśnie chodzi. Gdyby Joe — przez buga albo złośliwość — ominął sprawdzanie w API i sięgnął po tabelę Ann, RLS może to zablokować. Warstwy obrony, szczególnie przy autoryzacji i uwierzytelnianiu. To nie jest najbardziej techniczny temat świata — wymaga po prostu usiąścia i przepytywania modelu, aż zablokuje właściwe reguły dostępu do wszystkiego.
Bonus: Supabase ma teraz przy zakładaniu projektu przełącznik „włącz RLS domyślnie”. Włączajcie. Wyłączajcie pojedynczo, tylko gdy wiecie, że trzeba.
6.Obsługa błędów
Kolejny obszar, przy którym modele językowe — przynajmniej dzisiaj — są słabe. Sam musiałem pisać własne skille. Chodzi o to, co się dzieje, gdy coś w aplikacji pada: czy kładzie się całość, czy tylko zawartość w osobnym, schludnym pudełku? Czy reszta działa dalej, czy dostajemy niebieski ekran śmierci? Pozdrowienia dla dzieciaków Windowsa z lat 90.
Są dwa typy błędów: te, których się spodziewamy, i kompletnie nieoczekiwane. Oczekiwany błąd obsługuje się czystym komunikatem dla użytkownika: „Nie udało się połączyć z usługą poczty. Kliknij »Spróbuj ponownie«”. Elegancko, kulturalnie. Nieoczekiwane — te, których jeszcze nigdy nie widzieliśmy — trzeba przechwytywać i kierować do globalnego handlera. W aplikacji powinny istnieć globalne punkty przejmujące awarię na określonych granicach. I nie wysyłamy nikomu stack trace’ów ani nic wrażliwego. Jeśli pracowaliście w Next.js i poznaliście ten wielki brzydki boksu z listą miejsc, w których wszystko pękło — wiecie, czego użytkownik dostać nie powinien. A dostanie, jeśli tego nie zaprojektujecie.
Druga zasada: nie połykajcie błędów. Budujcie granice błędów na froncie i na backendzie. Granica to logicznie wyodrębniona część kodu, w której awaria ma zostać zawarta. Ale błądu nie ignorujemy — dlatego warto używać Sentry i podobnych narzędzi: komunikaty trafiają do monitoringu i widzicie, że coś się dzieje, zanim fala użytkowników odejdzie, a wy będziecie mieć bardzo zły czas.
Trzecia rzecz: walidacja wejść i ponowienia. Model piszący kod z pudełka projektuje szczęśliwą ścieżkę, czyli scenariusz, w którym wszystko idzie dobrze. Walidujcie dane na froncie i odrzucajcie śmieci wcześnie: oczekujecie liczby, przychodzi tekst? Niech to nie dolatuje do backendu. A wywołania API — zwłaszcza do modeli językowych — owijajcie w timeouty i retry. Inaczej użytkownik będzie mógł spamować zepsuty endpoint, rozsadzić wam limity u dostawcy LLM-a i narobić kosztów, a w efekcie wszyscy w aplikacji zostaną zawieszeni, bo ktoś niechcący katował punkty końcowe.
Dla jasności: to nie jest wyczerpujące omówienie żadnego z tych tematów. Każdy schodzi znacznie głębiej — omawiam po dwa–trzy elementy, a realnie jest ich dziesiątki. Chodzi o to, że jeśli nie pokrywacie choćby tych podstaw, to jest pierwsza lista do odhaczenia.
Punkt kontrolny: co już mamy
Zanim pójdziemy dalej, żeby się nie pogubić. Wiemy już: jak budować na szynach, żeby było jasne, co powstaje i dlaczego; jak dokumentować wiedzę i wnioski tak, by były żywe i świeże przy każdym uruchomieniu modelu; jak ustawić kontrolę wersji, by nowe rzeczy nie zabiły starych; jak dodawać testy w trakcie budowy; jak załatwić najniżej wiszące owoce bezpieczeństwa vibe codera, czyli uwierzytelnianie i autoryzację; i jak obsługiwać błędy, żeby użytkownik nie zobaczył nic brzydkiego. Wszystko to jest w stu procentach konieczne, jeśli chcecie wypchnąć aplikację na produkcję. Zaraz zejdziemy głębiej — we wdrożenia i bezpieczeństwo — ale najpierw temat, który wygląda podejrzanie prosto, a zamienia się w bezradne zamrożenie w momencie, gdy w aplikacji pojawiają się prawdziwi ludzie i trzeba coś zmieniać. Czyli bazy danych.
7.Bazy danych
Przyznam się: bazy danych wyglądają na proste. Supabase, zakładasz tabele, wrzucasz dane — Claude i tak robi całą robotę. Aż przychodzi moment, w którym obsługujesz wielu użytkowników i jeszcze budujesz nowe rzeczy. Wtedy jest jedna z dwóch sytuacji: albo błogo nie wiecie, jakie problemy na was czekają, albo wiecie — i właśnie to was blokuje przed publikacją, bo boicie się tej konsekwencji. Pokażę rzeczy, które nie są oczywiste, dopóki nie przeżyjecie ich w praktyce. To, że trzeba rozumieć modele danych i relacje między nimi — to akurat prostsze.
Po pierwsze: migracje. Każda zmiana struktury bazy — przemianowanie tabeli, nowa tabela, modyfikacja kolumny — powinna przechodzić przez system migracji. Dwie drogi: surowa aktualizacja tabel, czego nie polecam, albo narzędzie do migracji. Migracje to kontrola wersji dla schematu bazy: pełna historia zmian, możliwość cofnięcia się i przejścia naprzód. Po prostu dużo bezpieczniej.
Po drugie: wydajność. Myśląc o wydajności, skupiamy się zwykle na kodzie, aplikacji, froncie — a sposób, w jaki rozmawiamy z bazą, ma ogromne znaczenie. Pierwszy element to indeksy. Jeśli jakaś informacja służy stale do wyszukiwania albo sortowania — załóżcie indeks. Wyobraźcie sobie księgę telefoniczną ułożoną losowo: szukając nazwiska, przewertowalibyście wszystko. Indeks to ułożenie alfabetyczne: strona na „K”, potem „Ko”, i nazwisko „Kochel” leży na miejscu. Ogromny wpływ na szybkość. Jeśli budowaliście aplikacje bez indeksów — to jedna z najtańszych i najbardziej efektownych poprawek. I uwaga: Claude Code sam tego nie zrobi.
Drugi element to zapytania N+1. Też nie coś, co model naprawi z pudełka. Chodzi o kod, który wykonuje wielokrotnie więcej rundek do bazy niż trzeba. Kelnerska analogia: kelner podchodzi, przyjmuje wasze zamówienie, biegnie z nim do kuchni, wraca, przyjmuje zamówienie drugiej osoby, znowu biegnie do kucharza… a potem to samo z napojami. Piętnaście podróży tam i z powrotem na coś, co dało się załatwić jednym zamówieniem dla całego stołu. Niestety, to bardzo częsty wzorzec w kodzie, który piszą modele językowe — a nie chcecie go mieć.
Trzecia rzecz wraca do bezpieczeństwa, ale jest ważna: Row Level Security. Zamykajcie tabele tak, by ludzie mieli dostęp wyłącznie do tego, do czego mają. W logice aplikacji — i dodatkowo w samej bazie.
8.Bezpieczeństwo
Z całej listy to obszar, który trzeba dopiąć najlepiej. Na szczęście jest sporo świetnych narzędzi open source; wskażę dwa.
Moje ulubione: DeepSack — nakładka bezpieczeństwa dla waszego agenta kodującego. Nie jest tani, powiem wprost, więc odpalałbym go na licencji Claude Code albo Codex. To narzędzie zrobiło na mnie wrażenie: wykrywało w mojej aplikacji problemy tak nieoczywiste, że dla mnie wyglądały na ukryte, a mogły skończyć się dużym kłopotem. Szukacie solidnego skanera bezpieczeństwa — bardzo polecam; linki do moich materiałów znajdziecie w opisie. Z lżejszej, w pełni otwartej strony: firma Trail of Bits, badacze bezpieczeństwa, prowadzi znakomite repozytorium pełne wtyczek — audyty aplikacji, przeglądy diffów pod kątem bezpieczeństwa, wyszukiwanie niebezpiecznych ustawień domyślnych, analiza statyczna. Masa rzeczy. To nie jest obszar, w którym sami tworzylibyście promptem „jak powinien wyglądać skill bezpieczeństwa” — bierzcie gotowe narzędzia.
Kilka rzeczy do przemyślenia. Autoryzację i uwierzytelnianie już omówiliśmy. Po pierwsze: lista OWASP Top 10 — zestaw dziesięciu najczęstszych podatności, publikowany i aktualizowany mniej więcej co kilka lat. Trzymajcie go jako checklistę przy każdej pracy z czymkolwiek choć trochę wrażliwym; istnieją skanery, a choćby Trail of Bits sprawdza część pozycji.
(Informacja dodatkowa: OWASP — Open Worldwide Application Security Project, organizacja non-profit zajmująca się bezpieczeństwem aplikacji internetowych.)
Po drugie: zarządzanie sekretami. Klucze powinny mieszkać w zabezpieczonym środowisku — na przykład w zmiennych konfiguracji wdrożenia na Vercelu — a nie w kodzie frontu. Wydawałoby się oczywiste, a modele wciąż bywają w tym niekonsekwentne: z jednej strony przypominają, żeby nigdy nie wklejać im sekretów, a z drugiej same czytają wasz plik .env i przepraszają: „ups, przypadkiem go otworzyłem, lepiej wymieńcie wszystkie klucze API”. Najprostsza obrona: skaner pre-commit w projekcie. Przed każdym commitem do gita sprawdza zmiany i blokuje zaszyte na stałe sekrety. Banalne do zrobienia, a mało kto o tym myśli — a potem sekret ląduje w historii GitHuba i kiedyś może to wyjść bokiem.
Po trzecie, rzecz mniej intuicyjna, którą Vercel wielokrotnie wyłapywał za mnie: błędy logiki biznesowej potrafią otwierać realne dziury. Można zbudować coś w Claude Code w sposób, który jest po prostu niebezpieczny, choć się o tym nie wie. Przykład: nie obsłużycie błędu, ktoś wysyła zły request do backendu i coś się wykłada — „no dobra, coś padło”. Ale co ta awaria komu umożliwia? O tym mało kto myśli. Bez zabezpieczeń system może paść na otwarte: użytkownik planu darmowego po błędzie dostaje dostęp do funkcji planu pro, zaczyna szarpać API i budzicie się bez pieniędzy i w bardzo złym humorze. Trzeba kazać modelom przemyślać takie scenariusze — i dlatego sięga się po skanery, które już wiedzą, czego szukać. W skillach Trail of Bits jest na przykład „sharp edges”: wyłapuje podatne na błędy API, niebezpieczne konfiguracje i projektowe miny. Rekomendacja: jeśli macie plan Claude Max, przepuśćcie aplikację przez DeepSack chociaż raz w miesiącu jako kontrolę — nie musicie na co dzień.
9.Hosting
Dziewiąty temat: hosting. Wybierajcie hosta według dwóch wymiarów — waszego poziomu doświadczenia i modelu kosztowego aplikacji. Jeśli nie jesteście inżynierem, bierzcie platformę jako usługę, na przykład Vercel: cała inżynieryjna małpia robota jest tam za was ogarniana, a wdrożenie w zabezpieczone środowisko jest banalnie proste. To bezdyskusyjnie moja rekomendacja numer jeden. Nie zapisujcie się na Hostinger, nie bierzcie VPS-a, nie wdrażajcie na AWS czy Google Cloud, bo „przy milionie użytkowników wyjdzie taniej”. To pewny przepis na katastrofę. Wybierajcie pod siebie — nie pod to, co każe losowy człowiek z internetu.
Druga rzecz w kontekście platform: rozdzielajcie środowiska. Na Vercelu każde opublikowanie wersji ma podgląd. Klikam „preview” starszego wdrożenia, loguję się — i to nie jest wersja na żywo; to migawka tego, jak aplikacja wyglądała w tamtym punkcie czasu. To bezcenne, bo oddziela produkcję, gdzie mieszka główna aplikacja, od możliwości wystawienia zmian na osobnym podglądzie i przetestowania ich. Mój przepływ: wszystko idzie na gałąź develop; testy przechodzą; Vercel buduje aplikację i daje link podglądowy; wchodzę, loguję się, sprawdzam nowe funkcje, próbuję coś zepsuć — i dopiero gdy jestem zadowolony, promuję do main, czyli do wersji żywej. Podglądy Vercel są darmowe, więc w moich oczach nie ma powodu z nich nie korzystać.
Trzecia rzecz: skala i koszty. Zastanówcie się, jak wybrany host skaluje się do poziomu, którego się spodziewacie, jak znosi obciążenie — i jak to się przekłada na koszty u tego dostawcy. Nie umiecie liczyć wywołań edge functions? Zlećcie to modelowi: niech przejrzy kod, zrozumie serwisy istotne dla hostingu, przyjmie planowaną liczbę użytkowników i rozpisze wam marżę — analizę kosztów i korzyści różnych hostów — a wy podejmiecie decyzję na jej podstawie. Konkretnie z mojej aplikacji: prowadzę tracker jedzenia z funkcjami agentowymi, baza leży na Supabase, aplikacja idzie do App Store, a wywołania modeli językowych idą przez edge functions Supabase. Policzyłem — z pomocą modelu — oczekiwane zużycie tokenów na poszczególne funkcje, pozostałe koszty i marżę, i sprawdziłem, jak Supabase zniesie skalę użytkowników. Bez tego można obudzić się rano z rachunkiem za dwadzieścia tysięcy dolarów, bo zarządzało się czymś na Google Cloud, zamiast tego nie robić.
10.Wdrożenia: pipeline, migracje, bezpieczne wydania
Mamy hosta — jak doprowadzić do niego kod? Pierwsze: pipeline CI/CD, czyli ciągła integracja i wdrożenia. Chodzi o to, jak to, co budujecie na komputerze, trafia do hosta z całą machiną kontroli. Najprostsza droga dla początkującego i vibe codera: GitHub Actions. Tworzycie workflow — można poprosić model, zrobi to w minutę — który odpala cztery rzeczy: lint projektu, sprawdzenie typów, pełny zestaw testów (cokolwiek padnie, wdrożenie nie ruszy) i na końcu build aplikacji. Całość uruchamia się przy każdym pull requeście. Sukces? Dostajecie link podglądowy na Vercelu, klikacie, sprawdzacie. Porażka? Poprawiacie to, co padło. Chodzi o jedno: nie pchamy nic na żywioczo do main i nie pozwalamy, by się sypało.
Druga rzecz — szczerze mówiąc, najbardziej ekscytująca w całym materiale. Przy vibe kodowaniu nie przeszkadza wam, gdy coś padnie w środowisku deweloperskim: „aha, nie odpaliłem migracji, dlatego mi się sypie”. Ale to nie może się zdarzyć w rękach użytkownika. Istnieją konwencje robienia migracji porządnie — nie twierdzę, że moja jest jedyna słuszna, ale pokażę, jak wygląda mój proces. Nie wymyśliłem go sam.
Przypomnienie: migracja oznacza, że zmieniliśmy schemat bazy i najpewniej też kod, a tańczymy, żeby jedno i drugie wylądowały razem. Wypchnięty schemat bez kodu, który go czyta? Aplikacja pada. Wypchnięty kod, którego schemat jeszcze nie ma? Aplikacja pada. Konwencja nazywa się expand–migrate–contract.
Faza expand: dodajemy wszystkie nowe kolumny — zmieniane, świeże, jakiekolwiek — i wypychamy migrację. Żaden kod jeszcze ich nie czyta, bo kodu nie wypchnęliśmy. Nic się nie wykłada. Cała stara struktura zostaje na miejscu, bo stary kod wciąż czyta stary schemat.
Faza migrate: wypełniamy dane, jeśli trzeba — przemianowaliśmy kolumnę albo trzeba przenieść dane do nowej — i wypychamy kod, który czyta rozszerzony schemat. Stary schemat nadal tam jest; po prostu mówimy: „nie czytasz już tego, oto nowa logika, nowe tabele, nowe kolumny”. Nic nie próbuje czytać starych struktur, więc nie ma problemu.
Faza contract: gdy nowa wersja jest przetestowana i działa, usuwamy stare fragmenty schematu, których już nie potrzebujemy.
To rozwiązuje problem orkiestracji kolejności: modyfikacje bazy plus kod, który je czyta, lądują w takiej kolejności, że użytkownicy nie doświadczają przestoju ani zepsutych funkcji.
Trzecie: bezpieczne wydania. Najlepiej, żeby host wspierał adresy podglądowe; jeśli nie — miejcie osobne środowisko staging albo deweloperskie. Zmiany trafiają do bezpiecznej przestrzeni, testujecie je tam ręcznie, a dopiero gdy wszystko gra, promujecie do main. I zgodnie z powyższym: migracje bazy odpalamy przed wypchnięciem kodu, który ich wymaga.
11.Obserwowalność
Ostatni temat listy. Mówiliśmy o budowaniu, dokumentacji, kontroli wersji, testach, zamykaniu aplikacji, obsłudze błędów, bazach, bezpieczeństwie, hostingu i wdrożeniach. Ale skąd w ogóle wiemy, co dzieje się w aplikacji? Pojawiają się błędy — skąd wiemy? Wypchnęliśmy nową wersję i błędów przybyło — która to wersja, do którego commita się odnosi? Nie możemy przecież czekać, aż użytkownik przyśle zrzut ekranu. To właśnie jest obserwowalność.
Produktów jest sporo; pokazuję AppSignal, bo ich strona ma świetny charakter i świetnie tłumaczy funkcje, a Sentry historycznie używam w swoich projektach. Trzy elementy.
Logi: scentralizowane miejsce, na przykład w Sentry, do którego trafiają ważne zdarzenia — niekoniecznie błędy. Do zdarzenia dołączacie identyfikator żądania i choćby identyfikator użytkownika, żeby wiedzieć, kto i co robił. To jak dopracowany console.log, z tą różnicą, że dane realnie lecą do systemu monitorującego. Sentry ma skille i serwery MCP, które pomogą to spiąć.
Metryki: pulpity ze wskaźnikami. Przykład: używacie OpenAI do jakiejś funkcji AI i nagle widzicie ostry wzrost błędów 500 — a metryki wskazują wprost na integrację z OpenAI. Coś jest wyraźnie zepsute. Czy ostatnio wdrażałem zmianę, która to mogła złamać? Czy to błąd po stronie OpenAI? Co się dzieje? Bez tego zgadujecie. Metryki pozwalają śledzić takie rzeczy, budować pulpity i dostawać alerty po przekroczeniu progów.
Ślady (traces): błędy wyłapane przez obsługę z poprzednich sekcji wysyłamy do Sentry — widzimy dokładny błąd, komunikat i pełny przebieg: jak dane płynęły przez aplikację, zanim doszło do awarii, i jakie kroki poprzedzały moment, w którym się zaczęła. I alerty. Konkretny przykład: chcę dostawać powiadomienie o każdym nowym, nieobsłużonym błędzie złapanym przez globalny handler — wtedy wchodzę, oglądam, w razie potrzeby odzywam się do klienta i łatam, póki sprawa nie urosła.
Zakończenie: systematyczność robi różnicę
To nie jest kompendium, które wyczerpuje każdy temat — każdy z nich schodzi znacznie głębiej; samo tematy baz danych to realnie dziesiątki zagadnień, a ja dotknąłem po kilka. Ale jeśli waszym zmartwieniem jest „skąd wziąć pewność, żeby przejść z MVP na produkcję”, wracamy do bram i sieci. Bramy: budujemy mądrze, żeby złe rzeczy w ogóle nie dochodziły do ludzi. Sieci: wyłapujemy to, co się przemknęło, i naprawiamy.
Weźcie firmę taką jak Cal AI — niedawno przejętą za pokaźne pieniądze, a była to aplikacja wywibowana. Czym — poza marketingiem — różni się zespół, który to osiągnął, od setek vibe-codingowych demo? Tym, że robi te wszystkie rzeczy systematycznie. Jasna dokumentacja, wszystko pod kontrolą wersji, testy pisane na bieżąco, bezpieczeństwo załatwione, obsługa błędów pozwalająca łapać problemy, zanim urosną, baza zoptymalizowana pod obciążenie, host dobrany do modelu ekonomicznego i doświadczenia zespołu oraz systematyczne procesy wdrożeniowe, dzięki którym to, nad czym spędziliście setki godzin, nie zepsuje się nagle i nie zrazi do was wszystkich klientów.
(Informacja dodatkowa: Cal AI — popularna aplikacja do liczenia kalorii, budowana z pomocą modeli językowych; jej przejęcie za kwotę rzędu kilkudziesięciu milionów dolarów często przywoływane jest jako dowód, że „vibe coding” może prowadzić do realnego biznesu.)
Jeśli chcecie zobaczyć ten proces w aplikacji od początku do końca — z konkretami, skillami i teorią — przerabiam go w mojej płatnej społeczności: najpierw faza „do MVP”, potem sekcja „wypuszczania tego, co zbudowaliście”. A jeśli chcecie, żebym wszedł głębiej w któryś z obszarów albo pokazał więcej budowania na żywo — dawajcie znać w komentarzach i subskrybujcie. Na dziś tyle. Do zobaczenia w kolejnym materiale.