mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-24 15:31:09 -05:00
Add secret management guide, client-side performance monitoring, and search accessibility enhancements
- Introduced a comprehensive Secret Management Guide detailing best practices, secret classification, development setup, production management, rotation procedures, and emergency protocols. - Implemented a client-side performance monitoring script to track various metrics including page load performance, paint metrics, layout shifts, and memory usage. - Enhanced search accessibility with keyboard navigation support for search results, ensuring compliance with WCAG standards and improving user experience.
This commit is contained in:
@@ -78,13 +78,20 @@ class EditSubmission(StateMachineMixin, TrackedModel):
|
||||
settings.AUTH_USER_MODEL,
|
||||
on_delete=models.CASCADE,
|
||||
related_name="edit_submissions",
|
||||
help_text="User who submitted this edit",
|
||||
)
|
||||
|
||||
# What is being edited (Park or Ride)
|
||||
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
|
||||
content_type = models.ForeignKey(
|
||||
ContentType,
|
||||
on_delete=models.CASCADE,
|
||||
help_text="Type of object being edited",
|
||||
)
|
||||
object_id = models.PositiveIntegerField(
|
||||
null=True, blank=True
|
||||
) # Null for new objects
|
||||
null=True,
|
||||
blank=True,
|
||||
help_text="ID of object being edited (null for new objects)",
|
||||
)
|
||||
content_object = GenericForeignKey("content_type", "object_id")
|
||||
|
||||
# Type of submission
|
||||
@@ -127,13 +134,18 @@ class EditSubmission(StateMachineMixin, TrackedModel):
|
||||
null=True,
|
||||
blank=True,
|
||||
related_name="handled_submissions",
|
||||
help_text="Moderator who handled this submission",
|
||||
)
|
||||
handled_at = models.DateTimeField(
|
||||
null=True, blank=True, help_text="When this submission was handled"
|
||||
)
|
||||
handled_at = models.DateTimeField(null=True, blank=True)
|
||||
notes = models.TextField(
|
||||
blank=True, help_text="Notes from the moderator about this submission"
|
||||
)
|
||||
|
||||
class Meta(TrackedModel.Meta):
|
||||
verbose_name = "Edit Submission"
|
||||
verbose_name_plural = "Edit Submissions"
|
||||
ordering = ["-created_at"]
|
||||
indexes = [
|
||||
models.Index(fields=["content_type", "object_id"]),
|
||||
@@ -344,14 +356,16 @@ class ModerationReport(StateMachineMixin, TrackedModel):
|
||||
reported_by = models.ForeignKey(
|
||||
settings.AUTH_USER_MODEL,
|
||||
on_delete=models.CASCADE,
|
||||
related_name='moderation_reports_made'
|
||||
related_name='moderation_reports_made',
|
||||
help_text="User who made this report",
|
||||
)
|
||||
assigned_moderator = models.ForeignKey(
|
||||
settings.AUTH_USER_MODEL,
|
||||
on_delete=models.SET_NULL,
|
||||
null=True,
|
||||
blank=True,
|
||||
related_name='assigned_moderation_reports'
|
||||
related_name='assigned_moderation_reports',
|
||||
help_text="Moderator assigned to handle this report",
|
||||
)
|
||||
|
||||
# Resolution
|
||||
@@ -359,13 +373,21 @@ class ModerationReport(StateMachineMixin, TrackedModel):
|
||||
max_length=100, blank=True, help_text="Action taken to resolve")
|
||||
resolution_notes = models.TextField(
|
||||
blank=True, help_text="Notes about the resolution")
|
||||
resolved_at = models.DateTimeField(null=True, blank=True)
|
||||
resolved_at = models.DateTimeField(
|
||||
null=True, blank=True, help_text="When this report was resolved"
|
||||
)
|
||||
|
||||
# Timestamps
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
updated_at = models.DateTimeField(auto_now=True)
|
||||
created_at = models.DateTimeField(
|
||||
auto_now_add=True, help_text="When this report was created"
|
||||
)
|
||||
updated_at = models.DateTimeField(
|
||||
auto_now=True, help_text="When this report was last updated"
|
||||
)
|
||||
|
||||
class Meta(TrackedModel.Meta):
|
||||
verbose_name = "Moderation Report"
|
||||
verbose_name_plural = "Moderation Reports"
|
||||
ordering = ['-created_at']
|
||||
indexes = [
|
||||
models.Index(fields=['status', 'priority']),
|
||||
@@ -428,9 +450,12 @@ class ModerationQueue(StateMachineMixin, TrackedModel):
|
||||
on_delete=models.SET_NULL,
|
||||
null=True,
|
||||
blank=True,
|
||||
related_name='assigned_queue_items'
|
||||
related_name='assigned_queue_items',
|
||||
help_text="Moderator assigned to this item",
|
||||
)
|
||||
assigned_at = models.DateTimeField(
|
||||
null=True, blank=True, help_text="When this item was assigned"
|
||||
)
|
||||
assigned_at = models.DateTimeField(null=True, blank=True)
|
||||
estimated_review_time = models.PositiveIntegerField(
|
||||
default=30, help_text="Estimated time in minutes")
|
||||
|
||||
@@ -440,7 +465,8 @@ class ModerationQueue(StateMachineMixin, TrackedModel):
|
||||
on_delete=models.SET_NULL,
|
||||
null=True,
|
||||
blank=True,
|
||||
related_name='flagged_queue_items'
|
||||
related_name='flagged_queue_items',
|
||||
help_text="User who flagged this item",
|
||||
)
|
||||
tags = models.JSONField(default=list, blank=True,
|
||||
help_text="Tags for categorization")
|
||||
@@ -451,14 +477,21 @@ class ModerationQueue(StateMachineMixin, TrackedModel):
|
||||
on_delete=models.CASCADE,
|
||||
null=True,
|
||||
blank=True,
|
||||
related_name='queue_items'
|
||||
related_name='queue_items',
|
||||
help_text="Related moderation report",
|
||||
)
|
||||
|
||||
# Timestamps
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
updated_at = models.DateTimeField(auto_now=True)
|
||||
created_at = models.DateTimeField(
|
||||
auto_now_add=True, help_text="When this item was created"
|
||||
)
|
||||
updated_at = models.DateTimeField(
|
||||
auto_now=True, help_text="When this item was last updated"
|
||||
)
|
||||
|
||||
class Meta(TrackedModel.Meta):
|
||||
verbose_name = "Moderation Queue Item"
|
||||
verbose_name_plural = "Moderation Queue Items"
|
||||
ordering = ['priority', 'created_at']
|
||||
indexes = [
|
||||
models.Index(fields=['status', 'priority']),
|
||||
@@ -503,12 +536,14 @@ class ModerationAction(TrackedModel):
|
||||
moderator = models.ForeignKey(
|
||||
settings.AUTH_USER_MODEL,
|
||||
on_delete=models.CASCADE,
|
||||
related_name='moderation_actions_taken'
|
||||
related_name='moderation_actions_taken',
|
||||
help_text="Moderator who took this action",
|
||||
)
|
||||
target_user = models.ForeignKey(
|
||||
settings.AUTH_USER_MODEL,
|
||||
on_delete=models.CASCADE,
|
||||
related_name='moderation_actions_received'
|
||||
related_name='moderation_actions_received',
|
||||
help_text="User this action was taken against",
|
||||
)
|
||||
|
||||
# Related objects
|
||||
@@ -517,14 +552,21 @@ class ModerationAction(TrackedModel):
|
||||
on_delete=models.SET_NULL,
|
||||
null=True,
|
||||
blank=True,
|
||||
related_name='actions_taken'
|
||||
related_name='actions_taken',
|
||||
help_text="Related moderation report",
|
||||
)
|
||||
|
||||
# Timestamps
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
updated_at = models.DateTimeField(auto_now=True)
|
||||
created_at = models.DateTimeField(
|
||||
auto_now_add=True, help_text="When this action was created"
|
||||
)
|
||||
updated_at = models.DateTimeField(
|
||||
auto_now=True, help_text="When this action was last updated"
|
||||
)
|
||||
|
||||
class Meta(TrackedModel.Meta):
|
||||
verbose_name = "Moderation Action"
|
||||
verbose_name_plural = "Moderation Actions"
|
||||
ordering = ['-created_at']
|
||||
indexes = [
|
||||
models.Index(fields=['target_user', 'is_active']),
|
||||
@@ -605,16 +647,25 @@ class BulkOperation(StateMachineMixin, TrackedModel):
|
||||
created_by = models.ForeignKey(
|
||||
settings.AUTH_USER_MODEL,
|
||||
on_delete=models.CASCADE,
|
||||
related_name='bulk_operations_created'
|
||||
related_name='bulk_operations_created',
|
||||
help_text="User who created this operation",
|
||||
)
|
||||
|
||||
# Timestamps
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
started_at = models.DateTimeField(null=True, blank=True)
|
||||
completed_at = models.DateTimeField(null=True, blank=True)
|
||||
updated_at = models.DateTimeField(auto_now=True)
|
||||
started_at = models.DateTimeField(
|
||||
null=True, blank=True, help_text="When this operation started"
|
||||
)
|
||||
completed_at = models.DateTimeField(
|
||||
null=True, blank=True, help_text="When this operation completed"
|
||||
)
|
||||
updated_at = models.DateTimeField(
|
||||
auto_now=True, help_text="When this operation was last updated"
|
||||
)
|
||||
|
||||
class Meta(TrackedModel.Meta):
|
||||
verbose_name = "Bulk Operation"
|
||||
verbose_name_plural = "Bulk Operations"
|
||||
ordering = ['-created_at']
|
||||
indexes = [
|
||||
models.Index(fields=['status', 'priority']),
|
||||
@@ -645,11 +696,18 @@ class PhotoSubmission(StateMachineMixin, TrackedModel):
|
||||
settings.AUTH_USER_MODEL,
|
||||
on_delete=models.CASCADE,
|
||||
related_name="photo_submissions",
|
||||
help_text="User who submitted this photo",
|
||||
)
|
||||
|
||||
# What the photo is for (Park or Ride)
|
||||
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
|
||||
object_id = models.PositiveIntegerField()
|
||||
content_type = models.ForeignKey(
|
||||
ContentType,
|
||||
on_delete=models.CASCADE,
|
||||
help_text="Type of object this photo is for",
|
||||
)
|
||||
object_id = models.PositiveIntegerField(
|
||||
help_text="ID of object this photo is for"
|
||||
)
|
||||
content_object = GenericForeignKey("content_type", "object_id")
|
||||
|
||||
# The photo itself
|
||||
@@ -658,8 +716,10 @@ class PhotoSubmission(StateMachineMixin, TrackedModel):
|
||||
on_delete=models.CASCADE,
|
||||
help_text="Photo submission stored on Cloudflare Images"
|
||||
)
|
||||
caption = models.CharField(max_length=255, blank=True)
|
||||
date_taken = models.DateField(null=True, blank=True)
|
||||
caption = models.CharField(max_length=255, blank=True, help_text="Photo caption")
|
||||
date_taken = models.DateField(
|
||||
null=True, blank=True, help_text="Date the photo was taken"
|
||||
)
|
||||
|
||||
# Metadata
|
||||
status = RichFSMField(
|
||||
@@ -677,14 +737,19 @@ class PhotoSubmission(StateMachineMixin, TrackedModel):
|
||||
null=True,
|
||||
blank=True,
|
||||
related_name="handled_photos",
|
||||
help_text="Moderator who handled this submission",
|
||||
)
|
||||
handled_at = models.DateTimeField(
|
||||
null=True, blank=True, help_text="When this submission was handled"
|
||||
)
|
||||
handled_at = models.DateTimeField(null=True, blank=True)
|
||||
notes = models.TextField(
|
||||
blank=True,
|
||||
help_text="Notes from the moderator about this photo submission",
|
||||
)
|
||||
|
||||
class Meta(TrackedModel.Meta):
|
||||
verbose_name = "Photo Submission"
|
||||
verbose_name_plural = "Photo Submissions"
|
||||
ordering = ["-created_at"]
|
||||
indexes = [
|
||||
models.Index(fields=["content_type", "object_id"]),
|
||||
|
||||
Reference in New Issue
Block a user