- Migration 0019: email_unsubscribe_token column on users (unique, indexed)
- Token auto-generated on first email address save (same pattern as RSS token)
- GET /api/notifications/unsubscribe/{token} — no auth required, sets
email_enabled=False and returns a branded HTML confirmation page
- List-Unsubscribe + List-Unsubscribe-Post headers on every email
(improves deliverability; enables one-click unsubscribe in Gmail/Outlook)
- Unsubscribe link appended to email body plain text
Authored by: Jack Levy
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
23 lines
572 B
Python
23 lines
572 B
Python
"""Add email_unsubscribe_token to users
|
|
|
|
Revision ID: 0019
|
|
Revises: 0018
|
|
"""
|
|
from alembic import op
|
|
import sqlalchemy as sa
|
|
|
|
revision = "0019"
|
|
down_revision = "0018"
|
|
branch_labels = None
|
|
depends_on = None
|
|
|
|
|
|
def upgrade():
|
|
op.add_column("users", sa.Column("email_unsubscribe_token", sa.String(64), nullable=True))
|
|
op.create_index("ix_users_email_unsubscribe_token", "users", ["email_unsubscribe_token"], unique=True)
|
|
|
|
|
|
def downgrade():
|
|
op.drop_index("ix_users_email_unsubscribe_token", table_name="users")
|
|
op.drop_column("users", "email_unsubscribe_token")
|