2025-05-29 17:26:37 +08:00
|
|
|
|
# Generated by Django 5.2.1 on 2025-05-29 09:24
|
2025-05-29 10:08:06 +08:00
|
|
|
|
|
|
|
|
|
import django.db.models.deletion
|
2025-05-29 17:26:37 +08:00
|
|
|
|
import uuid
|
2025-05-29 10:08:06 +08:00
|
|
|
|
from django.conf import settings
|
|
|
|
|
from django.db import migrations, models
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Migration(migrations.Migration):
|
|
|
|
|
|
|
|
|
|
initial = True
|
|
|
|
|
|
|
|
|
|
dependencies = [
|
|
|
|
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
operations = [
|
|
|
|
|
migrations.CreateModel(
|
|
|
|
|
name='GmailConversation',
|
|
|
|
|
fields=[
|
|
|
|
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
2025-05-29 17:26:37 +08:00
|
|
|
|
('conversation_id', models.CharField(help_text='Unique conversation identifier', max_length=100, unique=True)),
|
|
|
|
|
('user_email', models.EmailField(help_text="User's Gmail address", max_length=254)),
|
|
|
|
|
('influencer_email', models.EmailField(help_text="Influencer's email address", max_length=254)),
|
|
|
|
|
('title', models.CharField(help_text='Conversation title', max_length=255)),
|
2025-05-29 10:08:06 +08:00
|
|
|
|
('created_at', models.DateTimeField(auto_now_add=True)),
|
|
|
|
|
('updated_at', models.DateTimeField(auto_now=True)),
|
2025-05-29 17:26:37 +08:00
|
|
|
|
('last_sync_time', models.DateTimeField(blank=True, help_text='Last time conversation was synced with Gmail', null=True)),
|
|
|
|
|
('is_active', models.BooleanField(default=True, help_text='Whether this conversation is active')),
|
|
|
|
|
('has_sent_greeting', models.BooleanField(default=False, help_text='Whether a greeting message has been sent to this conversation')),
|
|
|
|
|
('metadata', models.JSONField(blank=True, help_text='Additional metadata for the conversation', null=True)),
|
2025-05-29 10:08:06 +08:00
|
|
|
|
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='gmail_conversations', to=settings.AUTH_USER_MODEL)),
|
|
|
|
|
],
|
|
|
|
|
options={
|
|
|
|
|
'ordering': ['-updated_at'],
|
|
|
|
|
'unique_together': {('user', 'user_email', 'influencer_email')},
|
|
|
|
|
},
|
|
|
|
|
),
|
|
|
|
|
migrations.CreateModel(
|
|
|
|
|
name='GmailAttachment',
|
|
|
|
|
fields=[
|
|
|
|
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
|
|
|
('email_message_id', models.CharField(help_text='Gmail邮件ID', max_length=100)),
|
2025-05-29 17:26:37 +08:00
|
|
|
|
('attachment_id', models.TextField(help_text='Gmail附件的唯一标识符,可能很长')),
|
2025-05-29 10:08:06 +08:00
|
|
|
|
('filename', models.CharField(help_text='原始文件名', max_length=255)),
|
|
|
|
|
('file_path', models.CharField(help_text='保存在服务器上的路径', max_length=255)),
|
|
|
|
|
('content_type', models.CharField(help_text='MIME类型', max_length=100)),
|
|
|
|
|
('size', models.IntegerField(default=0, help_text='文件大小(字节)')),
|
|
|
|
|
('sender_email', models.EmailField(help_text='发送者邮箱', max_length=254)),
|
|
|
|
|
('chat_message_id', models.CharField(blank=True, help_text='关联到ChatHistory的消息ID', max_length=100, null=True)),
|
|
|
|
|
('created_at', models.DateTimeField(auto_now_add=True)),
|
|
|
|
|
('conversation', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='attachments', to='gmail.gmailconversation')),
|
|
|
|
|
],
|
|
|
|
|
options={
|
|
|
|
|
'ordering': ['-created_at'],
|
|
|
|
|
},
|
|
|
|
|
),
|
2025-05-29 17:26:37 +08:00
|
|
|
|
migrations.CreateModel(
|
|
|
|
|
name='ConversationSummary',
|
|
|
|
|
fields=[
|
|
|
|
|
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
|
|
|
|
('content', models.TextField(verbose_name='摘要内容')),
|
|
|
|
|
('last_message_id', models.CharField(blank=True, max_length=255, null=True, verbose_name='最后处理的消息ID或ChatHistory的ID')),
|
|
|
|
|
('created_at', models.DateTimeField(auto_now_add=True)),
|
|
|
|
|
('updated_at', models.DateTimeField(auto_now=True)),
|
|
|
|
|
('conversation', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='summary', to='gmail.gmailconversation')),
|
|
|
|
|
],
|
|
|
|
|
options={
|
|
|
|
|
'verbose_name': 'Gmail对话摘要',
|
|
|
|
|
'verbose_name_plural': 'Gmail对话摘要',
|
|
|
|
|
'db_table': 'gmail_conversation_summaries',
|
|
|
|
|
},
|
|
|
|
|
),
|
|
|
|
|
migrations.CreateModel(
|
|
|
|
|
name='ProcessedPushNotification',
|
|
|
|
|
fields=[
|
|
|
|
|
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
|
|
|
|
('message_id', models.CharField(help_text='Pub/Sub消息ID', max_length=255, unique=True)),
|
|
|
|
|
('email_address', models.EmailField(help_text='通知关联的Gmail邮箱', max_length=254)),
|
|
|
|
|
('history_id', models.CharField(help_text='Gmail历史ID', max_length=100)),
|
|
|
|
|
('processed_at', models.DateTimeField(auto_now_add=True, help_text='处理时间')),
|
|
|
|
|
('is_successful', models.BooleanField(default=True, help_text='处理是否成功')),
|
|
|
|
|
('metadata', models.JSONField(blank=True, default=dict, help_text='额外信息')),
|
|
|
|
|
],
|
|
|
|
|
options={
|
|
|
|
|
'verbose_name': '已处理推送通知',
|
|
|
|
|
'verbose_name_plural': '已处理推送通知',
|
|
|
|
|
'db_table': 'gmail_processed_push_notifications',
|
|
|
|
|
'ordering': ['-processed_at'],
|
|
|
|
|
'indexes': [models.Index(fields=['message_id'], name='gmail_proce_message_912a0c_idx'), models.Index(fields=['email_address', 'history_id'], name='gmail_proce_email_a_2e3770_idx')],
|
|
|
|
|
},
|
|
|
|
|
),
|
|
|
|
|
migrations.CreateModel(
|
|
|
|
|
name='UnmatchedEmail',
|
|
|
|
|
fields=[
|
|
|
|
|
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
|
|
|
|
('message_id', models.CharField(help_text='Gmail邮件ID', max_length=255, unique=True)),
|
|
|
|
|
('user_id', models.CharField(help_text='用户ID (UUID字符串形式)', max_length=36)),
|
|
|
|
|
('user_email', models.EmailField(help_text='用户Gmail邮箱', max_length=254)),
|
|
|
|
|
('from_email', models.EmailField(help_text='发件人邮箱', max_length=254)),
|
|
|
|
|
('to_email', models.EmailField(help_text='收件人邮箱', max_length=254)),
|
|
|
|
|
('subject', models.CharField(blank=True, help_text='邮件主题', max_length=500)),
|
|
|
|
|
('processed_at', models.DateTimeField(auto_now_add=True, help_text='处理时间')),
|
|
|
|
|
],
|
|
|
|
|
options={
|
|
|
|
|
'verbose_name': '未匹配邮件',
|
|
|
|
|
'verbose_name_plural': '未匹配邮件',
|
|
|
|
|
'db_table': 'gmail_unmatched_emails',
|
|
|
|
|
'ordering': ['-processed_at'],
|
|
|
|
|
'indexes': [models.Index(fields=['message_id'], name='gmail_unmat_message_c1924d_idx'), models.Index(fields=['user_id'], name='gmail_unmat_user_id_ee06fe_idx'), models.Index(fields=['user_email', 'from_email'], name='gmail_unmat_user_em_a096af_idx')],
|
|
|
|
|
},
|
|
|
|
|
),
|
|
|
|
|
migrations.CreateModel(
|
|
|
|
|
name='UserGoal',
|
|
|
|
|
fields=[
|
|
|
|
|
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
|
|
|
|
('description', models.TextField(verbose_name='目标描述')),
|
|
|
|
|
('status', models.CharField(choices=[('pending', '待处理'), ('in_progress', '进行中'), ('completed', '已完成'), ('failed', '失败')], default='pending', max_length=20, verbose_name='目标状态')),
|
|
|
|
|
('is_active', models.BooleanField(default=True, verbose_name='是否激活')),
|
|
|
|
|
('created_at', models.DateTimeField(auto_now_add=True)),
|
|
|
|
|
('updated_at', models.DateTimeField(auto_now=True)),
|
|
|
|
|
('completion_time', models.DateTimeField(blank=True, null=True, verbose_name='完成时间')),
|
|
|
|
|
('last_activity_time', models.DateTimeField(blank=True, null=True, verbose_name='最后活动时间')),
|
|
|
|
|
('metadata', models.JSONField(blank=True, default=dict, help_text='存储额外信息', null=True)),
|
|
|
|
|
('conversation', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='goals', to='gmail.gmailconversation')),
|
|
|
|
|
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='goals', to=settings.AUTH_USER_MODEL)),
|
|
|
|
|
],
|
|
|
|
|
options={
|
|
|
|
|
'verbose_name': '用户目标',
|
|
|
|
|
'verbose_name_plural': '用户目标',
|
|
|
|
|
'ordering': ['-updated_at'],
|
|
|
|
|
},
|
|
|
|
|
),
|
|
|
|
|
migrations.CreateModel(
|
|
|
|
|
name='AutoReplyConfig',
|
|
|
|
|
fields=[
|
|
|
|
|
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
|
|
|
|
('user_email', models.EmailField(help_text='用户Gmail邮箱', max_length=254)),
|
|
|
|
|
('influencer_email', models.EmailField(help_text='达人Gmail邮箱', max_length=254)),
|
|
|
|
|
('is_enabled', models.BooleanField(default=True, help_text='是否启用自动回复')),
|
|
|
|
|
('goal_description', models.TextField(help_text='AI回复时参考的目标', verbose_name='自动回复的目标描述')),
|
|
|
|
|
('reply_template', models.TextField(blank=True, help_text='回复模板(可选,为空则由AI生成)', null=True)),
|
|
|
|
|
('max_replies', models.IntegerField(default=5, help_text='最大自动回复次数')),
|
|
|
|
|
('current_replies', models.IntegerField(default=0, help_text='当前已自动回复次数')),
|
|
|
|
|
('last_reply_time', models.DateTimeField(blank=True, null=True)),
|
|
|
|
|
('created_at', models.DateTimeField(auto_now_add=True)),
|
|
|
|
|
('updated_at', models.DateTimeField(auto_now=True)),
|
|
|
|
|
('metadata', models.JSONField(blank=True, default=dict, help_text='存储额外信息,如已处理的消息ID等', null=True)),
|
|
|
|
|
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='auto_reply_configs', to=settings.AUTH_USER_MODEL)),
|
|
|
|
|
],
|
|
|
|
|
options={
|
|
|
|
|
'verbose_name': 'Gmail自动回复配置',
|
|
|
|
|
'verbose_name_plural': 'Gmail自动回复配置',
|
|
|
|
|
'db_table': 'gmail_auto_reply_configs',
|
|
|
|
|
'ordering': ['-updated_at'],
|
|
|
|
|
'unique_together': {('user', 'user_email', 'influencer_email')},
|
|
|
|
|
},
|
|
|
|
|
),
|
2025-05-29 10:08:06 +08:00
|
|
|
|
migrations.CreateModel(
|
|
|
|
|
name='GmailCredential',
|
|
|
|
|
fields=[
|
|
|
|
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
|
|
|
('email', models.EmailField(help_text='Gmail email address', max_length=254, unique=True)),
|
|
|
|
|
('credentials', models.TextField(help_text='Serialized OAuth2 credentials (JSON)')),
|
|
|
|
|
('is_default', models.BooleanField(default=False, help_text='Default Gmail account for user')),
|
|
|
|
|
('created_at', models.DateTimeField(auto_now_add=True)),
|
|
|
|
|
('updated_at', models.DateTimeField(auto_now=True)),
|
|
|
|
|
('is_valid', models.BooleanField(default=True, help_text='Whether the credential is valid')),
|
2025-05-29 17:26:37 +08:00
|
|
|
|
('last_history_id', models.CharField(blank=True, help_text='Last processed Gmail history ID', max_length=50, null=True)),
|
2025-05-29 10:08:06 +08:00
|
|
|
|
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='gmail_credentials', to=settings.AUTH_USER_MODEL)),
|
|
|
|
|
],
|
|
|
|
|
options={
|
|
|
|
|
'unique_together': {('user', 'email')},
|
|
|
|
|
},
|
|
|
|
|
),
|
|
|
|
|
]
|