146 lines
4.2 KiB
Python
146 lines
4.2 KiB
Python
"""
|
|
Moderation system models.
|
|
"""
|
|
from django.db import models
|
|
from django.contrib.auth import get_user_model
|
|
from reports.models import ScamReport
|
|
|
|
User = get_user_model()
|
|
|
|
|
|
class ModerationQueue(models.Model):
|
|
"""
|
|
Queue for reports awaiting moderation.
|
|
"""
|
|
PRIORITY_CHOICES = [
|
|
('low', 'Low'),
|
|
('normal', 'Normal'),
|
|
('high', 'High'),
|
|
('urgent', 'Urgent'),
|
|
]
|
|
|
|
report = models.OneToOneField(
|
|
ScamReport,
|
|
on_delete=models.CASCADE,
|
|
related_name='moderation_queue'
|
|
)
|
|
priority = models.CharField(
|
|
max_length=20,
|
|
choices=PRIORITY_CHOICES,
|
|
default='normal'
|
|
)
|
|
assigned_to = models.ForeignKey(
|
|
User,
|
|
on_delete=models.SET_NULL,
|
|
null=True,
|
|
blank=True,
|
|
related_name='assigned_moderations',
|
|
limit_choices_to={'role__in': ['moderator', 'admin']}
|
|
)
|
|
created_at = models.DateTimeField(auto_now_add=True)
|
|
updated_at = models.DateTimeField(auto_now=True)
|
|
|
|
class Meta:
|
|
db_table = 'moderation_moderationqueue'
|
|
verbose_name = 'Moderation Queue'
|
|
verbose_name_plural = 'Moderation Queues'
|
|
ordering = ['-priority', 'created_at']
|
|
indexes = [
|
|
models.Index(fields=['priority', 'created_at']),
|
|
models.Index(fields=['assigned_to', 'created_at']),
|
|
]
|
|
|
|
def __str__(self):
|
|
return f"Queue entry for Report #{self.report.id} - {self.get_priority_display()}"
|
|
|
|
|
|
class ModerationAction(models.Model):
|
|
"""
|
|
Log of moderation actions taken.
|
|
"""
|
|
ACTION_TYPE_CHOICES = [
|
|
('approve', 'Approve'),
|
|
('reject', 'Reject'),
|
|
('edit', 'Edit'),
|
|
('delete', 'Delete'),
|
|
('verify', 'Verify'),
|
|
('archive', 'Archive'),
|
|
('unarchive', 'Unarchive'),
|
|
('assign', 'Assign'),
|
|
('unassign', 'Unassign'),
|
|
]
|
|
|
|
report = models.ForeignKey(
|
|
ScamReport,
|
|
on_delete=models.CASCADE,
|
|
related_name='moderation_actions'
|
|
)
|
|
moderator = models.ForeignKey(
|
|
User,
|
|
on_delete=models.SET_NULL,
|
|
null=True,
|
|
related_name='moderation_actions',
|
|
limit_choices_to={'role__in': ['moderator', 'admin']}
|
|
)
|
|
action_type = models.CharField(
|
|
max_length=20,
|
|
choices=ACTION_TYPE_CHOICES
|
|
)
|
|
reason = models.TextField(
|
|
blank=True,
|
|
help_text='Reason for the action (visible to user for rejections)'
|
|
)
|
|
notes = models.TextField(
|
|
blank=True,
|
|
help_text='Additional notes'
|
|
)
|
|
previous_status = models.CharField(max_length=20, blank=True)
|
|
new_status = models.CharField(max_length=20, blank=True)
|
|
created_at = models.DateTimeField(auto_now_add=True)
|
|
|
|
class Meta:
|
|
db_table = 'moderation_moderationaction'
|
|
verbose_name = 'Moderation Action'
|
|
verbose_name_plural = 'Moderation Actions'
|
|
ordering = ['-created_at']
|
|
indexes = [
|
|
models.Index(fields=['report', 'created_at']),
|
|
models.Index(fields=['moderator', 'created_at']),
|
|
models.Index(fields=['action_type', 'created_at']),
|
|
]
|
|
|
|
def __str__(self):
|
|
return f"{self.get_action_type_display()} on Report #{self.report.id} by {self.moderator}"
|
|
|
|
|
|
class ModerationRule(models.Model):
|
|
"""
|
|
Automated moderation rules.
|
|
"""
|
|
name = models.CharField(max_length=100)
|
|
description = models.TextField(blank=True)
|
|
is_active = models.BooleanField(default=True)
|
|
priority = models.IntegerField(
|
|
default=0,
|
|
help_text='Rule priority (higher = evaluated first)'
|
|
)
|
|
conditions = models.JSONField(
|
|
default=dict,
|
|
help_text='Conditions that trigger this rule'
|
|
)
|
|
actions = models.JSONField(
|
|
default=dict,
|
|
help_text='Actions to take when rule matches'
|
|
)
|
|
created_at = models.DateTimeField(auto_now_add=True)
|
|
updated_at = models.DateTimeField(auto_now=True)
|
|
|
|
class Meta:
|
|
db_table = 'moderation_moderationrule'
|
|
verbose_name = 'Moderation Rule'
|
|
verbose_name_plural = 'Moderation Rules'
|
|
ordering = ['-priority', 'name']
|
|
|
|
def __str__(self):
|
|
return f"{self.name} ({'Active' if self.is_active else 'Inactive'})"
|