npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

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.sql

2. Supabase - Włącz autentykację Google

  1. W Supabase Dashboard → Authentication → Providers
  2. Włącz Google OAuth
  3. 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

  1. Zaloguj się do Stripe Dashboard
  2. Products → Create product
  3. Dla każdego płatnego podręcznika:
    • Nazwa produktu
    • Cena (np. 49.99 PLN)
    • Skopiuj Price ID (np. price_xxx)
  4. 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

  1. Stripe Dashboard → Developers → Webhooks
  2. Add endpoint:
    • URL: https://your-project-ref.supabase.co/functions/v1/stripe-webhook
    • Events: Wybierz checkout.session.completed
  3. Skopiuj Webhook signing secret (whsec_xxx)
  4. 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 .env

Edytuj .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 dev

Otwórz: http://localhost:4321

7. Deploy na Render.com

  1. Push kod do GitHub
  2. Render Dashboard → New Static Site
  3. Połącz z repozytorium
  4. Ustawienia:
    • Build Command: npm install && npm run build
    • Publish Directory: dist
  5. Environment Variables:
    • Dodaj wszystkie zmienne z .env
  6. 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

  1. User klika "Kup podręcznik"

    • Sprawdza czy jest zalogowany
    • Jeśli nie → redirect do Google OAuth
  2. Tworzenie sesji Stripe

    • POST /api/create-checkout-session
    • Tworzy Stripe Checkout Session z metadanymi:
      {
        "user_id": "uuid",
        "handbook_id": "uuid"
      }
  3. User płaci w Stripe

    • Redirect do Stripe Checkout
    • Płatność BLIK/Karta/P24
  4. Stripe webhook

    • Stripe wysyła checkout.session.completed
    • Supabase Edge Function otrzymuje webhook
    • Dodaje rekord do user_handbooks_access
  5. 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-webhook

Sprawdź 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:

  1. Sprawdź czy wszystkie zmienne środowiskowe są ustawione
  2. Sprawdź logi w Supabase Dashboard
  3. Sprawdź webhooks w Stripe Dashboard
  4. Sprawdź czy RLS policies są włączone

📄 Licencja

MIT# ep-5-minutes-reader