Skip to main content
ClassQuiz includes a moderation system for reviewing public quizzes and maintaining content quality. Moderators can rate quizzes to control their visibility in search results and public listings.

Moderation Overview

The moderation system is implemented in classquiz/routers/moderation.py and provides:
  • Review queue for unrated public quizzes
  • Rating system for content quality
  • Moderator authentication and permissions
  • Pagination for large review queues

Becoming a Moderator

Moderators are users with special permissions. The authentication check is handled by get_current_moderator from classquiz.auth.
Moderator permissions are typically granted by system administrators. Contact your instance admin to request moderator access.

Moderator Dashboard

Check Moderator Status

Endpoint: GET /api/v1/moderation/status Authentication: Moderator required
curl -X GET \
  'https://your-instance.com/api/v1/moderation/status' \
  -H 'Authorization: Bearer MODERATOR_TOKEN'
Response:
{
  "status": "ok"
}
The endpoint also sets a moderator=yes cookie for web interface access.

Review Queue

Get Quizzes to Review

Endpoint: GET /api/v1/moderation/quizzes Authentication: Moderator required Parameters:
  • page (int): Page number (starts at 1)
  • all (bool): If true, show all public quizzes; if false, only unrated quizzes
Example - Get unrated quizzes:
curl -X GET \
  'https://your-instance.com/api/v1/moderation/quizzes?page=1&all=false' \
  -H 'Authorization: Bearer MODERATOR_TOKEN'
Example - Get all public quizzes:
curl -X GET \
  'https://your-instance.com/api/v1/moderation/quizzes?page=1&all=true' \
  -H 'Authorization: Bearer MODERATOR_TOKEN'
Response:
[
  {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "title": "World Geography Quiz",
    "description": "Test your knowledge of world capitals",
    "public": true,
    "mod_rating": null,
    "created_at": "2023-10-15T10:30:00Z",
    "updated_at": "2023-10-15T12:00:00Z",
    "questions": [...],
    "imported_from_kahoot": false
  }
]

Pagination

The review queue uses standard pagination with a default page size. Page numbers start at 1.
Implementation from classquiz/routers/moderation.py:24-46:
if page < 1:
    raise HTTPException(status_code=400, detail="page 1 is the first")

if all:
    quizzes = await Quiz.objects.paginate(page=page) \
        .order_by(Quiz.updated_at.desc()) \
        .filter(Quiz.public == True).all()
else:
    quizzes = await Quiz.objects.paginate(page=page) \
        .order_by(Quiz.updated_at.desc()) \
        .filter(Quiz.public == True) \
        .filter(Quiz.mod_rating == None).all()
Quizzes are ordered by updated_at in descending order, showing recently updated quizzes first.

Rating Quizzes

Set Moderation Rating

Endpoint: POST /api/v1/moderation/rating/set/{quiz_id} Authentication: Moderator required Path Parameters:
  • quiz_id (UUID): The quiz to rate
Request Body:
{
  "rating": 5
}
Remove Rating:
{
  "rating": null
}
Example:
curl -X POST \
  'https://your-instance.com/api/v1/moderation/rating/set/550e8400-e29b-41d4-a716-446655440000' \
  -H 'Authorization: Bearer MODERATOR_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{"rating": 4}'
Response: Returns the updated Quiz object
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "title": "World Geography Quiz",
  "mod_rating": 4,
  ...
}

Rating System

The mod_rating field is a SmallInteger (see classquiz/db/models.py:201):
class Quiz(ormar.Model):
    mod_rating: int | None = ormar.SmallInteger(nullable=True)

Rating Scale

While the system supports any integer value, consider this recommended scale:
  • High-quality content
  • Educational value
  • No issues with accuracy or appropriateness
  • Well-formatted questions
  • Good images and design
Your ClassQuiz instance may use a different rating scale. Consult your moderation guidelines.

Moderation Workflow

1

Access the review queue

Call GET /api/v1/moderation/quizzes?page=1&all=false to get unrated public quizzes.
2

Review quiz content

For each quiz, review:
  • Question quality and accuracy
  • Appropriateness of content
  • Image quality and relevance
  • Overall educational value
  • Signs of spam or abuse
3

Assign rating

Use POST /api/v1/moderation/rating/set/{quiz_id} to assign a rating (1-5) or null to skip.
4

Move to next quiz

Rated quizzes are removed from the default queue (all=false). Continue to the next quiz.

Content Guidelines

When moderating quizzes, watch for:

✅ Good Content

  • Accurate information
  • Clear, well-written questions
  • Appropriate for educational use
  • Proper attribution for images
  • Reasonable time limits
  • Varied question types

❌ Problematic Content

  • Spam or promotional content
  • Offensive or inappropriate material
  • Plagiarized questions
  • Copyright-infringing images
  • Misleading or incorrect information
  • Personal information or doxxing
If you encounter quizzes with severe policy violations, contact your system administrator for immediate action beyond just rating.

Imported Kahoot Quizzes

Quizzes imported from Kahoot are marked in the database:
quiz.imported_from_kahoot: bool
These quizzes:
  • Have imported_from_kahoot: true in the response
  • Store original Kahoot ID in kahoot_id field
  • Start with mod_rating: null after import
  • Require manual moderation review
Imported Kahoot quizzes may need extra scrutiny for copyright issues. Verify that the content is appropriate for your ClassQuiz instance.

Error Handling

Quiz Not Found

{
  "detail": "Quiz not found"
}
HTTP 404 - The quiz ID doesn’t exist or isn’t public.

Invalid Page Number

{
  "detail": "page 1 is the first"
}
HTTP 400 - Page numbers must be >= 1.

Unauthorized

HTTP 401/403 - User doesn’t have moderator permissions.

Database Schema

Moderation-related fields in the Quiz model:
class Quiz(ormar.Model):
    id: uuid.UUID
    public: bool  # Must be true to appear in moderation queue
    mod_rating: int | None  # Moderation score
    imported_from_kahoot: bool | None  # Flag for imported content
    created_at: datetime
    updated_at: datetime  # Used for sorting review queue
    user_id: uuid.UUID  # Quiz creator
The moderation endpoints filter quizzes by: Public only:
.filter(Quiz.public == True)
Unrated only (when all=false):
.filter(Quiz.mod_rating == None)
Sorted by update time:
.order_by(Quiz.updated_at.desc())
This ensures moderators see:
  1. Only public quizzes (private quizzes aren’t moderated)
  2. Recently updated quizzes first
  3. Unrated quizzes by default
Moderation ratings can be used to filter search results:
# Example: Only show quizzes with rating >= 3 in search
high_quality = await Quiz.objects.filter(
    public=True,
    mod_rating__gte=3
).all()
Your ClassQuiz instance may implement:
  • Minimum rating thresholds for public search
  • Sorting by rating in browse pages
  • Filtering low-rated content from recommendations

Best Practices

For Moderators

1

Be consistent

Use the same rating criteria for all quizzes. Document your guidelines and follow them.
2

Be fair

Judge content objectively based on quality, not personal preferences.
3

Leave notes

If your system supports moderation notes, document reasons for low ratings.
4

Act quickly on violations

Escalate serious policy violations to administrators immediately.

For Instance Administrators

  1. Clear guidelines: Publish moderation standards for your instance
  2. Multiple moderators: Distribute workload among trusted users
  3. Appeals process: Allow quiz creators to appeal ratings
  4. Automation: Consider auto-hiding quizzes with rating < 2
  5. Metrics: Track moderation velocity and rating distribution

API Implementation

The moderation system is a lightweight API with three endpoints:
  1. Status check (/status): Verify moderator permissions
  2. Review queue (/quizzes): Get quizzes to review with pagination
  3. Set rating (/rating/set/{quiz_id}): Assign or remove ratings
All endpoints require moderator authentication via get_current_moderator dependency. See complete implementation in classquiz/routers/moderation.py:1-62.

Future Enhancements

Potential moderation features (not yet implemented):
  • Moderation history log
  • Multi-moderator consensus
  • Automated spam detection
  • Report system for users
  • Moderator performance metrics
  • Bulk rating operations
  • Custom rating categories (accuracy, design, educational value)
If you’re building moderation tooling, consider tracking moderator actions in a separate audit log table for accountability and analytics.

Build docs developers (and LLMs) love