mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-22 16:31:09 -05:00
- Introduced reusable test utilities in `backend/tests/utils` for FSM transitions, HTMX interactions, and common scenarios. - Added factory functions for creating test submissions, parks, rides, and photo submissions. - Implemented assertion helpers for verifying state changes, toast notifications, and transition logs. - Created comprehensive state machine diagrams for all FSM-enabled models in `docs/STATE_DIAGRAMS.md`, detailing states, transitions, and guard conditions.
225 lines
9.5 KiB
Python
225 lines
9.5 KiB
Python
"""
|
|
Moderation URLs
|
|
|
|
This module defines URL patterns for the moderation API endpoints.
|
|
All endpoints are nested under /api/moderation/ and provide comprehensive
|
|
moderation functionality including reports, queue management, actions, and bulk operations.
|
|
"""
|
|
|
|
from django.urls import path, include
|
|
from django.views.generic import TemplateView
|
|
from rest_framework.routers import DefaultRouter
|
|
|
|
from .views import (
|
|
ModerationReportViewSet,
|
|
ModerationQueueViewSet,
|
|
ModerationActionViewSet,
|
|
BulkOperationViewSet,
|
|
UserModerationViewSet,
|
|
)
|
|
from apps.core.views.views import FSMTransitionView
|
|
|
|
|
|
class ModerationDashboardView(TemplateView):
|
|
"""Moderation dashboard view with HTMX integration."""
|
|
template_name = "moderation/dashboard.html"
|
|
|
|
def get_context_data(self, **kwargs):
|
|
from .models import EditSubmission, PhotoSubmission
|
|
from .selectors import pending_submissions_for_review
|
|
|
|
context = super().get_context_data(**kwargs)
|
|
context["submissions"] = pending_submissions_for_review()
|
|
return context
|
|
|
|
|
|
class SubmissionListView(TemplateView):
|
|
"""Submission list view with filtering."""
|
|
template_name = "moderation/partials/dashboard_content.html"
|
|
|
|
def get_context_data(self, **kwargs):
|
|
from .models import EditSubmission, PhotoSubmission
|
|
from itertools import chain
|
|
|
|
context = super().get_context_data(**kwargs)
|
|
status = self.request.GET.get("status", "PENDING")
|
|
|
|
# Get filtered submissions
|
|
edit_submissions = EditSubmission.objects.filter(status=status).select_related("user")
|
|
photo_submissions = PhotoSubmission.objects.filter(status=status).select_related("user")
|
|
|
|
# Combine and sort
|
|
context["submissions"] = sorted(
|
|
chain(edit_submissions, photo_submissions),
|
|
key=lambda x: x.created_at,
|
|
reverse=True,
|
|
)
|
|
return context
|
|
|
|
|
|
class HistoryPageView(TemplateView):
|
|
"""Main history page view."""
|
|
template_name = "moderation/history.html"
|
|
|
|
# Create router and register viewsets
|
|
router = DefaultRouter()
|
|
router.register(r"reports", ModerationReportViewSet, basename="moderation-reports")
|
|
router.register(r"queue", ModerationQueueViewSet, basename="moderation-queue")
|
|
router.register(r"actions", ModerationActionViewSet, basename="moderation-actions")
|
|
router.register(r"bulk-operations", BulkOperationViewSet, basename="bulk-operations")
|
|
router.register(r"users", UserModerationViewSet, basename="user-moderation")
|
|
|
|
app_name = "moderation"
|
|
|
|
# FSM transition convenience URLs for moderation models
|
|
fsm_transition_patterns = [
|
|
# EditSubmission transitions
|
|
# URL: /api/moderation/submissions/<pk>/transition/<transition_name>/
|
|
path(
|
|
"submissions/<int:pk>/transition/<str:transition_name>/",
|
|
FSMTransitionView.as_view(),
|
|
{"app_label": "moderation", "model_name": "editsubmission"},
|
|
name="submission_transition",
|
|
),
|
|
# PhotoSubmission transitions
|
|
# URL: /api/moderation/photos/<pk>/transition/<transition_name>/
|
|
path(
|
|
"photos/<int:pk>/transition/<str:transition_name>/",
|
|
FSMTransitionView.as_view(),
|
|
{"app_label": "moderation", "model_name": "photosubmission"},
|
|
name="photo_transition",
|
|
),
|
|
# ModerationReport transitions
|
|
# URL: /api/moderation/reports/<pk>/transition/<transition_name>/
|
|
path(
|
|
"reports/<int:pk>/transition/<str:transition_name>/",
|
|
FSMTransitionView.as_view(),
|
|
{"app_label": "moderation", "model_name": "moderationreport"},
|
|
name="report_transition",
|
|
),
|
|
# ModerationQueue transitions
|
|
# URL: /api/moderation/queue/<pk>/transition/<transition_name>/
|
|
path(
|
|
"queue/<int:pk>/transition/<str:transition_name>/",
|
|
FSMTransitionView.as_view(),
|
|
{"app_label": "moderation", "model_name": "moderationqueue"},
|
|
name="queue_transition",
|
|
),
|
|
# BulkOperation transitions
|
|
# URL: /api/moderation/bulk/<pk>/transition/<transition_name>/
|
|
path(
|
|
"bulk/<int:pk>/transition/<str:transition_name>/",
|
|
FSMTransitionView.as_view(),
|
|
{"app_label": "moderation", "model_name": "bulkoperation"},
|
|
name="bulk_operation_transition",
|
|
),
|
|
# Backward compatibility aliases for EditSubmission actions
|
|
# These redirect the old URL patterns to the FSM transition view
|
|
path(
|
|
"submissions/<int:pk>/approve/",
|
|
FSMTransitionView.as_view(),
|
|
{"app_label": "moderation", "model_name": "editsubmission", "transition_name": "transition_to_approved"},
|
|
name="approve_submission",
|
|
),
|
|
path(
|
|
"submissions/<int:pk>/reject/",
|
|
FSMTransitionView.as_view(),
|
|
{"app_label": "moderation", "model_name": "editsubmission", "transition_name": "transition_to_rejected"},
|
|
name="reject_submission",
|
|
),
|
|
path(
|
|
"submissions/<int:pk>/escalate/",
|
|
FSMTransitionView.as_view(),
|
|
{"app_label": "moderation", "model_name": "editsubmission", "transition_name": "transition_to_escalated"},
|
|
name="escalate_submission",
|
|
),
|
|
# Backward compatibility aliases for PhotoSubmission actions
|
|
path(
|
|
"photos/<int:pk>/approve/",
|
|
FSMTransitionView.as_view(),
|
|
{"app_label": "moderation", "model_name": "photosubmission", "transition_name": "transition_to_approved"},
|
|
name="approve_photo",
|
|
),
|
|
path(
|
|
"photos/<int:pk>/reject/",
|
|
FSMTransitionView.as_view(),
|
|
{"app_label": "moderation", "model_name": "photosubmission", "transition_name": "transition_to_rejected"},
|
|
name="reject_photo",
|
|
),
|
|
path(
|
|
"photos/<int:pk>/escalate/",
|
|
FSMTransitionView.as_view(),
|
|
{"app_label": "moderation", "model_name": "photosubmission", "transition_name": "transition_to_escalated"},
|
|
name="escalate_photo",
|
|
),
|
|
]
|
|
|
|
# HTML page patterns (for moderation dashboard)
|
|
html_patterns = [
|
|
path("", ModerationDashboardView.as_view(), name="dashboard"),
|
|
path("submissions/", SubmissionListView.as_view(), name="submission_list"),
|
|
path("history/", HistoryPageView.as_view(), name="history"),
|
|
]
|
|
|
|
urlpatterns = [
|
|
# HTML page views
|
|
*html_patterns,
|
|
# Include all router URLs (API endpoints)
|
|
path("api/", include(router.urls)),
|
|
# FSM transition convenience endpoints
|
|
] + fsm_transition_patterns
|
|
|
|
# URL patterns generated by the router:
|
|
#
|
|
# Moderation Reports:
|
|
# GET /api/moderation/reports/ - List all reports
|
|
# POST /api/moderation/reports/ - Create new report
|
|
# GET /api/moderation/reports/{id}/ - Get specific report
|
|
# PUT /api/moderation/reports/{id}/ - Update report
|
|
# PATCH /api/moderation/reports/{id}/ - Partial update report
|
|
# DELETE /api/moderation/reports/{id}/ - Delete report
|
|
# POST /api/moderation/reports/{id}/assign/ - Assign report to moderator
|
|
# POST /api/moderation/reports/{id}/resolve/ - Resolve report
|
|
# GET /api/moderation/reports/stats/ - Get report statistics
|
|
#
|
|
# Moderation Queue:
|
|
# GET /api/moderation/queue/ - List queue items
|
|
# POST /api/moderation/queue/ - Create queue item
|
|
# GET /api/moderation/queue/{id}/ - Get specific queue item
|
|
# PUT /api/moderation/queue/{id}/ - Update queue item
|
|
# PATCH /api/moderation/queue/{id}/ - Partial update queue item
|
|
# DELETE /api/moderation/queue/{id}/ - Delete queue item
|
|
# POST /api/moderation/queue/{id}/assign/ - Assign queue item
|
|
# POST /api/moderation/queue/{id}/unassign/ - Unassign queue item
|
|
# POST /api/moderation/queue/{id}/complete/ - Complete queue item
|
|
# GET /api/moderation/queue/my_queue/ - Get current user's queue items
|
|
#
|
|
# Moderation Actions:
|
|
# GET /api/moderation/actions/ - List all actions
|
|
# POST /api/moderation/actions/ - Create new action
|
|
# GET /api/moderation/actions/{id}/ - Get specific action
|
|
# PUT /api/moderation/actions/{id}/ - Update action
|
|
# PATCH /api/moderation/actions/{id}/ - Partial update action
|
|
# DELETE /api/moderation/actions/{id}/ - Delete action
|
|
# POST /api/moderation/actions/{id}/deactivate/ - Deactivate action
|
|
# GET /api/moderation/actions/active/ - Get active actions
|
|
# GET /api/moderation/actions/expired/ - Get expired actions
|
|
#
|
|
# Bulk Operations:
|
|
# GET /api/moderation/bulk-operations/ - List bulk operations
|
|
# POST /api/moderation/bulk-operations/ - Create bulk operation
|
|
# GET /api/moderation/bulk-operations/{id}/ - Get specific operation
|
|
# PUT /api/moderation/bulk-operations/{id}/ - Update operation
|
|
# PATCH /api/moderation/bulk-operations/{id}/ - Partial update operation
|
|
# DELETE /api/moderation/bulk-operations/{id}/ - Delete operation
|
|
# POST /api/moderation/bulk-operations/{id}/cancel/ - Cancel operation
|
|
# POST /api/moderation/bulk-operations/{id}/retry/ - Retry failed operation
|
|
# GET /api/moderation/bulk-operations/{id}/logs/ - Get operation logs
|
|
# GET /api/moderation/bulk-operations/running/ - Get running operations
|
|
#
|
|
# User Moderation:
|
|
# GET /api/moderation/users/{id}/ - Get user moderation profile
|
|
# POST /api/moderation/users/{id}/moderate/ - Take action against user
|
|
# GET /api/moderation/users/search/ - Search users for moderation
|
|
# GET /api/moderation/users/stats/ - Get user moderation statistics
|