- getTenantId wirft bei fehlendem Header statt silent fallback auf 'default'
- Alle API-Routes fangen den Fehler ab und antworten mit 401
- Worker gibt err() zurück wenn APP_URL nicht konfiguriert ist
- Migration: recipient_has_one Constraint schließt NULL/NULL-Zeilen aus
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- send/route.ts: try/catch + Rollback auf draft wenn Empfänger-Query oder Queue-Enqueue fehlschlägt
- campaigns.ts: Fehlermeldung 'Kampagne nicht im Draft-Status' (zuvor enthielt sie 'nicht gefunden' — verursachte falschen 404 in PATCH)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Implementiert vier Next.js App-Router API-Routen für das Campaign-Management:
- GET/POST /api/campaigns (Liste + Erstellen)
- GET/PATCH /api/campaigns/[id] (Einzeln abrufen + Aktualisieren)
- POST /api/campaigns/[id]/send (Sofortiger Versand — nur Draft-Status)
- POST /api/campaigns/[id]/schedule (Zeitplan setzen — once/cron/immediate)
Alle Routen lesen Tenant-ID aus x-tenant-id Header, nutzen das Result-Pattern
und validieren Eingaben über Zod-Schemas. Der Smoke-Test ist mit describe.skip
markiert, da next/server in Vitest nicht verfügbar ist.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>