handbooks-reader
v1.0.0
Published
System do wyświetlania płatnych i darmowych podręczników z integracją Stripe.
Readme
📚 Handbooks Reader - Astro + Supabase + Stripe
System do wyświetlania płatnych i darmowych podręczników z integracją Stripe.
🏗️ Architektura
- Frontend: Astro (Static Site Generation)
- Backend: Supabase (PostgreSQL + Auth + Edge Functions)
- Płatności: Stripe
- Hosting: Render.com (static site)
📦 Struktura projektu
handbooks-reader/
├── src/
│ ├── layouts/
│ │ └── Layout.astro # Główny layout z nawigacją i logowaniem
│ ├── pages/
│ │ ├── index.astro # Lista wszystkich podręczników
│ │ ├── handbooks/
│ │ │ └── [slug].astro # Reader pojedynczego podręcznika
│ │ ├── success.astro # Strona po udanej płatności
│ │ └── api/
│ │ └── create-checkout-session.ts # API endpoint dla Stripe
│ └── lib/
│ └── supabase.ts # Klient Supabase + typy TypeScript
├── supabase/
│ └── functions/
│ └── stripe-webhook/ # Edge Function dla webhooków Stripe
│ └── index.ts
└── supabase-migrations/ # SQL migrations
├── 01_add_payment_columns.sql
├── 02_create_user_handbooks_access.sql
└── 03_rls_policies.sql🚀 Setup krok po kroku
1. Supabase - Migracje bazy danych
Zaloguj się do Supabase Dashboard i wykonaj SQL:
# 1. Dodaj kolumny płatności do sl_handbooks
# Uruchom: supabase-migrations/01_add_payment_columns.sql
# 2. Utwórz tabelę dostępu użytkowników
# Uruchom: supabase-migrations/02_create_user_handbooks_access.sql
# 3. Skonfiguruj RLS policies
# Uruchom: supabase-migrations/03_rls_policies.sql2. Supabase - Włącz autentykację Google
- W Supabase Dashboard → Authentication → Providers
- Włącz Google OAuth
- Dodaj Authorized redirect URLs:
http://localhost:4321/auth/callback(development)https://twoja-domena.com/auth/callback(production)
3. Supabase - Deploy Edge Function
# Zainstaluj Supabase CLI
npm install -g supabase
# Zaloguj się
supabase login
# Link do swojego projektu
supabase link --project-ref your-project-ref
# Deploy Edge Function
supabase functions deploy stripe-webhook
# Ustaw zmienne środowiskowe dla Edge Function
supabase secrets set STRIPE_SECRET_KEY=sk_test_...
supabase secrets set STRIPE_WEBHOOK_SECRET=whsec_...
supabase secrets set SUPABASE_URL=https://xxx.supabase.co
supabase secrets set SUPABASE_SERVICE_ROLE_KEY=eyJh...URL Twojej Edge Function:
https://your-project-ref.supabase.co/functions/v1/stripe-webhook
4. Stripe - Konfiguracja
A. Utwórz produkty
- Zaloguj się do Stripe Dashboard
- Products → Create product
- Dla każdego płatnego podręcznika:
- Nazwa produktu
- Cena (np. 49.99 PLN)
- Skopiuj Price ID (np.
price_xxx)
- Zaktualizuj bazę danych:
UPDATE sl_handbooks
SET is_paid = true,
price = 4999, -- w groszach
stripe_price_id = 'price_xxx'
WHERE slug = 'twoj-podrecznik';B. Skonfiguruj webhook
- Stripe Dashboard → Developers → Webhooks
- Add endpoint:
- URL:
https://your-project-ref.supabase.co/functions/v1/stripe-webhook - Events: Wybierz
checkout.session.completed
- URL:
- Skopiuj Webhook signing secret (whsec_xxx)
- Dodaj go do Supabase Edge Function secrets (krok 3)
5. Astro - Instalacja i konfiguracja
cd handbooks-reader
# Zainstaluj zależności
npm install
# Utwórz plik .env
cp .env.example .envEdytuj .env:
PUBLIC_SUPABASE_URL=https://xxx.supabase.co
PUBLIC_SUPABASE_ANON_KEY=eyJh...
PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_...
STRIPE_SECRET_KEY=sk_test_...6. Lokalne uruchomienie
npm run devOtwórz: http://localhost:4321
7. Deploy na Render.com
- Push kod do GitHub
- Render Dashboard → New Static Site
- Połącz z repozytorium
- Ustawienia:
- Build Command:
npm install && npm run build - Publish Directory:
dist
- Build Command:
- Environment Variables:
- Dodaj wszystkie zmienne z
.env
- Dodaj wszystkie zmienne z
- Deploy!
🔒 Jak działa security (RLS)
Darmowe podręczniki:
-- Każdy może czytać rozdziały z darmowych podręczników
CREATE POLICY "Anyone can read free handbook chapters"
ON sl_chapters FOR SELECT
USING (
EXISTS (
SELECT 1 FROM sl_handbooks
WHERE sl_handbooks.id = sl_chapters.handbook_id
AND sl_handbooks.is_paid = false
)
);Płatne podręczniki:
-- Tylko użytkownicy którzy kupili mogą czytać
CREATE POLICY "Users can read purchased handbook chapters"
ON sl_chapters FOR SELECT
USING (
auth.uid() IS NOT NULL
AND EXISTS (
SELECT 1 FROM user_handbooks_access
WHERE user_handbooks_access.user_id = auth.uid()
AND user_handbooks_access.handbook_id = sl_chapters.handbook_id
)
);💳 Flow zakupu
User klika "Kup podręcznik"
- Sprawdza czy jest zalogowany
- Jeśli nie → redirect do Google OAuth
Tworzenie sesji Stripe
- POST
/api/create-checkout-session - Tworzy Stripe Checkout Session z metadanymi:
{ "user_id": "uuid", "handbook_id": "uuid" }
- POST
User płaci w Stripe
- Redirect do Stripe Checkout
- Płatność BLIK/Karta/P24
Stripe webhook
- Stripe wysyła
checkout.session.completed - Supabase Edge Function otrzymuje webhook
- Dodaje rekord do
user_handbooks_access
- Stripe wysyła
User ma dostęp
- Wraca na stronę podręcznika
- RLS automatycznie daje dostęp do rozdziałów
- Może czytać cały podręcznik
🧪 Testowanie
Test płatności (Stripe test mode)
Użyj testowych kart:
- Sukces:
4242 4242 4242 4242 - Wymaga 3D Secure:
4000 0027 6000 3184 - Odrzucona:
4000 0000 0000 0002 - Data: dowolna przyszła data
- CVC: dowolne 3 cyfry
Test BLIK (test mode)
- Kod:
777777
🐛 Debugowanie
Sprawdź logi Edge Function:
supabase functions logs stripe-webhookSprawdź logi Stripe:
Stripe Dashboard → Developers → Events
Sprawdź RLS policies:
-- Sprawdź czy user ma dostęp
SELECT * FROM user_handbooks_access
WHERE user_id = 'user-uuid';
-- Sprawdź jakie rozdziały user widzi
SELECT * FROM sl_chapters
WHERE handbook_id = 'handbook-uuid';📝 TODO / Kolejne kroki
- [ ] Dodaj email potwierdzający zakup
- [ ] Dashboard użytkownika z listą zakupionych podręczników
- [ ] Strona "Moje podręczniki"
- [ ] Eksport do PDF
- [ ] Bookmarki/notatki w rozdziałach
- [ ] Wyszukiwarka w treści podręczników
- [ ] Tryb ciemny
🆘 Pomoc
Jeśli coś nie działa:
- Sprawdź czy wszystkie zmienne środowiskowe są ustawione
- Sprawdź logi w Supabase Dashboard
- Sprawdź webhooks w Stripe Dashboard
- Sprawdź czy RLS policies są włączone
📄 Licencja
MIT# ep-5-minutes-reader
