Email Unsubscribe System Documentation
Overview
This system provides legally-compliant email unsubscribe functionality while protecting operational and transactional emails that users need.Email Categories
1. Marketing Emails (Can Unsubscribe) ✅ ACTIVE
When a user clicks “unsubscribe” from ANY marketing email, they are automatically unsubscribed from ALL marketing emails:- ✉️
feature_announcements- New feature announcements and product updates - ✉️
marketing_general- General marketing communications, webinars, and promotional content
EmailSubscriptionManager class.
2. Operational Emails (Managed in Settings UI) ✅ ACTIVE
Managed separately in Settings UI, independent of marketing unsubscribe:- 📊
emailDailySummary- Daily portfolio snapshots (via all_users table) - 📈
emailStockPriceSpikes- Stock price movement alerts - 💳
emailSpendingSpikes- Spending spike alerts - 📄
emailFinancialStatementSchedule- Scheduled financial statements
useEmailPreferences hook and Settings UI toggles.
3. Transactional Emails (Always Sent) ✅ ACTIVE
These emails are always sent regardless of user preferences (legal requirement):- 🔒
security- Security alerts and 2FA - 👋
welcome- Welcome and onboarding emails - 🗑️
account_deletion- Account deletion confirmations - ⚠️
error_notifications- Critical error alerts
User Experience Flow
Marketing Email Unsubscribe
- User receives marketing email (e.g., feature announcement, webinar invite)
- Clicks “Unsubscribe from marketing emails” link at bottom
- Automatically unsubscribed from BOTH marketing email types:
feature_announcements= falsemarketing_general= false
- Sees confirmation page explaining they’ll still receive:
- Daily financial snapshots (if enabled)
- Important account and security notifications
- Can manage detailed preferences in Settings → Email Notifications
Marketing Email Management in Settings
- User goes to Settings → Email Notifications
- Can toggle individual marketing preferences:
- ☑️ Feature Announcements - New features, product updates, improvements
- ☑️ Marketing & Promotions - Webinars, office hours, educational content
- Both have blue “Marketing” badges to distinguish from operational emails
Operational Email Management
- User goes to Settings → Email Notifications
- Can toggle individual preferences:
- ☑️ Portfolio Summary (Daily)
- ☑️ Spending Alerts (Weekly)
- ☑️ Stock Price Alerts (Daily)
- ☑️ Personal Financial Statement (Scheduled)
- These are independent of marketing email preferences
Technical Implementation
Permission Check Before Sending
Generate Unsubscribe Link
Using Marketing Preferences in Settings UI
Using Operational Email Preferences
Processing Unsubscribe
When token is clicked:- Validates token (not expired, not used)
- Checks if it’s a marketing email type
- If marketing → disables BOTH marketing preferences
- If operational → disables only that specific preference
- Redirects to confirmation page
Database Schema
email_preferences table
unsubscribe_tokens table
Legal Compliance
CAN-SPAM Act ✅
- ✅ One-click unsubscribe in all marketing emails
- ✅ Clear “Unsubscribe” language
- ✅ Processes unsubscribe within 10 business days (instant)
- ✅ Physical address in footer (Silvia contact info)
GDPR ✅
- ✅ Users can manage all preferences
- ✅ Clear explanation of email types
- ✅ Easy opt-out mechanism
- ✅ No dark patterns
Best Practices ✅
- ✅ Protects operational emails users need
- ✅ Clear communication about what continues
- ✅ Settings page for granular control
- ✅ Transactional emails always sent
Email Footer Template
All marketing emails must include:Key Files
Backend
/lib/email-subscription-manager.ts- Core EmailSubscriptionManager class/app/api/unsubscribe/route.ts- Unsubscribe token processing/app/api/marketing-preferences/route.ts- Marketing preferences CRUD/sql-queries/email-preferences-schema.sql- Database schema
Frontend
/app/settings/page.tsx- Settings page with email preference toggles/app/unsubscribe/page.tsx- Unsubscribe confirmation page/hooks/queries/use-marketing-preferences.ts- Marketing preferences hook/hooks/queries/use-email-preferences.ts- Operational email preferences hook
Email Templates
/emails/feature-announcement-email.tsx- Feature announcement template/emails/daily-email.tsx- Daily portfolio summary template
Testing Checklist
Before sending marketing emails:- Run SQL schema to create tables
- Test unsubscribe link generation
- Verify marketing email disables both marketing prefs
- Verify operational emails still work after unsubscribe
- Check confirmation page displays correctly
- Verify expired tokens are rejected
- Verify used tokens can’t be reused
- Test permission checks skip unsubscribed users
API Routes
Unsubscribe System
GET /api/unsubscribe?token=xxx- Process unsubscribe token and redirect to confirmationPOST /api/unsubscribe- Alternative POST method for unsubscribe
Marketing Preferences Management
GET /api/marketing-preferences- Fetch user’s marketing email preferencesPATCH /api/marketing-preferences- Update marketing preferences (feature_announcements, marketing_general)
Email Sending
GET /api/email/feature-announcement?secretKey=xxx- Send feature announcement emailsGET /api/email/daily?secretKey=xxx- Send daily portfolio summaries
Implemented Features
✅ Completed:- ✅ Email preference management UI in settings (both marketing and operational)
- ✅ Marketing preferences API endpoint
- ✅ Granular toggles for all email types
- ✅ Toast notifications on preference changes
- ✅ Real-time preference updates
- Resubscribe flow for users who change their mind
- Email frequency controls (e.g., digest mode)
- A/B testing for unsubscribe language
- Analytics dashboard for email preferences
- Email preview before scheduling
How to Send a Marketing Email (Complete Example)
Summary
✅ Marketing emails → One-click unsubscribe from ALL marketing✅ Operational emails → Managed individually in settings
✅ Transactional emails → Always sent (legal/security)
✅ Legally compliant → CAN-SPAM and GDPR
✅ User-friendly → Clear communication about what continues
✅ Fully implemented → Settings UI, API routes, and token system