Newsletter / mailing list (premium feature #1) + SMTP wiring
Email infrastructure reuses src/config/mailer.js (env SMTP_*, graceful: without
SMTP no sending, sign-ups still work via single opt-in).
- DB: subscribers table (per-site, status pending/confirmed/unsub, token) +
newsletters table (send history). Idempotent in initializeDatabase.
- SubscriberService: addSubscriber (double opt-in if SMTP, otherwise single),
confirm, unsubscribe, confirmedFor, counts. Email validation + dedupe per
(site, email).
- routes/newsletter.js (public, premium-gated; unsubscribe always works):
GET/POST /nieuwsbrief, /nieuwsbrief/bevestigen/:token,
/nieuwsbrief/uitschrijven/:token. Confirm/unsub links absolute via
PUBLIC_BASE_URL + siteUrlBase.
- routes/admin-newsletter.js (site admin + premium): GET /admin/newsletter
(compose + counts + history + shareable signup link + SMTP warning),
POST /admin/newsletter/send (to confirmed subscribers, unsubscribe link per
email, history written).
- views: pages/newsletter.ejs (multi-state) + pages/admin-newsletter.ejs.
- admin dashboard: premium links Newsletter + Press kit added.
Feature #2 (download-for-email) and #8 (notify) reuse subscribers. node --check
passed; local test suite missing better-sqlite3 (runs on the VPS).
Co-Authored-By: Claude <noreply@…>