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

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

Setup~3 Min.

Abhängigkeiten installieren

Installieren Sie npm-Pakete im Projektroot, bevor Sie Umgebungsvariablen konfigurieren.

Einmal nach dem Klonen des Repositorys ausführen:

Terminal
npm install
Voraussetzung~5 Min.

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

Terminal
cp .env.example .env.local

App

Erforderlich

Ihre deployte App-URL — für Checkout-Weiterleitungen, E-Mail-Links und OAuth-Callbacks.

Schritte

  1. 1Für lokale Entwicklung NEXT_PUBLIC_APP_URL=http://localhost:3000 setzen
  2. 2Für Production Vercel-Deployment-URL oder Custom Domain verwenden
  3. 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_NAME

Markenname in transaktionalen E-Mails.

Wo zu finden

Beliebigen Anzeigenamen wählen — kein externer Dienst nötig

Beispiel: Acme SaaS

Setup~15 Min.

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

1

Supabase-Projekt erstellen

Bei supabase.com anmelden, New project klicken, Name und Region wählen, Datenbankpasswort setzen und auf die Bereitstellung warten.

Supabase Dashboard öffnen
2

Project ID kopieren

Wird beim Verknüpfen der CLI und beim Erstellen der API-URL benötigt.

Wo zu finden: Supabase Dashboard → Project → Project Settings → Project ID

Supabase-Umgebungsvariablen

Nach Erstellung des Supabase-Projekts in .env.local eintragen — vor Datenbankmigrationen.

NEXT_PUBLIC_SUPABASE_URL

Ihre Projekt-API-URL. YOURPROJECTID durch Ihre Supabase Project ID ersetzen.

.env.local
NEXT_PUBLIC_SUPABASE_URL=https://YOURPROJECTID.supabase.co

Wo 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_KEY

Nur 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

3

Supabase CLI installieren

Global installieren, dann prüfen:

Terminal
npm install -g supabase

Installation prüfen:

Terminal
supabase --version
4

Bei Supabase CLI anmelden

Ein Browserfenster öffnet sich zur Authentifizierung. Anmelden und zum Terminal zurückkehren.

Terminal
supabase login
5

Lokales Projekt verknüpfen

PROJECT_REF durch Ihre Project ID aus Schritt 2 ersetzen.

Terminal
supabase link --project-ref <PROJECT_REF>

Beispiel:

Terminal
supabase link --project-ref abcdefghijklmnop
6

Datenbankmigrationen anwenden

Erstellt alle Tabellen, Funktionen, Policies und Seed-Daten. Supabase-Zugangsdaten müssen in .env.local stehen.

Terminal
supabase db push
7

Tabellen prüfen

Schema bestätigen, bevor Sie fortfahren.

Wo zu finden: Supabase Dashboard → Project → Table Editor

Datenbank aktualisieren

Nach Repo-Updates mit Datenbankänderungen:

Terminal
git pull
supabase db push
Konfiguration~15 Min.

Stripe-Setup

Stripe CLI

Stripe CLI für lokale Authentifizierung und Webhook-Weiterleitung während der Entwicklung.

  1. 1Stripe CLI gemäß der offiziellen Stripe-Dokumentation installieren
  2. 2Plattformspezifische Installationsschritte abschließen
  3. 3Stripe-Authentifizierung/Login ausführen
  4. 4Nach der Authentifizierung mit der lokalen Stripe-Entwicklung fortfahren
Stripe CLI Installationsanleitung

CLI authentifizieren

login ausführen — ein Browserfenster verbindet Ihr Stripe-Konto:

Terminal
stripe login

Webhooks lokal weiterleiten

In einem separaten Terminal Events an den lokalen Webhook-Handler weiterleiten. Signing secret in STRIPE_WEBHOOK_SECRET kopieren:

Terminal
stripe listen --forward-to localhost:3000/api/stripe/webhook

API-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_KEYErforderlich

Server-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_KEYErforderlich

Client-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

  1. 1Für lokale Entwicklung stripe listen --forward-to localhost:3000/api/stripe/webhook ausführen und das Webhook-Signing-Secret kopieren
  2. 2Für deployed Umgebungen Webhook-Endpoint hinzufügen: https://YOUR_APP_URL/api/stripe/webhook
  3. 3Events auswählen: checkout.session.completed, customer.subscription.*, invoice.*, payment_method.*
  4. 4Webhook-Signing-Secret in STRIPE_WEBHOOK_SECRET in .env.local eintragen

Umgebungsvariablen

STRIPE_WEBHOOK_SECRETErforderlich

Verifiziert Webhook-Signaturen von Stripe.

Wo zu finden

Stripe Dashboard → Developers → Webhooks → Signing secret · Lokal: Ausgabe von stripe listen

Konfiguration~10 Min.

Resend-Setup

Resend

Erforderlich

Transaktions-E-Mail — Einladungen, 2FA-OTP, Passwort-Reset. Supabase-E-Mail wird nicht verwendet.

Schritte

  1. 1Auf resend.com registrieren
  2. 2Sende-Domain hinzufügen und verifizieren (DNS-Einträge)
  3. 3API-Key erstellen
  4. 4RESEND_FROM_EMAIL auf verifizierte Adresse Ihrer Domain setzen

Umgebungsvariablen

RESEND_API_KEYErforderlich

API-Key zum E-Mail-Versand.

Wo zu finden

Resend Dashboard → API Keys → Create API Key

RESEND_FROM_EMAILErforderlich

Verifizierte Absenderadresse (z. B. noreply@ihredomain.de).

Wo zu finden

Resend Dashboard → Domains → Domain hinzufügen → DNS verifizieren → Adresse auf dieser Domain nutzen

Setup~2 Min.

Schnellstart

Nach Abschluss von Umgebungs-, Supabase-, Stripe- und Resend-Setup oben diese Befehle der Reihe nach ausführen:

Projektabhängigkeiten installieren

Terminal
npm install

Seed-Pläne mit Stripe synchronisieren — hauptsächlich zum Testen und zum Abgleich der Stripe-Pläne mit der Datenbank

Terminal
npm run sync:plans

Entwicklungsserver unter http://localhost:3000 starten

Terminal
npm run dev
Referenz~3 Min.

Entwicklung vs. Production

Unterschiedliche Befehle für den täglichen Entwicklungsbetrieb und die lokale Vorschau eines Production-Builds.

Entwicklung

Entwicklungsserver mit Hot Reload starten:

Terminal
npm run dev

Production-Vorschau

Production-Umgebung lokal prüfen — App bauen, dann Production-Server starten:

Terminal
npm run build
Terminal
npm run start
Referenz

Skript-Referenz

BefehlBeschreibung
supabase db pushDatenbankschema anwenden (supabase db push)
npm run sync:plansSeed-Pläne mit Stripe-Produkten/Preisen synchronisieren
npm run devEntwicklungsserver starten
npm run buildProduction-Build
npm run startProduction-Server starten (nach Build)
npm run testJest-Unit-Tests ausführen (nur Services)
Referenz

Architektur

Vier Schichten mit strikter Aufrufreihenfolge — Agents und Entwickler folgen demselben Pfad:

UI → Server Actions / API → Services → Repositories → PostgreSQL (RLS/RPC)

Wichtige Orte:

1

Schicht 1

Präsentation — src/app/, src/components/

2

Schicht 2

Anwendung — Server Actions, createRequestContext(), RBAC-Guards

3

Schicht 3

Domain — src/modules/*/ *.service.ts (Geschäftslogik)

4

Schicht 4

Daten — Repositories + PostgreSQL RLS/RPCs via src/services/

Referenz

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.

Referenz

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 Mitgliederverwaltung
  • adminMitglieder einladen/entfernen, Workspace-Einstellungen aktualisieren
  • memberLesen und teilnehmen — keine Admin-Aktionen
Referenz

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~15 Min.

Deployment

Empfohlener Stack: Vercel (Next.js) + Supabase Cloud + Stripe-Webhooks.

  1. 1Schema auf Production-Supabase anwenden (supabase db push)
  2. 2Alle Env-Variablen in Vercel setzen — Abschnitt Umgebungs-Setup oben
  3. 3Next.js-App deployen
  4. 4Stripe-Webhook registrieren → https://IHRE_APP_URL/api/stripe/webhook
  5. 5Super-Admin bootstrappen und sync:plans in Production ausführen