feat(api): wire Novu lifecycle email triggers
Some checks failed
QA Gate (P0/P1) / Test affected app (pull_request) Has been cancelled

Route all lifecycle/transactional emails through Novu
(api.bildirim.semih.ai, delivered via Postal). A framework-agnostic
client is shared by the NestJS API and the standalone BullMQ worker.

- welcome + referral on signup (better-auth user.create.after)
- email-verification + password-reset (auth.ts; token links never
  track-wrapped so the one-time token survives)
- referral-qualified / referral-reward to the referrer on qualification
- payment-success / payment-failed in the Stripe webhook handlers
- trial-ending + win-back via a new daily lifecycle-email cron (worker),
  idempotent via a 1-day endDate window (no sent-flag column)
- signed track.sase.tr CTA links when MAILTRACK_SECRET is set
- NOVU_* / APP_PUBLIC_URL / MAILTRACK_SECRET env added to config,
  validation, .env.example and both compose service blocks

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-27 01:30:39 +03:00
parent d35a009653
commit 1c79c18aff
18 changed files with 665 additions and 8 deletions

View File

@@ -53,6 +53,11 @@ services:
- POSTAL_API_KEY=${POSTAL_API_KEY:-}
- POSTAL_FROM_ADDRESS=${POSTAL_FROM_ADDRESS:-noreply@sase.tr}
- POSTAL_FROM_NAME=${POSTAL_FROM_NAME:-Sase.tr}
# Novu lifecycle e-mail automation (Tailscale-only; sends via Postal)
- NOVU_API_URL=${NOVU_API_URL:-https://api.bildirim.semih.ai}
- NOVU_API_KEY=${NOVU_API_KEY:-}
- APP_PUBLIC_URL=${APP_PUBLIC_URL:-https://sase.tr}
- MAILTRACK_SECRET=${MAILTRACK_SECRET:-}
- OTEL_ENABLED=${OTEL_ENABLED:-false}
- OTEL_EXPORTER_OTLP_ENDPOINT=${OTEL_EXPORTER_OTLP_ENDPOINT:-}
- OTEL_EXPORTER_OTLP_HEADERS=${OTEL_EXPORTER_OTLP_HEADERS:-}
@@ -111,6 +116,11 @@ services:
- PCAT_PROXY_HOST=${PCAT_PROXY_HOST:-gw.dataimpulse.com}
- PCAT_PROXY_USER=${PCAT_PROXY_USER:-}
- PCAT_PROXY_PASS=${PCAT_PROXY_PASS:-}
# Novu lifecycle e-mail automation — the worker fires trial-ending + win-back
- NOVU_API_URL=${NOVU_API_URL:-https://api.bildirim.semih.ai}
- NOVU_API_KEY=${NOVU_API_KEY:-}
- APP_PUBLIC_URL=${APP_PUBLIC_URL:-https://sase.tr}
- MAILTRACK_SECRET=${MAILTRACK_SECRET:-}
- OTEL_ENABLED=${OTEL_ENABLED:-false}
- OTEL_EXPORTER_OTLP_ENDPOINT=${OTEL_EXPORTER_OTLP_ENDPOINT:-}
- OTEL_EXPORTER_OTLP_HEADERS=${OTEL_EXPORTER_OTLP_HEADERS:-}