Od prototypu do prawdziwej aplikacji SaaS – co musisz wiedzieć o bezpieczeństwie i architekturze #EN345
Adam Michalski
3 listopada 2025
To są notatki z 40-minutowej rozmowy Petera z Colinem Matthewsem. Wszystkie tezy, obserwacje i wnioski pochodzą od rozmówców.
TL;DR
- Prototyp to tylko klient, produkt to klient + serwer + baza + integracje
- Każdy endpoint backendu musi weryfikować sesję i uprawnienia użytkownika
- RLS (Row Level Security) w Supabase bywa domyślnie otwarte – grozi wyciek danych
- Migracje bazy zamiast ręcznych edycji utrzymują spójność kodu i schematu
- Szablon z auth, Stripe, emailami, storage, analityką i monitoringiem błędów skraca czas do produkcji
- Wdrożenie: GitHub → Render; alternatywy: Replit (all-in-one), Vercel
- „Nie cofnie się zmian w bazie tak łatwo jak w kodzie” – priorytet przy każdej operacji
Kontekst rozmowy
Colin Matthews pokazuje, jak „vibe-coded” prototyp generatora zdjęć profilowych zamienić w prostą aplikację SaaS gotową do monetyzacji. Demonstracja ujawnia braki typowych prototypów oraz minimalny zestaw kroków prowadzących do bezpiecznego wdrożenia. Nacisk kładziony jest na bezpieczeństwo, trwałość danych i operacyjne „plumbing” – rzeczy, które odróżniają demo od produktu.
Prototyp vs aplikacja full-stack
Czego brakuje w prototypie
Jak podkreśla Matthews, prototyp zwykle kończy się na warstwie klienta. Brakuje trwałości danych i kontroli dostępu. Aplikacja produkcyjna wymaga jednak:
- Serwera z logiką sesji i uprawnień
- Bazy danych z trwałym zapisem i migracjami
- Integracji: email (SendGrid), przechowywanie plików, Stripe, analityka oraz rejestrowanie błędów (np. Sentry)
Wniosek: Prototyp to demo, natomiast produkt to system odporny na błędy i gotowy dla płacących użytkowników.
Niezbędnik SaaS w materiale
Matthews wymienia standardowe komponenty produkcyjnej aplikacji:
- OAuth do logowania (Google, GitHub) – weryfikacja tożsamości
- Stripe do planów i płatności – limity oraz ceny ustawia się po stronie Stripe, nie w kodzie
- Emaile transakcyjne (SendGrid) – powiadomienia i komunikacja z użytkownikami
- Przechowywanie plików/blobs – uploady użytkowników i zasoby
- Analityka produktu – w szablonie śledzone są m.in. DAU (daily active users), wizyty, zachowania
- Rejestrowanie błędów (Sentry) – przechwytywanie i analiza problemów
- Wbudowany czat AI – backend przechodzi na OpenAI Agent Kit
Bezpieczeństwo i dane – kluczowe problemy
RLS w Supabase bywa domyślnie otwarte
Matthews wyjaśnia, że Lovable i Bolt używają Supabase jako backendu. Niedawno obie platformy ogłosiły „własne rozwiązania backendowe”, ale jak odkrył Matthews – to tylko white-label Supabase.
Kluczowy problem: Domyślna konfiguracja RLS jest całkowicie otwarta. Oznacza to, że każdy użytkownik może odczytać wszystkie dane z bazy – włącznie z emailami innych użytkowników, danymi osobowymi, wszystkim. Lovable ostrzega przy publikacji, jednak reguły należy jawnie skonfigurować.
Kontrola uprawnień na każdym endpointcie
Każdy endpoint backendu powinien sprawdzać, czy użytkownik ma prawo do akcji. To reguła przewodnia rozmowy. W przeciwnym razie dostęp pozostaje nadmierny, a aplikacja niezabezpieczona.
Migracje bazy danych
Zamiast bezpośrednich zmian w środowisku produkcyjnym, należy generować pliki migracji. W rezultacie kod i schemat pozostają zsynchronizowane. Matthews pokazuje moment, gdy Claude pyta o pozwolenie na zastosowanie migracji – to naprawdę dobry wzorzec.
Matthews ostrzega: „Nie cofnie się zmian w bazie tak łatwo jak w kodzie.” To zdanie porządkuje priorytety pracy i zmienia podejście do modyfikacji schematu.
Pozostałe zasady bezpieczeństwa
- Sekrety w
.env, nie w repozytorium - Brak hardcoded
localhostw kodzie produkcyjnym - Szablon, na którym pracowano, został wcześniej poddany testowi penetracyjnemu (kilka tysięcy dolarów)
Co poprawiono w trakcie przeróbki prototypu
Zidentyfikowane pułapki prototypu:
- Twardo zakodowane
localhost:3001w kliencie - Obrazy przechowywane jako długie ciągi Base64 zamiast referencji do plików
- Brak autoryzacji w backendzie – endpoint działał bez sprawdzania uprawnień
- Brak migracji schematu
Kroki naprawcze:
- Przeniesienie komponentów UI do szablonu z auth i Stripe
- Dodanie tras backendowych z kontrolą sesji i uprawnień
- Zapis historii wygenerowanych zdjęć w tabeli (ID użytkownika, styl, licznik użyć)
- Aktualizacja integracji z Gemini po wklejeniu właściwej dokumentacji modelu
- Ustalenie darmowego progu: 3 zdjęcia miesięcznie (planowane „kredyty” użytkownika świadomie pominięto na tym etapie)
Operacjonalizacja i wdrożenie
Opcje deploymentu
GitHub → Render zapewnia automatyczne wdrożenie po wypchnięciu zmian. Synchronizacja kodu, zarządzanie bazą danych i serwerem. To opcja dla bardziej zaawansowanych użytkowników.
Replit działa jako wariant all-in-one z bazą, serwerem i publikacją jednym kliknięciem. Matthews wyjaśnia: Replit używa tego samego stosu technologicznego co jego szablon. Nie trzeba robić żadnej konfiguracji lokalnej – importujesz szablon, klikasz przycisk publikacji.
Vercel stanowi alternatywną ścieżkę hostingu z oficjalnymi Next.js boilerplates.
Wymagane klucze API
- Stripe – klucze do płatności (publishable + secret key)
- OAuth – Google/GitHub client ID i secret
- SendGrid – API key do emaili transakcyjnych
- Opcjonalnie: Storage (przechowywanie plików), Analytics (PostHog), Monitoring (Sentry)
Dlatego warto włączyć analitykę i monitoring błędów od samego początku – widzisz, co dzieje się w produkcie i gdzie pojawiają się problemy.
Praca z AI podczas developmentu
Plan → implementacja
Matthews zawsze włącza tryb planowania przed wykonaniem zmian. To unika niejawnych zmian wprowadzanych przez narzędzie. Claude przedstawia plan, Matthews go przegląda, modyfikuje i dopiero wtedy zatwierdza implementację.
Dokumentacja w promptach
Dokumentacja w promptach jest potrzebna do doboru właściwego modelu i endpointu. Przykład z rozmowy: błąd „zły model” przy Gemini (flash-xp-2.0 nie istniał). Matthews wkleił aktualną dokumentację Gemini Imagen i problem zniknął.
Matthews zauważa: mogliby uniknąć tego problemu, gdyby podali dokumentację z góry.
Testy jednostkowe
Testy jednostkowe ograniczają regresje, gdy AI modyfikuje kod. Zwykle chcesz pisać testy jednostkowe w kodzie, żeby móc je automatycznie uruchamiać. Dzięki temu, gdy AI wprowadza zmiany, możesz sprawdzić, czy coś się zepsuło.
Krótka checklista „od prototypu do SaaS”
☑ Wybrać szablon z auth, Stripe, emailami, analityką i rejestrowaniem błędów
☑ Przenieść komponenty UI z prototypu
☑ Dodać backend z kontrolą sesji i uprawnień
☑ Zdefiniować schemat i uruchomić migracje
☑ Skonfigurować RLS (jeśli używane jest Supabase)
☑ Umieścić klucze w .env
☑ Wdrożyć: Render / Replit / Vercel
☑ Uruchomić testy, analitykę i monitoring
☑ Ustawić darmowy próg (np. 3 zdjęcia miesięcznie) w Stripe
Prompty do AI – rekonstrukcja z transkryptu
Na podstawie workflow Matthewsa, oto gotowe do użycia prompty z kontekstem „kiedy stosować”:
Rozpoczęcie projektu
Prompt 1: Analiza prototypu
"Wygeneruj specyfikację/README na podstawie tego prototypu.
Opisz wszystkie funkcjonalności, strukturę komponentów,
użyte API i wymagania do przebudowania w środowisku produkcyjnym."
Kiedy: Przed przeróbką, aby mieć wymagania i kroki migracji.
Prompt 2: Integracja z szablonem
"Mam szablon SaaS z następującą strukturą [opisz strukturę].
Chcę zintegrować komponenty z [ścieżka] zachowując istniejące
wzorce autentykacji i dostępu do bazy danych. Wygeneruj plan zmian."
Kiedy: Chcesz zachować UI w szkielecie z auth/Stripe.
Planowanie i implementacja
Prompt 3: Przed większymi zmianami
"Włącz tryb planowania. Przygotuj plan zmian i dopiero potem implementuj.
Chcę dodać [funkcjonalność X]. Przeanalizuj istniejący kod i zaproponuj
implementację zgodną z obecnymi wzorcami. Uwzględnij:
migracje bazy, endpointy backendu z autentykacją, testy jednostkowe."
Kiedy: Praca w trybie plan → apply dla kontroli nad agentem.
Prompt 4: Backend z autoryzacją
"Zaktualizuj backend: dodaj trasy, wymuś autoryzację na każdym endpointcie,
przygotuj migracje DB. Każdy endpoint musi sprawdzać sesję użytkownika
i jego uprawnienia przed wykonaniem akcji."
Kiedy: Prototyp ma tylko klienta i brak mu bezpieczeństwa.
Baza danych
Prompt 5: Zmiana schematu
"Zmień schemat bazy: dodaj tabelę zdjęć profilowych z polami:
- user_id (foreign key do users)
- style (string)
- created_at (timestamp)
- licznik użyć/miesiąc
Wygeneruj plik migracji zgodny z wzorcem w [ścieżka].
NIE APLIKUJ zmian automatycznie - tylko wygeneruj plik."
Kiedy: Potrzebny jest trwały zapis i limit; chcesz przejrzeć migrację przed zastosowaniem.
Prompt 6: Aplikacja migracji
"Przejrzyj ten plik migracji [wklej zawartość].
Sprawdź potencjalne problemy z utratą danych, konfliktami kluczy,
wydajnością. Jeśli wszystko OK, zastosuj migrację."
Kiedy: Po wygenerowaniu i przeglądzie migracji, gotowy do apply.
Poprawki w prototypie
Prompt 7: Przeniesienie komponentów
"Przenieś istniejące komponenty UI z prototypu [ścieżka źródłowa]
do szablonu aplikacji [ścieżka docelowa]. Zachowaj strukturę
i style, zintegruj z istniejącymi wzorcami."
Kiedy: Chcesz zachować wygląd prototypu w nowym środowisku.
Prompt 8: Usunięcie hardcoded wartości
"Usuń twarde odwołania do localhost w kliencie i użyj poprawnych
adresów serwera. Sprawdź wszystkie pliki pod kątem hardcoded:
- localhost:3001
- 127.0.0.1
- Klucze API w kodzie"
Kiedy: Kod był pisany lokalnie i nie zadziała po wdrożeniu.
Prompt 9: Optymalizacja storage
"Zamień obrazy trzymane jako długie base64 na pliki w storage.
Użyj referencji do plików zamiast stringów w bazie danych."
Kiedy: Prototyp zwraca ogromne stringi zamiast plików.
Integracje API
Prompt 10: Naprawa integracji zewnętrznej
"Napraw integrację z Gemini: użyj właściwego modelu i endpointu
zgodnie z załączoną dokumentacją.
[wklej aktualną dokumentację Gemini Imagen]
Aplikacja zwraca błąd: [wklej komunikat błędu]"
Kiedy: Pojawiają się błędy modelu/pakietu; AI używa przestarzałej dokumentacji.
Testy
Prompt 11: Generowanie testów
"Dodaj testy jednostkowe dla krytycznych tras i logiki:
- [endpoint/funkcja 1]
- [endpoint/funkcja 2]
Wzoruj się na stylu testów w [przykład]. Testy powinny pokrywać:
- Happy path
- Brak autentykacji
- Nieprawidłowy input
- Błędy API zewnętrznego"
Kiedy: AI będzie modyfikować kod; potrzebujesz automatycznej weryfikacji.
Konfiguracja SaaS
Prompt 12: Konfiguracja auth i płatności
"Skonfiguruj logowanie i płatności:
- OAuth (Google/GitHub)
- Stripe z darmowym progiem: 3 zdjęcia miesięcznie
- Limity po stronie Stripe, nie w kodzie
Dodaj tabele do śledzenia użycia per użytkownik per miesiąc."
Kiedy: Przygotowujesz podstawy SaaS; limity po stronie Stripe ułatwiają zarządzanie.
Prompt 13: Integracje operacyjne
"Dodaj emaile transakcyjne (SendGrid), rejestrowanie błędów (Sentry)
i analitykę produktu (PostHog). Śledź:
- DAU (daily active users)
- Wizyty i konwersje
- Błędy krytyczne z alertami"
Kiedy: Etap operacyjny z telemetrią i alertami; chcesz wiedzieć, co dzieje się w produkcie.
Deployment
Prompt 14: Zarządzanie sekretami
"Przygotuj plik .env i przenieś tam klucze:
- STRIPE_PUBLISHABLE_KEY
- STRIPE_SECRET_KEY
- GOOGLE_CLIENT_ID
- GOOGLE_CLIENT_SECRET
- SENDGRID_API_KEY
- GEMINI_API_KEY
Upewnij się, że .env jest w .gitignore."
Kiedy: Porządkowanie sekretów przed wdrożeniem.
Prompt 15: Konfiguracja wdrożenia
"Skonfiguruj wdrożenie: GitHub → Render z automatycznymi deploymentami
po push. Alternatywnie przygotuj setup dla Replit (all-in-one)
lub Vercel."
Kiedy: Automatyczne wdrożenie po wypchnięciu zmian lub ścieżka all-in-one.
Bezpieczeństwo
Prompt 16: Audyt RLS
"Wyświetl i zweryfikuj reguły RLS w Supabase przed publikacją.
Dla tabeli [nazwa] wygeneruj reguły, które:
- Pozwalają użytkownikom czytać tylko własne rekordy
- Pozwalają administratorom na pełen dostęp
- Blokują anonimowe zapytania
Wyjaśnij każdą regułę."
Kiedy: Trzeba domknąć dostęp do danych; weryfikacja przed publikacją.
Kiedy stosować który prompt? – Szybka tabela
| Sytuacja | Użyj promptu | Kluczowa uwaga |
|---|---|---|
| Rozpoczynasz z prototypem | #1, #2 | Zawsze generuj specyfikację najpierw |
| Dodajesz funkcjonalność | #3, #4 | Włącz tryb planowania! |
| Zmieniasz schemat bazy | #5, #6 | NIGDY nie aplikuj od razu – przejrzyj migrację |
| Naprawiasz prototyp | #7, #8, #9 | Usuń hardcoded wartości, base64, dodaj auth |
| Integrujesz API | #10 | Załącz aktualną dokumentację |
| Przed wdrożeniem | #11, #12, #13 | Testy, auth, płatności, monitoring |
| Deployment | #14, #15 | Sekrety w .env, automatyczne wdrożenie |
| Bezpieczeństwo | #16 | Weryfikuj RLS przed publikacją |
Filozofia budowania prawdziwych produktów
Doświadczenie > certyfikaty
Matthews bardzo mocno podkreśla kluczową różnicę w podejściu do nauki. Nie jest wielkim fanem certyfikatów, szczególnie w produktach czy technologii jako mechanizmu rozwoju kariery. Doświadczenie to to, co czyni cię lepszym. Główne to nauczyć się umiejętności i osiągnąć materialny rezultat – jak stworzenie projektu pobocznego, który generuje dochód. To jest dużo lepsze niż posiadanie certyfikatu.
Zgadza się to z filozofią jego kursu – nie chodzi o zdobycie certyfikatu ukończenia, ale o faktyczne zbudowanie działającego produktu SaaS, za który ludzie będą płacić.
Zrozumienie vs szybkość
Matthews radzi nie traktować procesu jako „chcę rezultat najszybciej jak się da i nie obchodzi mnie, jak cokolwiek działa”, ale raczej: okej, jak to naprawdę działa? I spróbować się tego nauczyć.
To kluczowe rozróżnienie. Narzędzia AI pozwalają bardzo szybko stworzyć coś, co wygląda jak działająca aplikacja. Jednak bez zrozumienia, co dzieje się pod maską, będziesz bezradny, gdy coś się zepsuje.
Najtrudniejszy moment
Matthews identyfikuje najtrudniejszy punkt w rozwoju: w końcu będziesz musiał dodać płatności. Platformy mają integrację ze Stripe, ale nadal musisz iść do Stripe i wszystko skonfigurować. Musisz dodać email. Musisz to dodać.
Jeśli nie rozumiesz, jak działają te systemy, to na końcu dnia, gdy masz błąd w swoim systemie emailowym, a jedyne co możesz zrobić, to promptować „napraw mój system emailowy” – to jest trudna część.
Bez fundamentalnego zrozumienia architektury aplikacji, kończysz jako osoba całkowicie zależna od AI do każdego debugowania.
Narzędzia i stack technologiczny
VS Code + Claude Code vs Cursor
Matthews preferuje VS Code z Claude Code dla bieżącego projektu, ale zauważa, że Cursor działa lepiej dla większych baz kodu. Zalety VS Code to natywna integracja Claude Code, czytelny edytor Markdown i możliwość scrollowania tekstu z inputem na dole.
Matthews podkreśla, że te narzędzia nie są trudniejsze w użyciu niż Lovable czy Bolt – to po prostu pisanie w czacie.
Ewolucja narzędzi
Matthews wspomina: Bolt niedawno przeszedł na Claude. To dobra decyzja strategiczna – pokazuje, że nawet platformy no-code rozpoznają przewagę bardziej zaawansowanych modeli.
Polecane zasoby
Kursy i społeczność:
- Build with AI – podcast Matthewsa na YouTube z wywiadami z twórcami aplikacji SaaS
- Kurs Matthewsa – 8 tygodni z dedykowanym wsparciem inżynierskim i szablonem przetestowanym pod kątem bezpieczeństwa
- Społeczność – około 700 osób, newsletter z praktycznymi case studies
Darmowe szablony:
- Vercel – oficjalne Next.js boilerplates
- GitHub – szukaj: „Next.js boilerplate”, „Node React template”, „SaaS starter”
- Replit – gotowe szablony z integracjami
Narzędzia:
- VS Code + Claude Code / Cursor – do developmentu
- Render / Replit / Vercel – do deploymentu
- Supabase / PostgreSQL – bazy danych
- PostHog – analytics produktowa (śledzi DAU, wizyty, konwersje)
- Sentry – monitoring błędów
Sponsor:
- Composio – SDK do łączenia z 800+ aplikacjami (Slack, GitHub, Gmail, Jira)
- Rube App – chat AI połączony bezpośrednio z aplikacjami biznesowymi
Kluczowy insight
Mniej serwera, więcej ryzyka
Standardowo myślimy: Im mniej backendu i rozwiązań „bezserwerowych”, tym szybciej oraz bezpieczniej. Mniej kodu = mniej błędów, prawda?
W praktyce okazuje się, że: Cienka, jawna warstwa serwera + sprawdzony szablon zmniejsza ryzyko i przyspiesza dojście do produkcji. Natomiast automatycznie generowane API bez kontroli tworzy luki. Matthews odkrył, że Lovable i Bolt domyślnie pozostawiają bazę danych całkowicie otwartą. Problem nie polega na tym, że narzędzie jest złe, ale że użytkownik nawet nie wie, że musi coś skonfigurować. W tradycyjnym kodzie serwerowym widzisz każdy endpoint i jawnie piszesz logikę uprawnień – błędy są widoczne.
Dlaczego to jest istotne: Zmienia kryterium „szybkości”. Najkrótsza droga do płacących użytkowników to minimalny własny serwer z kontrolą uprawnień, migracjami i poprawnie ustawionym RLS. Prostota interfejsu często oznacza ukrytą złożoność w miejscach krytycznych dla bezpieczeństwa.
Test na jutro: Gdy planujesz „bezserwerowy” prototyp na danych użytkowników, zamiast publikować otwarte endpointy, dodaj prosty backend z weryfikacją sesji i ról, zamknij RLS do właściciela rekordu i spróbuj odczytać cudze dane jako anonimowy klient. Sprawdź, czy wyciek znika.
Notka końcowa: Ten wpis jest częścią mojej kolekcji notatek z ciekawych podcastów, webinarów i innych treści, które uważam za wartościowe i do których sam chcę wracać. Jeśli chcesz sprawdzić oryginalne źródło, znajdziesz je tutaj: [Full Tutorial: From Prototype to a Real SaaS App in 40 Minutes | Colin Matthews]
