mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2026-02-05 06:05:18 -05:00
feat: Add analytics, incident, and alert models and APIs, along with user permissions and bulk profile lookups.
This commit is contained in:
@@ -66,3 +66,105 @@ class Ticket(TrackedModel):
|
||||
if self.user and not self.email:
|
||||
self.email = self.user.email
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
|
||||
class Report(TrackedModel):
|
||||
"""
|
||||
User-submitted reports about content issues.
|
||||
|
||||
Reports allow users to flag problems with specific entities
|
||||
(parks, rides, reviews, etc.) for moderator review.
|
||||
"""
|
||||
|
||||
class ReportType(models.TextChoices):
|
||||
INACCURATE = "inaccurate", "Inaccurate Information"
|
||||
INAPPROPRIATE = "inappropriate", "Inappropriate Content"
|
||||
SPAM = "spam", "Spam"
|
||||
COPYRIGHT = "copyright", "Copyright Violation"
|
||||
DUPLICATE = "duplicate", "Duplicate Content"
|
||||
OTHER = "other", "Other"
|
||||
|
||||
class Status(models.TextChoices):
|
||||
PENDING = "pending", "Pending"
|
||||
INVESTIGATING = "investigating", "Investigating"
|
||||
RESOLVED = "resolved", "Resolved"
|
||||
DISMISSED = "dismissed", "Dismissed"
|
||||
|
||||
# Reporter (optional for anonymous reports)
|
||||
reporter = models.ForeignKey(
|
||||
settings.AUTH_USER_MODEL,
|
||||
on_delete=models.SET_NULL,
|
||||
null=True,
|
||||
blank=True,
|
||||
related_name="submitted_reports",
|
||||
help_text="User who submitted the report",
|
||||
)
|
||||
|
||||
# Target entity using GenericForeignKey
|
||||
content_type = models.ForeignKey(
|
||||
"contenttypes.ContentType",
|
||||
on_delete=models.CASCADE,
|
||||
help_text="Type of entity being reported",
|
||||
)
|
||||
object_id = models.CharField(
|
||||
max_length=50,
|
||||
help_text="ID of the entity being reported",
|
||||
)
|
||||
# Note: GenericForeignKey doesn't create a database column
|
||||
# It's a convenience for accessing the related object
|
||||
# content_object = GenericForeignKey("content_type", "object_id")
|
||||
|
||||
# Report details
|
||||
report_type = models.CharField(
|
||||
max_length=20,
|
||||
choices=ReportType.choices,
|
||||
db_index=True,
|
||||
help_text="Type of issue being reported",
|
||||
)
|
||||
reason = models.TextField(
|
||||
help_text="Detailed description of the issue",
|
||||
)
|
||||
status = models.CharField(
|
||||
max_length=20,
|
||||
choices=Status.choices,
|
||||
default=Status.PENDING,
|
||||
db_index=True,
|
||||
help_text="Current status of the report",
|
||||
)
|
||||
|
||||
# Resolution
|
||||
resolved_at = models.DateTimeField(
|
||||
null=True,
|
||||
blank=True,
|
||||
help_text="When the report was resolved",
|
||||
)
|
||||
resolved_by = models.ForeignKey(
|
||||
settings.AUTH_USER_MODEL,
|
||||
on_delete=models.SET_NULL,
|
||||
null=True,
|
||||
blank=True,
|
||||
related_name="resolved_reports",
|
||||
help_text="Moderator who resolved the report",
|
||||
)
|
||||
resolution_notes = models.TextField(
|
||||
blank=True,
|
||||
help_text="Notes about how the report was resolved",
|
||||
)
|
||||
|
||||
class Meta(TrackedModel.Meta):
|
||||
verbose_name = "Report"
|
||||
verbose_name_plural = "Reports"
|
||||
ordering = ["-created_at"]
|
||||
indexes = [
|
||||
models.Index(fields=["status", "created_at"]),
|
||||
models.Index(fields=["content_type", "object_id"]),
|
||||
models.Index(fields=["report_type", "created_at"]),
|
||||
]
|
||||
|
||||
def __str__(self):
|
||||
return f"[{self.get_report_type_display()}] {self.content_type} #{self.object_id}"
|
||||
|
||||
@property
|
||||
def is_resolved(self) -> bool:
|
||||
return self.status in (self.Status.RESOLVED, self.Status.DISMISSED)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user