Production Checklist

Vollständige Go-Live-Checkliste für Umgebungsvariablen, Datenbank, Sicherheit, Zahlungen und Monitoring

Nutze diese Checkliste, um jedes System vor dem Launch deiner Kit-Anwendung zu überprüfen. Jeder Abschnitt deckt einen kritischen Bereich ab — Umgebungskonfiguration, Datenbankbereitschaft, Sicherheitshärtung, Authentifizierung, Zahlungen, Performance, SEO und Monitoring. Schließe alle Punkte ab, bevor du echte Nutzer auf deine Production-URL weiterleitest.

Umgebungsvariablen

Jeder externe Dienst benötigt Production-Zugangsdaten. Die Verwendung von Entwicklungs- oder Test-Schlüsseln in Production führt zu stillen Fehlern, Datenverlust oder Sicherheitslücken.
1

Production-App-URL setzen

bash
NEXT_PUBLIC_APP_URL=https://yourdomain.com
Dieser Wert wird für absolute URLs in E-Mails, Sitemap-Generierung, Open Graph Tags und Webhook-Callbacks verwendet. Ein falscher Wert führt zu defekten Links in der gesamten Anwendung.
2

CORS-Origins konfigurieren

bash
ALLOWED_ORIGINS=https://yourdomain.com
3

Rate Limiting aktivieren

bash
UPSTASH_REDIS_REST_URL=https://your-redis.upstash.io
UPSTASH_REDIS_REST_TOKEN=your-token
Rate Limiting ist in Production erforderlich. Ohne Upstash Redis ist das gesamte API Rate Limiting deaktiviert und deine Endpunkte sind Missbrauch ausgesetzt. Kit verwendet kategoriebasiertes Rate Limiting (Auth, API, KI, Webhooks) mit unterschiedlichen Limits pro Kategorie.
4

Cron Secret setzen

bash
CRON_SECRET=your-random-32-char-string
Generiere mit openssl rand -base64 32. Vercel Cron Jobs senden diesen Wert im Authorization-Header. Ohne ihn lehnen die Trial-Check- und Credit-Expiry-Endpunkte alle Anfragen ab.
5

Alle Service-Schlüssel auf Production-Schlüssel prüfen

Bestätige, dass jeder API-Schlüssel von der Production-Instanz des jeweiligen Dienstes stammt, nicht von Entwicklung oder Test:
DienstEntwicklungsschlüssel-MusterProduction-Schlüssel-Muster
Clerkpk_test_... / sk_test_...pk_live_... / sk_live_...
Lemon SqueezyTestmodus im DashboardLive-Modus im Dashboard
SupabaseLokales oder Staging-ProjektProduction-Projekt
ResendEntwicklungsdomainVerifizierte Production-Domain
UpstashBeliebige InstanzProduction-Tier-Instanz
KI-ProviderAI_API_KEY=... oder individuelle SchlüsselProduction-Schlüssel vom jeweiligen Provider-Dashboard
6

KI-Provider-Schlüssel konfigurieren

Falls deine Anwendung KI-Features verwendet (LLM Chat, RAG Chat, Vision Chat), stelle sicher, dass mindestens ein Provider-Schlüssel konfiguriert ist:
SetupBenötigte Variablen
Einfach (einzelner Provider)AI_PROVIDER + AI_API_KEY
Erweitert (Multi-Provider-Fallback)Provider-spezifische Schlüssel: OPENAI_API_KEY, ANTHROPIC_API_KEY, etc.
RAG-FeaturesOPENAI_API_KEY ist erforderlich für die Embedding-Generierung, auch wenn dein Chat-Provider Anthropic/Google/xAI ist
Konfiguriere KI-Feature-Flags entsprechend deinen Anforderungen:
FlagStandardZweck
NEXT_PUBLIC_AI_LLM_CHAT_ENABLEDtrueLLM Chat auf /dashboard/chat-llm
NEXT_PUBLIC_AI_RAG_CHAT_ENABLEDtrueRAG Chat auf /dashboard/chat-rag
NEXT_PUBLIC_AI_VISION_ENABLEDtrueBildanalyse im LLM Chat (erfordert aktivierten LLM Chat)
NEXT_PUBLIC_AI_AUDIO_INPUT_ENABLEDtrueSpracheingabe im LLM Chat (erfordert aktivierten LLM Chat)
NEXT_PUBLIC_AI_PDF_CHAT_ENABLEDtruePDF-Analyse im LLM Chat (erfordert aktivierten LLM Chat)
NEXT_PUBLIC_AI_IMAGE_GEN_ENABLEDtrueBildgenerierung auf /dashboard/image-gen (erfordert OPENAI_API_KEY)
NEXT_PUBLIC_AI_CONTENT_GEN_ENABLEDtrueContent Generator auf /dashboard/content
Siehe KI-Provider für die vollständige Provider-Einrichtungsanleitung.

Datenbank

1

Migrationen in Production ausführen

bash
cd apps/boilerplate && npx prisma migrate deploy
Das wendet alle ausstehenden Migrationen auf deine Production-Datenbank an. Im Gegensatz zu prisma db push (für die Entwicklung) ist migrate deploy sicher für Production — es wendet nur neue Migrationen an und setzt niemals Daten zurück.
2

Connection Pooling überprüfen

Kit verwendet zwei Datenbankverbindungs-Strings:
VariableZweckVerbindungstyp
DATABASE_URLAnwendungsabfragenGepoolte Verbindung (via PgBouncer, Port 6543)
DIRECT_URLPrisma-MigrationenDirekte Verbindung (Port 5432)
Supabase stellt beide URLs in den Projekteinstellungen bereit. Die gepoolte Verbindung verarbeitet gleichzeitige Anfragen effizient, während die direkte Verbindung für Schema-Migrationen benötigt wird.
3

pgvector-Erweiterung überprüfen

Falls du RAG-Features verwendest (KI-Dokumenten-Chat), muss die pgvector-Erweiterung aktiviert sein:
sql
CREATE EXTENSION IF NOT EXISTS vector;
Supabase aktiviert das automatisch, aber überprüfe es, falls du von einem anderen Provider migriert bist.

Sicherheit

Kit enthält eine umfassende Sicherheitsschicht, die standardmäßig aktiv ist. Überprüfe, ob diese Einstellungen für deine Production-Umgebung korrekt konfiguriert sind.
1

Sicherheits-Header (automatisch konfiguriert)

Die folgenden Header werden auf alle Routen via next.config.mjs angewendet:
next.config.mjs — Production Security Headers
// Security Headers
  async headers() {
    return [
      {
        source: '/:path*',
        headers: [
          {
            key: 'X-DNS-Prefetch-Control',
            value: 'on',
          },
          {
            key: 'X-Frame-Options',
            value: 'SAMEORIGIN',
          },
          {
            key: 'X-Content-Type-Options',
            value: 'nosniff',
          },
          {
            key: 'X-XSS-Protection',
            value: '1; mode=block',
          },
          {
            key: 'Referrer-Policy',
            value: 'strict-origin-when-cross-origin',
          },
          {
            key: 'Permissions-Policy',
            value: 'camera=(), microphone=(self), geolocation=(), interest-cohort=(), payment=(), usb=()',
          },
          {
            key: 'Content-Security-Policy',
            value: ContentSecurityPolicy.replace(/\s{2,}/g, ' ').trim(),
          },
        ],
      },
    ]
  },
HeaderSchutz
Content-Security-PolicyVerhindert XSS durch Einschränkung von Script-/Style-/Bildquellen
X-Frame-OptionsVerhindert Clickjacking durch Blockierung von iframe-Einbettung
X-Content-Type-OptionsVerhindert MIME-Type-Sniffing-Angriffe
X-XSS-ProtectionLegacy-XSS-Filter für ältere Browser
Referrer-PolicyKontrolliert Informationen, die im Referer-Header gesendet werden
Permissions-PolicySchränkt Kamera und Geolocation ein; Mikrofon für Same-Origin-Audioeingabe erlaubt
Diese werden automatisch angewendet — keine Konfiguration erforderlich. Falls du neue vertrauenswürdige Script-Quellen hinzufügst (Analytics, Chat-Widgets), aktualisiere das TRUSTED_SCRIPT_SOURCES-Array in next.config.mjs.
2

CORS-Origins eingeschränkt

Überprüfe, ob ALLOWED_ORIGINS nur deine Production-Domain enthält. Die Sicherheits-Middleware lehnt API-Anfragen von Origins ab, die nicht in dieser Liste stehen.
3

Rate Limiting aktiv

Überprüfe, ob Upstash Redis-Zugangsdaten gesetzt sind. Teste, indem du den Health-Endpunkt aufrufst:
bash
curl https://yourdomain.com/api/health
Falls Rate Limiting aktiv ist, geben schnell wiederholte Anfragen 429 Too Many Requests zurück.
4

API-Schlüssel-Rotationsplan erstellen

Setze Erinnerungen für regelmäßige Schlüssel-Rotation:
KategorieRotationsintervallDienste
KritischAlle 90 TageClerk, Lemon Squeezy, Supabase Service Role
StandardAlle 180 TageResend, Upstash, Vercel Blob, KI-Provider
Siehe die Sicherheitsübersicht für detaillierte Rotationsverfahren.
5

Eingabe-Sanitierung (eingebaut)

Kit sanitiert alle Benutzereingaben serverseitig gegen XSS und SQL-Injection. Das ist standardmäßig in API-Routen und Server Actions aktiv — keine Konfiguration erforderlich.

Authentifizierung

1

Clerk Production-Instanz verwenden

Clerk trennt Entwicklungs- und Production-Instanzen. Dein Production Deployment muss die Production-Instanz verwenden:
  • Publishable Key beginnt mit pk_live_
  • Secret Key beginnt mit sk_live_
Die Verwendung von pk_test_-Schlüsseln in Production zeigt ein Entwicklungs-Banner und schränkt die Funktionalität ein.
2

Webhook-Endpunkt konfigurieren

Setze die Clerk-Webhook-URL auf deine Production-Domain:
https://yourdomain.com/api/webhooks/clerk
Füge das Webhook-Secret als CLERK_WEBHOOK_SECRET in deinen Vercel-Umgebungsvariablen hinzu. Kit verwendet Clerk-Webhooks, um Benutzerdaten mit der lokalen Datenbank zu synchronisieren.
3

Social-Login-Provider aktivieren

Aktiviere und konfiguriere im Clerk Dashboard mindestens:
  • Google — Deckt die meisten Nutzer ab
  • GitHub — Wichtig für entwicklerorientierte SaaS
Jeder Provider benötigt OAuth-Zugangsdaten von der jeweiligen Plattform. Das Clerk-Dashboard führt dich durch die Einrichtung.
4

Authentifizierungsflow testen

Überprüfe nach dem Deployment den vollständigen Flow:
  1. Neues Konto registrieren
  2. Mit E-Mail und Passwort einloggen
  3. Mit einem Social-Provider einloggen
  4. Passwort per E-Mail zurücksetzen
  5. Eine geschützte Route aufrufen (/dashboard)
  6. Ausloggen und Weiterleitung überprüfen

Zahlungen

1

Zu Lemon Squeezy Production-Modus wechseln

Stelle im Lemon Squeezy Dashboard sicher, dass dein Shop im Live-Modus ist (nicht im Testmodus). Testmodus-Transaktionen verarbeiten keine echten Zahlungen.
2

Production-Webhook konfigurieren

Setze die Webhook-URL im Lemon Squeezy Dashboard:
https://yourdomain.com/api/webhooks/lemonsqueezy
Überprüfe, ob das Webhook-Secret mit LEMONSQUEEZY_WEBHOOK_SECRET in deiner Vercel-Umgebung übereinstimmt.
3

Alle Plan-Variant-IDs setzen

Jeder Preisplan benötigt seine konfigurierte Lemon Squeezy Variant-ID:
bash
# Abonnementbasierte Preisgestaltung
NEXT_PUBLIC_LEMONSQUEEZY_BASIC_MONTHLY_VARIANT_ID=...
NEXT_PUBLIC_LEMONSQUEEZY_BASIC_YEARLY_VARIANT_ID=...
NEXT_PUBLIC_LEMONSQUEEZY_PRO_MONTHLY_VARIANT_ID=...
NEXT_PUBLIC_LEMONSQUEEZY_PRO_YEARLY_VARIANT_ID=...
NEXT_PUBLIC_LEMONSQUEEZY_ENTERPRISE_MONTHLY_VARIANT_ID=...
NEXT_PUBLIC_LEMONSQUEEZY_ENTERPRISE_YEARLY_VARIANT_ID=...

# Kreditbasierte Preisgestaltung (bei Verwendung von NEXT_PUBLIC_PRICING_MODEL=credit_based)
NEXT_PUBLIC_CREDIT_BASIC_MONTHLY_VARIANT_ID=...
NEXT_PUBLIC_CREDIT_PRO_MONTHLY_VARIANT_ID=...
NEXT_PUBLIC_CREDIT_ENTERPRISE_MONTHLY_VARIANT_ID=...

# Bonus-Credit-Pakete (falls NEXT_PUBLIC_BONUS_CREDITS_ENABLED=true)
NEXT_PUBLIC_BONUS_BASIC_PACKAGE1_VARIANT_ID=...
NEXT_PUBLIC_BONUS_BASIC_PACKAGE2_VARIANT_ID=...
NEXT_PUBLIC_BONUS_PRO_PACKAGE1_VARIANT_ID=...
NEXT_PUBLIC_BONUS_PRO_PACKAGE2_VARIANT_ID=...
NEXT_PUBLIC_BONUS_ENTERPRISE_PACKAGE1_VARIANT_ID=...
NEXT_PUBLIC_BONUS_ENTERPRISE_PACKAGE2_VARIANT_ID=...
Fehlende Variant-IDs führen dazu, dass der Checkout-Button lautlos fehlschlägt. Bonus-Paket-Variant-IDs sind nur erforderlich, wenn NEXT_PUBLIC_BONUS_CREDITS_ENABLED=true — siehe Lemon Squeezy Setup zum Erstellen der Einmalkauf-Produkte.
4

Kunden-Portal-URL setzen

bash
NEXT_PUBLIC_LEMONSQUEEZY_CUSTOMER_PORTAL_URL=https://your-store.lemonsqueezy.com/billing
Diese URL ermöglicht es Kunden, Abonnements zu verwalten, Zahlungsmethoden zu aktualisieren und Rechnungen direkt über Lemon Squeezy's gehostetes Portal herunterzuladen.
5

Zahlungsflow testen

Führe eine echte Transaktion in Production durch:
  1. Preisseite aufrufen
  2. Auf Upgrade für einen Plan klicken
  3. Checkout mit einer echten Zahlungsmethode abschließen
  4. Überprüfen, ob der Webhook das Abonnement verarbeitet
  5. Bestätigen, dass der Plan des Nutzers im Dashboard aktualisiert wird
  6. Kündigung und Rückerstattung über das Kunden-Portal testen

Performance

1

Bundle-Größe analysieren

Führe den Bundle-Analyzer aus, um zu überprüfen, ob dein Production-Bundle Kits Performance-Ziele erfüllt:
bash
ANALYZE=true pnpm build:boilerplate
Das generiert HTML-Berichte in apps/boilerplate/.next/analyze/, die die genaue Größe jedes Moduls zeigen.
MetrikZiel
Initiales JS-Load< 200 KB (gzipped)
Pro-Route-Chunks< 50 KB (gzipped)
Lighthouse Performance> 90
2

Bildoptimierung überprüfen

Kit verhandelt automatisch das beste Bildformat pro Browser:
next.config.mjs — Image Configuration
images: {
    remotePatterns: [
      {
        protocol: 'https',
        hostname: 'images.unsplash.com',
        port: '',
        pathname: '/**',
      },
      {
        protocol: 'https',
        hostname: 'images.clerk.dev',
        port: '',
        pathname: '/**',
      },
      {
        protocol: 'https',
        hostname: 'img.clerk.com',
        port: '',
        pathname: '/**',
      },
      {
        protocol: 'https',
        hostname: '*.clerkstatic.com',
        port: '',
        pathname: '/**',
      },
      {
        protocol: 'https',
        hostname: 'lh3.googleusercontent.com',
        port: '',
        pathname: '/**',
      },
      {
        protocol: 'https',
        hostname: 'avatars.githubusercontent.com',
        port: '',
        pathname: '/**',
      },
    ],
    formats: ['image/avif', 'image/webp'],
  },
Die Einstellung formats: ['image/avif', 'image/webp'] liefert automatisch AVIF an Browser, die es unterstützen (40-50% kleiner als WebP), und fällt für andere auf WebP zurück. Keine manuelle Konvertierung nötig — Next.js übernimmt das am Edge.
3

Lighthouse-Audit ausführen

Führe einen Lighthouse-Audit gegen deine Production-URL aus:
  1. Chrome DevTools öffnen > Lighthouse
  2. Performance, Accessibility, Best Practices, SEO auswählen
  3. Auf Analyze page load klicken
Zielwerte:
KategorieZiel
Performance> 90
Accessibility> 90
Best Practices> 90
SEO> 90

SEO

1

robots.txt überprüfen

Kit generiert robots.txt dynamisch und blockiert sensible Routen vor Suchmaschinen:
src/app/robots.ts
import { MetadataRoute } from 'next'

/**
 * robots.txt Generator
 *
 * Blocks search engines from accessing protected routes:
 * - /api/* - API endpoints (internal)
 * - /dashboard/* - Authenticated app pages
 * - /(auth)/* - Authentication flow pages
 * - /admin/* - Admin pages
 * - /_next/* - Next.js internals
 * - /private/* - Private resources
 *
 * AI Crawlers: llms.txt available at /llms.txt per llmstxt.org standard.
 */
export default function robots(): MetadataRoute.Robots {
  const baseUrl = process.env.NEXT_PUBLIC_APP_URL || 'https://localhost:3000'

  return {
    rules: [
      {
        userAgent: '*',
        allow: '/',
        disallow: [
          '/api/',
          '/dashboard/',
          '/(dashboard)/',
          '/(auth)/',
          '/admin/',
          '/_next/',
          '/private/',
        ],
      },
    ],
    sitemap: `${baseUrl}/sitemap.xml`,
    host: baseUrl,
  }
}
Wichtige Regeln:
  • Erlaubt alle öffentlichen Seiten (/, /login, /register, /privacy, /terms, /imprint)
  • Blockiert API-Routen (/api/), Dashboard (/dashboard/), Auth-Seiten, Admin und interne Next.js-Routen
2

Sitemap überprüfen

Kit generiert sitemap.xml dynamisch aus deinen Routen:
src/app/sitemap.ts
import { MetadataRoute } from 'next'

export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
  const baseUrl = process.env.NEXT_PUBLIC_APP_URL || 'https://localhost:3000'

  // Static pages
  const staticPages = [
    '',
    '/login',
    '/register',
    '/privacy',
    '/terms',
    '/imprint',
  ].map((route) => ({
    url: `${baseUrl}${route}`,
    lastModified: new Date().toISOString(),
    changeFrequency: (route === '' ? 'daily' : 'weekly') as 'daily' | 'weekly',
    priority: route === '' ? 1 : 0.8,
  }))

  return staticPages
}
Die Sitemap verwendet NEXT_PUBLIC_APP_URL für alle URLs. Überprüfe, ob sie deine Production-Domain zurückgibt, indem du https://yourdomain.com/sitemap.xml aufrufst.
3

llms.txt überprüfen

Kit generiert llms.txt gemäß dem llmstxt.org-Standard und bietet KI-Crawlern (ChatGPT, Claude, Perplexity) strukturierten Zugriff auf deine Website:
src/app/llms.txt/route.ts
/**
 * ============================================================================
 * llms.txt Route Handler
 * ============================================================================
 *
 * Generates a Markdown file following the llmstxt.org standard.
 * Provides AI crawlers (ChatGPT, Claude, Perplexity) with structured
 * access to your site's public content.
 *
 * CUSTOMIZATION AFTER PURCHASE:
 * 1. Update the description text to match your product
 * 2. Add your public pages/features to the "Pages" section
 * 3. Add a "## Docs" section if you have public documentation
 * 4. Add a "## API" section if you have a public API
 *
 * @see https://llmstxt.org
 * ============================================================================
 */

import { siteConfig } from '@/config/site'

export const dynamic = 'force-static'

export async function GET() {
  const baseUrl = process.env.NEXT_PUBLIC_APP_URL || 'https://localhost:3000'

  const lines: string[] = []

  // Title (H1) — per llmstxt.org spec
  lines.push(`# ${siteConfig.name}`)
  lines.push('')

  // Blockquote description
  lines.push(`> ${siteConfig.tagline} — ${siteConfig.description}`)
  lines.push('')

  // Detailed description
  lines.push(
    `${siteConfig.name} is a SaaS application built with Next.js.`
  )
  lines.push('')

  // Public pages
  lines.push('## Pages')
  lines.push('')
  lines.push(`- [Login](${baseUrl}/login): Sign in to your account`)
  lines.push(`- [Register](${baseUrl}/register): Create a new account`)
  lines.push(
    `- [Privacy Policy](${baseUrl}/privacy): Privacy policy and data handling`
  )
  lines.push(
    `- [Terms of Service](${baseUrl}/terms): Terms and conditions`
  )
  lines.push(
    `- [Legal Notice](${baseUrl}/imprint): Legal notice and company information`
  )
  lines.push('')

  const content = lines.join('\n')

  return new Response(content, {
    headers: {
      'Content-Type': 'text/plain; charset=utf-8',
      'Cache-Control':
        'public, s-maxage=86400, stale-while-revalidate=604800',
    },
  })
}
Überprüfe, ob gültiges Markdown zurückgegeben wird, indem du https://yourdomain.com/llms.txt aufrufst. Eine .well-known/llms.txt-Weiterleitung ist ebenfalls für Crawler enthalten, die diesen Pfad prüfen.
4

Benutzerdefinierte Fehlerseiten überprüfen

Kit enthält benutzerdefinierte 404- und 500-Fehlerseiten. Teste sie:
  • 404 — Rufe https://yourdomain.com/nonexistent-page auf
  • 500 — Überprüfe, ob die Error-Boundary eine benutzerfreundliche Meldung rendert (teste in der Entwicklung mit einem absichtlichen Fehler)

Monitoring

1

Health-Endpunkt überprüfen

Kit enthält einen Health-Check-Endpunkt, der die Datenbankverbindung und Speichernutzung überwacht:
src/app/api/health/route.ts
import { NextResponse } from 'next/server'
import { prisma } from '@/lib/db'

export const runtime = 'nodejs'
export const dynamic = 'force-dynamic'

interface HealthCheck {
  status: 'healthy' | 'unhealthy'
  timestamp: string
  version: string
  environment: string
  checks: {
    database: 'healthy' | 'unhealthy' | 'unknown'
    memory: {
      used: number
      limit: number
      percentage: number
    }
  }
  error?: string
}

export async function GET() {
  const startTime = Date.now()

  try {
    // Check database connection
    let databaseStatus: 'healthy' | 'unhealthy' | 'unknown' = 'unknown'

    try {
      await prisma.$queryRaw`SELECT 1`
      databaseStatus = 'healthy'
    } catch (dbError) {
      console.error('Database health check failed:', dbError)
      databaseStatus = 'unhealthy'
    }

    // Memory usage
    const memoryUsage = process.memoryUsage()
    const memoryLimit = 512 * 1024 * 1024 // 512MB default for Vercel
    const memoryPercentage = (memoryUsage.heapUsed / memoryLimit) * 100

    const healthCheck: HealthCheck = {
      status: databaseStatus === 'healthy' ? 'healthy' : 'unhealthy',
      timestamp: new Date().toISOString(),
      version: process.env.NEXT_PUBLIC_APP_VERSION || '1.0.0',
      environment: process.env.NODE_ENV || 'development',
      checks: {
        database: databaseStatus,
        memory: {
          used: Math.round(memoryUsage.heapUsed / 1024 / 1024),
          limit: Math.round(memoryLimit / 1024 / 1024),
          percentage: Math.round(memoryPercentage),
        },
      },
    }

    const responseTime = Date.now() - startTime

    return NextResponse.json(
      {
        ...healthCheck,
        responseTime: `${responseTime}ms`,
      },
      {
        status: healthCheck.status === 'healthy' ? 200 : 503,
        headers: {
          'Cache-Control': 'no-cache, no-store, must-revalidate',
        },
      }
    )
  } catch (error) {
    console.error('Health check error:', error)

    return NextResponse.json(
      {
        status: 'unhealthy',
        timestamp: new Date().toISOString(),
        version: process.env.NEXT_PUBLIC_APP_VERSION || '1.0.0',
        environment: process.env.NODE_ENV || 'development',
        error: error instanceof Error ? error.message : 'Unknown error',
        responseTime: `${Date.now() - startTime}ms`,
      },
      {
        status: 503,
        headers: {
          'Cache-Control': 'no-cache, no-store, must-revalidate',
        },
      }
    )
  }
}
Teste ihn nach dem Deployment:
bash
curl https://yourdomain.com/api/health
Erwartete Antwort:
json
{
  "status": "healthy",
  "timestamp": "2026-01-15T10:30:00.000Z",
  "version": "1.0.0",
  "environment": "production",
  "checks": {
    "database": "healthy",
    "memory": {
      "used": 85,
      "limit": 512,
      "percentage": 17
    }
  },
  "responseTime": "45ms"
}
Eine 200-Antwort bedeutet, dass die Datenbank verbunden und der Speicher innerhalb der Limits ist. Eine 503-Antwort bedeutet, dass der Datenbankcheck fehlgeschlagen ist.
2

Cron Jobs überprüfen

Prüfe das Vercel Dashboard unter dem Cron-Tab, um zu bestätigen, dass beide geplanten Jobs registriert sind:
JobZeitplanNächster Durchlauf
/api/cron/check-trials0 2 * * * (2 Uhr UTC)Zeigt nächste Ausführungszeit
/api/cron/expire-bonus-credits0 3 * * * (3 Uhr UTC)Zeigt nächste Ausführungszeit
Du kannst jeden Cron Job manuell über das Dashboard auslösen, um zu überprüfen, ob er korrekt ausgeführt wird.
3

Error Tracking einrichten (empfohlen)

Kit enthält keinen spezifischen Error-Tracking-Dienst, aber wir empfehlen, einen für Production-Sichtbarkeit hinzuzufügen:
DienstIntegration
Sentry@sentry/nextjs — Automatische Fehlererfassung für Client und Server
Vercel AnalyticsEingebaut — Im Vercel Dashboard aktivieren
Vercel Speed InsightsEingebaut — Real-User-Performance-Monitoring
Sentry ist die umfassendste Option. Füge das @sentry/nextjs-Paket hinzu und konfiguriere es mit deinem DSN, um unbehandelte Fehler, Performance-Traces und Session-Replays zu erfassen.

Nach dem Launch

Nachdem deine Anwendung live ist, überwache diese Bereiche in den ersten 24-48 Stunden:
1

Deployment überprüfen

bash
# Health Check
curl https://yourdomain.com/api/health

# HTTPS-Weiterleitung überprüfen
curl -I http://yourdomain.com
# Sollte 301/308 Weiterleitung zu https:// zurückgeben
2

Kritische User Flows testen

Gehe den vollständigen User Journey durch:
  1. Registrierung — Neues Konto registrieren (E-Mail + Social Login)
  2. Anmeldung — Einloggen und Weiterleitung zum Dashboard überprüfen
  3. Zahlung — Abonnement- oder Credit-Kauf abschließen
  4. KI-Chat — Nachricht senden und Streaming-Antwort überprüfen. Falls Vision Chat aktiviert ist, Bild-Upload und Analyse testen. Falls Audio-Eingabe aktiviert ist, Sprachaufnahme und Transkription testen (falls KI aktiviert)
  5. Bildgenerierung — Bild generieren und korrekte Anzeige überprüfen (falls Image Gen aktiviert)
  6. Content Generator — Inhalt aus einer Vorlage generieren und Streaming-Ausgabe überprüfen (falls Content Gen aktiviert)
  7. Datei-Upload — Datei hochladen und persistente Speicherung überprüfen (falls Storage aktiviert)
  8. E-Mail — Transaktions-E-Mail auslösen und Zustellung überprüfen
3

Fehlerraten überwachen

Achte auf Spitzen bei:
  • Vercel Functions — Im Functions-Tab auf 500-Fehler prüfen
  • Webhook-Zustellung — Überprüfen, ob Clerk- und Lemon Squeezy-Webhooks erfolgreich sind
  • Cron-Ausführung — Bestätigen, dass der erste geplante Durchlauf erfolgreich abschließt
4

Uptime-Monitoring einrichten (empfohlen)

Richte einen Uptime-Monitor für deinen Health-Endpunkt ein:
GET https://yourdomain.com/api/health
Expected: 200 OK
Interval: 5 minutes
Kostenlose Optionen umfassen UptimeRobot, Better Stack oder Checkly. Konfiguriere Alerts für Ausfallzeiten, damit du sofort benachrichtigt wirst, wenn die Datenbankverbindung fehlschlägt oder die Anwendung abstürzt.

Vollständige Checkliste

Nutze diese Übersicht, um deinen Fortschritt zu verfolgen:
KategoriePunktStatus
UmgebungNEXT_PUBLIC_APP_URL auf Production-Domain gesetzt
UmgebungALLOWED_ORIGINS konfiguriert (keine Wildcards)
UmgebungUpstash Redis-Zugangsdaten gesetzt
UmgebungCRON_SECRET konfiguriert
UmgebungAlle Service-Schlüssel sind Production-Schlüssel
UmgebungKI-Provider-Schlüssel konfiguriert
UmgebungKI-Feature-Flags gesetzt (LLM_CHAT_ENABLED, RAG_CHAT_ENABLED, VISION_ENABLED, AUDIO_INPUT_ENABLED, PDF_CHAT_ENABLED, IMAGE_GEN_ENABLED, CONTENT_GEN_ENABLED)
Datenbankprisma migrate deploy ausgeführt
DatenbankConnection Pooling überprüft
SicherheitCORS-Origins eingeschränkt
SicherheitRate Limiting aktiv
SicherheitSchlüssel-Rotationsplan geplant
AuthClerk Production-Instanz aktiv
AuthWebhook-Endpunkt konfiguriert
AuthSocial-Login-Provider aktiviert
ZahlungenLemon Squeezy im Live-Modus
ZahlungenWebhook-URL auf Production-Domain gesetzt
ZahlungenAlle Variant-IDs konfiguriert
ZahlungenKunden-Portal-URL gesetzt
PerformanceBundle-Größe unter Zielwerten
PerformanceLighthouse-Score > 90
SEOrobots.txt überprüft
SEOsitemap.xml überprüft
SEOllms.txt überprüft
MonitoringHealth-Endpunkt gibt 200 zurück
MonitoringCron Jobs registriert
MonitoringError Tracking konfiguriert
Nach dem LaunchKritische Flows getestet
Nach dem LaunchUptime-Monitoring aktiv