Files
thrillwiki_django_no_react/backend/apps/moderation/urls.py
pacnpal 45d97b6e68 Add test utilities and state machine diagrams for FSM models
- 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.
2025-12-22 08:55:39 -05:00

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