added marketing-building-blog-v1

This commit is contained in:
Rajpreet0 2026-10-02 17:31:08 +02:00
parent a9f248c91d
commit dc4f08ab0c
71 changed files with 6307 additions and 183 deletions

View file

@ -18,22 +18,34 @@ Kein Docker: die App ist ein reines Next.js 16 (App Router) Full-Stack-Projekt o
Alle in Vercel unter **Project Settings → Environment Variables**, Scope **"Preview"** (niemals "Production" — das hält Staging- und Produktions-Secrets sauber getrennt).
| Variable | Quelle |
| ---------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- |
| `DATABASE_URL` | Supabase Staging, Transaction Pooler, Port 6543, `?pgbouncer=true&connection_limit=1` |
| `DIRECT_URL` | Supabase Staging, **Session Pooler** (nicht Direct Connection!), Port 5432 — siehe Stolperfalle unten |
| `NEXT_PUBLIC_SUPABASE_URL` | Supabase Staging Projekt-URL |
| `NEXT_PUBLIC_SUPABASE_ANON_KEY` | Supabase Staging anon key |
| `SUPABASE_SERVICE_ROLE_KEY` | Supabase Staging service_role key |
| `RESEND_API_KEY` / `RESEND_FROM` / `SMTP_TEST_MAIL` | wiederverwendet von lokal |
| `STRIPE_SECRET_KEY` / `NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY` | Test-Mode-Keys, wiederverwendet von lokal |
| `STRIPE_WEBHOOK_SECRET` | eigener Wert, siehe Stripe-Webhook unten |
| `STRIPE_PLATFORM_FEE_PERCENT` | gleicher Wert wie lokal |
| `NEXT_PUBLIC_SITE_URL` / `NEXT_PUBLIC_APP_URL` | `https://kumasy-git-dev-kumasy.vercel.app` |
| `COMPANY_NAME` | `"Kumasy"` |
| Variable | Quelle |
| ---------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
| `DATABASE_URL` | Supabase Staging, Transaction Pooler, Port 6543, `?pgbouncer=true&connection_limit=1` |
| `DIRECT_URL` | Supabase Staging, **Session Pooler** (nicht Direct Connection!), Port 5432 — siehe Stolperfalle unten |
| `NEXT_PUBLIC_SUPABASE_URL` | Supabase Staging Projekt-URL |
| `NEXT_PUBLIC_SUPABASE_ANON_KEY` | Supabase Staging anon key |
| `SUPABASE_SERVICE_ROLE_KEY` | Supabase Staging service_role key |
| `RESEND_API_KEY` / `RESEND_FROM` / `SMTP_TEST_MAIL` | wiederverwendet von lokal |
| `STRIPE_SECRET_KEY` / `NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY` | Test-Mode-Keys, wiederverwendet von lokal |
| `STRIPE_WEBHOOK_SECRET` | eigener Wert, siehe Stripe-Webhook unten |
| `STRIPE_PLATFORM_FEE_PERCENT` | gleicher Wert wie lokal |
| `NEXT_PUBLIC_SITE_URL` / `NEXT_PUBLIC_APP_URL` | `https://kumasy-git-dev-kumasy.vercel.app` |
| `COMPANY_NAME` | `"Kumasy"` |
| `CRON_SECRET` | eigener Zufallswert (`openssl rand -hex 32`), schützt `/api/cron/marketing`, siehe Marketing-Cron unten |
| `MARKETING_TOKEN_SECRET` | eigener Zufallswert, signiert die Abmeldelinks in Marketing-Mails - nie ändern, sonst gehen alte Links nicht mehr |
Lokales Pendant für einmalige DB-Operationen gegen Staging (z.B. neue Migrationen einspielen): `.env.staging` im Repo-Root, gitignored (`.env*` steht in `.gitignore`), wird nie committed.
## Marketing-Cron
Automatische Marketing-Mails (Geburtstag, Meilenstein, Reaktivierung) verschickt einmal täglich `GET /api/cron/marketing`. Die Route prüft nur den Header `Authorization: Bearer <CRON_SECRET>` - wer sie aufruft, ist egal:
- **Production:** Vercel Cron aus `vercel.json` (täglich 07:00 UTC = 9 Uhr Sommer / 8 Uhr Winter). Vercel setzt den Header selbst, sobald `CRON_SECRET` als Umgebungsvariable existiert. Vercel Cron läuft **nur auf Production-Deployments**.
- **Staging:** Job bei [cron-job.org](https://cron-job.org) auf `https://kumasy-git-dev-kumasy.vercel.app/api/cron/marketing`, täglich, mit dem Header `Authorization: Bearer <CRON_SECRET aus Vercel Preview>`. Ist die Vercel Deployment Protection für Previews an, zusätzlich `x-vercel-protection-bypass: <Bypass-Secret>` (Project Settings → Deployment Protection → Protection Bypass for Automation).
- **Lokal:** `npm run cron:marketing` (liest `CRON_SECRET` aus `.env`). Zum Testen: `-- --dry-run` (zeigt nur, wer was bekäme), `-- --date=2026-05-12` (tut so, als wäre heute dieser Tag), `-- --business=<id>`.
`date` ist in Production gesperrt. Doppelte Aufrufe sind harmlos: pro Studio, Kunde, Trigger-Art und Zeitraum gibt es höchstens eine Mail (Unique-Key in `MarketingSend`).
## Build Command (Vercel Project Settings → Build & Development Settings)
```