Email COnfigs & setup

This commit is contained in:
IGNY8 VPS (Salman)
2026-01-08 05:41:28 +00:00
parent 7da3334c03
commit 3651ee9ed4
34 changed files with 2418 additions and 77 deletions

View File

@@ -0,0 +1,93 @@
# Generated by Django 5.2.10 on 2026-01-08 01:23
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('system', '0019_model_schema_update'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='EmailTemplate',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('template_name', models.CharField(help_text='Template file name without extension (e.g., "welcome")', max_length=100, unique=True)),
('template_path', models.CharField(help_text='Full template path (e.g., "emails/welcome.html")', max_length=200)),
('display_name', models.CharField(help_text='Human-readable template name', max_length=100)),
('description', models.TextField(blank=True, help_text='Description of when this template is used')),
('template_type', models.CharField(choices=[('auth', 'Authentication'), ('billing', 'Billing'), ('notification', 'Notification'), ('marketing', 'Marketing')], default='notification', max_length=20)),
('default_subject', models.CharField(help_text='Default email subject line', max_length=200)),
('required_context', models.JSONField(blank=True, default=list, help_text='List of required context variables for this template')),
('sample_context', models.JSONField(blank=True, default=dict, help_text='Sample context for test sending (JSON)')),
('is_active', models.BooleanField(default=True, help_text='Whether this template is currently in use')),
('send_count', models.IntegerField(default=0, help_text='Number of emails sent using this template')),
('last_sent_at', models.DateTimeField(blank=True, help_text='Last time an email was sent with this template', null=True)),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
],
options={
'verbose_name': 'Email Template',
'verbose_name_plural': 'Email Templates',
'db_table': 'igny8_email_templates',
'ordering': ['template_type', 'display_name'],
},
),
migrations.CreateModel(
name='EmailLog',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('message_id', models.CharField(blank=True, help_text='Provider message ID (from Resend)', max_length=200)),
('to_email', models.EmailField(help_text='Recipient email', max_length=254)),
('from_email', models.EmailField(help_text='Sender email', max_length=254)),
('subject', models.CharField(help_text='Email subject', max_length=500)),
('template_name', models.CharField(blank=True, help_text='Template used (if any)', max_length=100)),
('status', models.CharField(choices=[('sent', 'Sent'), ('delivered', 'Delivered'), ('failed', 'Failed'), ('bounced', 'Bounced')], default='sent', max_length=20)),
('provider', models.CharField(default='resend', help_text='Email provider used', max_length=50)),
('error_message', models.TextField(blank=True, help_text='Error message if failed')),
('tags', models.JSONField(blank=True, default=list, help_text='Email tags for categorization')),
('sent_at', models.DateTimeField(auto_now_add=True)),
],
options={
'verbose_name': 'Email Log',
'verbose_name_plural': 'Email Logs',
'db_table': 'igny8_email_log',
'ordering': ['-sent_at'],
'indexes': [models.Index(fields=['to_email', 'sent_at'], name='igny8_email_to_emai_f0efbd_idx'), models.Index(fields=['status', 'sent_at'], name='igny8_email_status_7107f0_idx'), models.Index(fields=['template_name', 'sent_at'], name='igny8_email_templat_e979b9_idx')],
},
),
migrations.CreateModel(
name='EmailSettings',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('from_email', models.EmailField(default='noreply@igny8.com', help_text='Default sender email address (must be verified in Resend)', max_length=254)),
('from_name', models.CharField(default='IGNY8', help_text='Default sender display name', max_length=100)),
('reply_to_email', models.EmailField(default='support@igny8.com', help_text='Default reply-to email address', max_length=254)),
('company_name', models.CharField(default='IGNY8', help_text='Company name shown in emails', max_length=100)),
('company_address', models.TextField(blank=True, help_text='Company address for email footer (CAN-SPAM compliance)')),
('logo_url', models.URLField(blank=True, help_text='URL to company logo for emails')),
('support_email', models.EmailField(default='support@igny8.com', help_text='Support email shown in emails', max_length=254)),
('support_url', models.URLField(blank=True, help_text='Link to support/help center')),
('unsubscribe_url', models.URLField(blank=True, help_text='URL for email unsubscribe (for marketing emails)')),
('send_welcome_emails', models.BooleanField(default=True, help_text='Send welcome email on user registration')),
('send_billing_emails', models.BooleanField(default=True, help_text='Send payment confirmation, invoice emails')),
('send_subscription_emails', models.BooleanField(default=True, help_text='Send subscription renewal reminders')),
('send_low_credit_warnings', models.BooleanField(default=True, help_text='Send low credit warning emails')),
('low_credit_threshold', models.IntegerField(default=100, help_text='Send warning when credits fall below this value')),
('renewal_reminder_days', models.IntegerField(default=7, help_text='Days before subscription renewal to send reminder')),
('updated_at', models.DateTimeField(auto_now=True)),
('updated_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='email_settings_updates', to=settings.AUTH_USER_MODEL)),
],
options={
'verbose_name': 'Email Settings',
'verbose_name_plural': 'Email Settings',
'db_table': 'igny8_email_settings',
},
),
# Note: AccountIntegrationOverride delete removed - table doesn't exist in DB
]