schon/engine/authv/messaging/models.py

75 lines
2.6 KiB
Python

from __future__ import annotations
from django.core.exceptions import ValidationError
from django.db.models import (
CharField,
DateTimeField,
EmailField,
ForeignKey,
Index,
JSONField,
TextChoices,
TextField,
SET_NULL,
CASCADE,
)
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from engine.core.abstract import NiceModel
from engine.authv.models import User
class ThreadStatus(TextChoices):
OPEN = "open", _("Open")
CLOSED = "closed", _("Closed")
class SenderType(TextChoices):
USER = "user", _("User")
STAFF = "staff", _("Staff")
SYSTEM = "system", _("System")
class ChatThread(NiceModel):
user = ForeignKey(User, null=True, blank=True, on_delete=SET_NULL, related_name="chat_threads")
email = EmailField(blank=True, default="", help_text=_("For anonymous threads"))
assigned_to = ForeignKey(User, null=True, blank=True, on_delete=SET_NULL, related_name="assigned_chat_threads")
status = CharField(max_length=16, choices=ThreadStatus.choices, default=ThreadStatus.OPEN)
last_message_at = DateTimeField(default=timezone.now)
attributes = JSONField(default=dict, blank=True)
class Meta:
indexes = [
Index(fields=["status", "modified"], name="chatthread_status_mod_idx"),
Index(fields=["assigned_to", "status"], name="chatthread_assigned_status_idx"),
Index(fields=["user"], name="chatthread_user_idx"),
Index(fields=["email"], name="chatthread_email_idx"),
]
ordering = ("-modified",)
verbose_name = _("Chat thread")
verbose_name_plural = _("Chat threads")
def clean(self) -> None:
super().clean()
if not self.user and not self.email:
raise ValidationError({"email": _("Provide user or email for anonymous thread.")})
if self.assigned_to and not self.assigned_to.is_staff:
raise ValidationError({"assigned_to": _("Assignee must be a staff user.")})
class ChatMessage(NiceModel):
thread = ForeignKey(ChatThread, on_delete=CASCADE, related_name="messages")
sender_type = CharField(max_length=16, choices=SenderType.choices)
sender_user = ForeignKey(User, null=True, blank=True, on_delete=SET_NULL, related_name="chat_messages")
text = TextField()
sent_at = DateTimeField(default=timezone.now)
attributes = JSONField(default=dict, blank=True)
class Meta:
indexes = [
Index(fields=["thread", "sent_at"], name="chatmessage_thread_sent_idx"),
]
ordering = ("sent_at", "uuid")
verbose_name = _("Chat message")
verbose_name_plural = _("Chat messages")