diff --git a/core/__pycache__/models.cpython-311.pyc b/core/__pycache__/models.cpython-311.pyc index e061640..0304b67 100644 Binary files a/core/__pycache__/models.cpython-311.pyc and b/core/__pycache__/models.cpython-311.pyc differ diff --git a/core/__pycache__/urls.cpython-311.pyc b/core/__pycache__/urls.cpython-311.pyc index 5a69659..feb3db8 100644 Binary files a/core/__pycache__/urls.cpython-311.pyc and b/core/__pycache__/urls.cpython-311.pyc differ diff --git a/core/__pycache__/views.cpython-311.pyc b/core/__pycache__/views.cpython-311.pyc index 2a36fd6..3988cc3 100644 Binary files a/core/__pycache__/views.cpython-311.pyc and b/core/__pycache__/views.cpython-311.pyc differ diff --git a/core/migrations/0001_initial.py b/core/migrations/0001_initial.py new file mode 100644 index 0000000..df4dd95 --- /dev/null +++ b/core/migrations/0001_initial.py @@ -0,0 +1,62 @@ +# Generated by Django 5.2.7 on 2026-02-07 20:27 + +import django.db.models.deletion +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='Channel', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(choices=[('whatsapp', 'WhatsApp Business'), ('messenger', 'Facebook Messenger'), ('instagram', 'Instagram Messages'), ('sms', 'SMS (Twilio)'), ('tiktok', 'TikTok Messages')], max_length=50, unique=True)), + ('is_active', models.BooleanField(default=False)), + ('api_key', models.CharField(blank=True, max_length=255, null=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ], + ), + migrations.CreateModel( + name='Conversation', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('external_id', models.CharField(max_length=255)), + ('participant_name', models.CharField(max_length=255)), + ('last_message_at', models.DateTimeField(auto_now=True)), + ('channel', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='conversations', to='core.channel')), + ], + ), + migrations.CreateModel( + name='Message', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('body', models.TextField()), + ('is_from_me', models.BooleanField(default=False)), + ('timestamp', models.DateTimeField(auto_now_add=True)), + ('external_id', models.CharField(blank=True, max_length=255, null=True)), + ('conversation', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='messages', to='core.conversation')), + ], + options={ + 'ordering': ['timestamp'], + }, + ), + migrations.CreateModel( + name='Profile', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('security_pin', models.CharField(blank=True, max_length=4, null=True)), + ('deadman_pin', models.CharField(blank=True, max_length=4, null=True)), + ('is_biometric_enabled', models.BooleanField(default=False)), + ('last_wipe_at', models.DateTimeField(blank=True, null=True)), + ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + ), + ] diff --git a/core/migrations/__pycache__/0001_initial.cpython-311.pyc b/core/migrations/__pycache__/0001_initial.cpython-311.pyc new file mode 100644 index 0000000..b6c8c5c Binary files /dev/null and b/core/migrations/__pycache__/0001_initial.cpython-311.pyc differ diff --git a/core/models.py b/core/models.py index 71a8362..5fe9b7c 100644 --- a/core/models.py +++ b/core/models.py @@ -1,3 +1,62 @@ from django.db import models +from django.contrib.auth.models import User +from django.db.models.signals import post_save +from django.dispatch import receiver -# Create your models here. +class Profile(models.Model): + user = models.OneToOneField(User, on_delete=models.CASCADE) + security_pin = models.CharField(max_length=4, blank=True, null=True) + deadman_pin = models.CharField(max_length=4, blank=True, null=True) + is_biometric_enabled = models.BooleanField(default=False) + last_wipe_at = models.DateTimeField(null=True, blank=True) + + def __str__(self): + return f"Profile for {self.user.username}" + +@receiver(post_save, sender=User) +def create_user_profile(sender, instance, created, **kwargs): + if created: + Profile.objects.create(user=instance) + +@receiver(post_save, sender=User) +def save_user_profile(sender, instance, **kwargs): + instance.profile.save() + +class Channel(models.Model): + PLATFORM_CHOICES = [ + ('whatsapp', 'WhatsApp Business'), + ('messenger', 'Facebook Messenger'), + ('instagram', 'Instagram Messages'), + ('sms', 'SMS (Twilio)'), + ('tiktok', 'TikTok Messages'), + ] + + name = models.CharField(max_length=50, choices=PLATFORM_CHOICES, unique=True) + is_active = models.BooleanField(default=False) + api_key = models.CharField(max_length=255, blank=True, null=True) + updated_at = models.DateTimeField(auto_now=True) + + def __str__(self): + return self.get_name_display() + +class Conversation(models.Model): + channel = models.ForeignKey(Channel, on_delete=models.CASCADE, related_name='conversations') + external_id = models.CharField(max_length=255) # ID from the platform + participant_name = models.CharField(max_length=255) + last_message_at = models.DateTimeField(auto_now=True) + + def __str__(self): + return f"{self.participant_name} ({self.channel.get_name_display()})" + +class Message(models.Model): + conversation = models.ForeignKey(Conversation, on_delete=models.CASCADE, related_name='messages') + body = models.TextField() + is_from_me = models.BooleanField(default=False) + timestamp = models.DateTimeField(auto_now_add=True) + external_id = models.CharField(max_length=255, blank=True, null=True) + + class Meta: + ordering = ['timestamp'] + + def __str__(self): + return f"{'Me' if self.is_from_me else self.conversation.participant_name}: {self.body[:50]}" \ No newline at end of file diff --git a/core/templates/base.html b/core/templates/base.html index 1e7e5fb..65592da 100644 --- a/core/templates/base.html +++ b/core/templates/base.html @@ -1,25 +1,78 @@ +{% load static %} -
- -