UXAIRFORCE

Od prototypu do prawdziwej aplikacji SaaS – co musisz wiedzieć o bezpieczeństwie i architekturze #EN345

A

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 localhost w 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:3001 w 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:

  1. Przeniesienie komponentów UI do szablonu z auth i Stripe
  2. Dodanie tras backendowych z kontrolą sesji i uprawnień
  3. Zapis historii wygenerowanych zdjęć w tabeli (ID użytkownika, styl, licznik użyć)
  4. Aktualizacja integracji z Gemini po wklejeniu właściwej dokumentacji modelu
  5. 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]

More from the blog