Production SaaS Starter
Multi-Tenant-SaaS-Plattform
Production-orientierte B2B-SaaS-Basis mit workspace-basierter Multi-Tenancy, Stripe-Billing, Platform-Admin, RBAC und i18n. Diese Anleitung bringt Sie in unter einer Stunde vom Klon zum lokalen Betrieb.
Übersicht
Der Production SaaS Starter ist eine workspace-basierte Multi-Tenant-Plattform — keine Minimal-Demo. Er enthält echte Muster: PostgreSQL RLS, SECURITY DEFINER RPCs, Stripe-Webhook-Idempotenz, duale RBAC-Schichten und Service-Provider-Abstraktion.
- Workspaces mit Mitgliedschaften, Einladungen und slug-basierten URLs
- Stripe-Abonnements, Usage-Metering, Promo-Codes und Enterprise-Deals
- Platform-Admin-Konsole mit Audit-Logs und User/Workspace-Moderation
- E-Mail/Passwort + OAuth, 2FA, Passwort-Reset via Resend
Stack: Next.js 16, React 19, Supabase, Stripe, Resend, next-intl mit 4 Locales.
Abhängigkeiten installieren
Installieren Sie npm-Pakete im Projektroot, bevor Sie Umgebungsvariablen konfigurieren.
Einmal nach dem Klonen des Repositorys ausführen:
npm installUmgebungs-Setup
Konfigurieren Sie .env.local vor Datenbankmigrationen oder dem Start der App. Legen Sie die Datei zuerst an und fügen Sie Werte Abschnitt für Abschnitt hinzu.
Lokale Env-Datei erstellen
Beispieldatei kopieren — Stripe- und Resend-Werte in den Abschnitten unten hinzufügen. Supabase-Variablen werden im Supabase-Setup-Abschnitt konfiguriert.
cp .env.example .env.localApp
ErforderlichIhre deployte App-URL — für Checkout-Weiterleitungen, E-Mail-Links und OAuth-Callbacks.
Schritte
- 1Für lokale Entwicklung NEXT_PUBLIC_APP_URL=http://localhost:3000 setzen
- 2Für Production Vercel-Deployment-URL oder Custom Domain verwenden
- 3Variable in Vercel → Projekt → Einstellungen → Umgebungsvariablen hinzufügen
Umgebungsvariablen
NEXT_PUBLIC_APP_URLErforderlichÖffentliche URL Ihrer SaaS-App (ohne abschließenden Schrägstrich).
Wo zu finden
Lokal: http://localhost:3000 · Production: Vercel-Projektdomain oder Custom Domain
Beispiel: https://app.ihredomain.de
NEXT_PUBLIC_APP_NAMEMarkenname in transaktionalen E-Mails.
Wo zu finden
Beliebigen Anzeigenamen wählen — kein externer Dienst nötig
Beispiel: Acme SaaS
Supabase-Setup
Diese Supabase-Schritte der Reihe nach ausführen — Projekterstellung, Umgebungsvariablen und Datenbankmigration.
Diese Supabase-Schritte der Reihe nach ausführen — Projekterstellung, Umgebungsvariablen und Datenbankmigration.
7 Schritte — der Reihe nach ausführen
Supabase-Setup
~5 Min.Projekt erstellen und Project ID kopieren
Supabase-Projekt erstellen
Bei supabase.com anmelden, New project klicken, Name und Region wählen, Datenbankpasswort setzen und auf die Bereitstellung warten.
Supabase Dashboard öffnenProject ID kopieren
Wird beim Verknüpfen der CLI und beim Erstellen der API-URL benötigt.
Supabase-Umgebungsvariablen
Nach Erstellung des Supabase-Projekts in .env.local eintragen — vor Datenbankmigrationen.
NEXT_PUBLIC_SUPABASE_URLIhre Projekt-API-URL. YOURPROJECTID durch Ihre Supabase Project ID ersetzen.
NEXT_PUBLIC_SUPABASE_URL=https://YOURPROJECTID.supabase.coWo zu finden
Supabase Dashboard → Project Settings → API
NEXT_PUBLIC_SUPABASE_ANON_KEYÖffentlicher anon-Schlüssel — sicher für Browser. Aus dem Dashboard kopieren; keinen Platzhalter verwenden.
Wo zu finden
Supabase Dashboard → Project Settings → API
SUPABASE_SERVICE_ROLE_KEYNur serverseitig. Niemals im Client preisgeben. Aus dem Dashboard kopieren; keinen Platzhalter verwenden.
Wo zu finden
Supabase Dashboard → Project Settings → API
Datenbank-Setup und Migrationen
~15 Min.CLI-Setup, Verknüpfung und Schema-Migration
Supabase CLI installieren
Global installieren, dann prüfen:
npm install -g supabaseInstallation prüfen:
supabase --versionBei Supabase CLI anmelden
Ein Browserfenster öffnet sich zur Authentifizierung. Anmelden und zum Terminal zurückkehren.
supabase loginLokales Projekt verknüpfen
PROJECT_REF durch Ihre Project ID aus Schritt 2 ersetzen.
supabase link --project-ref <PROJECT_REF>Beispiel:
supabase link --project-ref abcdefghijklmnopDatenbankmigrationen anwenden
Erstellt alle Tabellen, Funktionen, Policies und Seed-Daten. Supabase-Zugangsdaten müssen in .env.local stehen.
supabase db pushTabellen prüfen
Schema bestätigen, bevor Sie fortfahren.
Datenbank aktualisieren
Nach Repo-Updates mit Datenbankänderungen:
git pull
supabase db pushStripe-Setup
Stripe CLI
Stripe CLI für lokale Authentifizierung und Webhook-Weiterleitung während der Entwicklung.
- 1Stripe CLI gemäß der offiziellen Stripe-Dokumentation installieren
- 2Plattformspezifische Installationsschritte abschließen
- 3Stripe-Authentifizierung/Login ausführen
- 4Nach der Authentifizierung mit der lokalen Stripe-Entwicklung fortfahren
CLI authentifizieren
login ausführen — ein Browserfenster verbindet Ihr Stripe-Konto:
stripe loginWebhooks lokal weiterleiten
In einem separaten Terminal Events an den lokalen Webhook-Handler weiterleiten. Signing secret in STRIPE_WEBHOOK_SECRET kopieren:
stripe listen --forward-to localhost:3000/api/stripe/webhookAPI-Schlüssel
Schlüssel aus dem Stripe-Dashboard in .env.local kopieren — niemals Schlüssel im Repository oder in der Dokumentation hardcoden.
Wo zu finden
Stripe Dashboard → Developers → API Keys
- Publishable Key (pk_test_...)
- Secret Key (sk_test_...)
Umgebungsvariablen
STRIPE_SECRET_KEYErforderlichServer-seitiger Stripe-API-Schlüssel — aus dem Dashboard kopieren, nie hardcoden.
Wo zu finden
Stripe Dashboard → Developers → API Keys — Secret key (sk_test_...)
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEYErforderlichClient-seitiger Schlüssel für Stripe.js Checkout — aus dem Dashboard kopieren, nie hardcoden.
Wo zu finden
Stripe Dashboard → Developers → API Keys — Publishable key (pk_test_...)
Webhooks
Schritte
- 1Für lokale Entwicklung stripe listen --forward-to localhost:3000/api/stripe/webhook ausführen und das Webhook-Signing-Secret kopieren
- 2Für deployed Umgebungen Webhook-Endpoint hinzufügen: https://YOUR_APP_URL/api/stripe/webhook
- 3Events auswählen: checkout.session.completed, customer.subscription.*, invoice.*, payment_method.*
- 4Webhook-Signing-Secret in STRIPE_WEBHOOK_SECRET in .env.local eintragen
Umgebungsvariablen
STRIPE_WEBHOOK_SECRETErforderlichVerifiziert Webhook-Signaturen von Stripe.
Wo zu finden
Stripe Dashboard → Developers → Webhooks → Signing secret · Lokal: Ausgabe von stripe listen
Resend-Setup
Resend
ErforderlichTransaktions-E-Mail — Einladungen, 2FA-OTP, Passwort-Reset. Supabase-E-Mail wird nicht verwendet.
Schritte
- 1Auf resend.com registrieren
- 2Sende-Domain hinzufügen und verifizieren (DNS-Einträge)
- 3API-Key erstellen
- 4RESEND_FROM_EMAIL auf verifizierte Adresse Ihrer Domain setzen
Umgebungsvariablen
RESEND_API_KEYErforderlichAPI-Key zum E-Mail-Versand.
Wo zu finden
Resend Dashboard → API Keys → Create API Key
RESEND_FROM_EMAILErforderlichVerifizierte Absenderadresse (z. B. noreply@ihredomain.de).
Wo zu finden
Resend Dashboard → Domains → Domain hinzufügen → DNS verifizieren → Adresse auf dieser Domain nutzen
Schnellstart
Nach Abschluss von Umgebungs-, Supabase-, Stripe- und Resend-Setup oben diese Befehle der Reihe nach ausführen:
Projektabhängigkeiten installieren
npm installSeed-Pläne mit Stripe synchronisieren — hauptsächlich zum Testen und zum Abgleich der Stripe-Pläne mit der Datenbank
npm run sync:plansEntwicklungsserver unter http://localhost:3000 starten
npm run devEntwicklung vs. Production
Unterschiedliche Befehle für den täglichen Entwicklungsbetrieb und die lokale Vorschau eines Production-Builds.
Entwicklung
Entwicklungsserver mit Hot Reload starten:
npm run devProduction-Vorschau
Production-Umgebung lokal prüfen — App bauen, dann Production-Server starten:
npm run buildnpm run startSkript-Referenz
| Befehl | Beschreibung |
|---|---|
| supabase db push | Datenbankschema anwenden (supabase db push) |
| npm run sync:plans | Seed-Pläne mit Stripe-Produkten/Preisen synchronisieren |
| npm run dev | Entwicklungsserver starten |
| npm run build | Production-Build |
| npm run start | Production-Server starten (nach Build) |
| npm run test | Jest-Unit-Tests ausführen (nur Services) |
Architektur
Vier Schichten mit strikter Aufrufreihenfolge — Agents und Entwickler folgen demselben Pfad:
UI → Server Actions / API → Services → Repositories → PostgreSQL (RLS/RPC)Wichtige Orte:
Schicht 1
Präsentation — src/app/, src/components/
Schicht 2
Anwendung — Server Actions, createRequestContext(), RBAC-Guards
Schicht 3
Domain — src/modules/*/ *.service.ts (Geschäftslogik)
Schicht 4
Daten — Repositories + PostgreSQL RLS/RPCs via src/services/
Multi-Tenancy
Ein Workspace ist der Mandant — es gibt keine separate Organisationstabelle.
- Mandanten-Key: workspaces.id (UUID); URLs nutzen eindeutigen slug
- Memberships verknüpfen User mit Workspaces in owner-, admin- oder member-Rollen
- RLS-Policies erzwingen workspace_id IN (Mitgliedschaften des Users)
Platform-Admins greifen über platform_admins auf /admin zu — Rollen super_admin, platform_admin oder platform_viewer.
Authentifizierung & Autorisierung
Auth-Flow: Login → optional 2FA → Onboarding (kein Workspace) oder Workspace-Dashboard. Platform-Admin-Einladungen führen zu platform-onboarding.
- E-Mail/Passwort und OAuth via Supabase Auth
- 2FA via E-Mail-OTP (Resend) — nicht Supabase-Built-in-E-Mail
- Passwort-Reset mit tokenbasiertem Flow und Rate Limiting
Workspace-Rollen und Berechtigungen:
ownerBilling, Workspace löschen, volle MitgliederverwaltungadminMitglieder einladen/entfernen, Workspace-Einstellungen aktualisierenmemberLesen und teilnehmen — keine Admin-Aktionen
Billing & Abonnements
Ein aktives Abonnement pro Workspace, verknüpft mit Stripe-Customer- und Subscription-IDs.
- Checkout für neue Abos; Portal für Self-Service-Verwaltung
- Upgrades mit Proration; Downgrades zum Periodenende geplant
- Seed-Pläne: Starter ($29/Mo.), Pro ($39/Mo.), Enterprise (individuell)
- Webhook unter /api/stripe/webhook synchronisiert Status mit idempotenter stripe_events-Tabelle
Deployment
Empfohlener Stack: Vercel (Next.js) + Supabase Cloud + Stripe-Webhooks.
- 1Schema auf Production-Supabase anwenden (supabase db push)
- 2Alle Env-Variablen in Vercel setzen — Abschnitt Umgebungs-Setup oben
- 3Next.js-App deployen
- 4Stripe-Webhook registrieren → https://IHRE_APP_URL/api/stripe/webhook
- 5Super-Admin bootstrappen und sync:plans in Production ausführen

