Files
tasks-backend/ADMIN_QUESTIONS_API.md
2025-12-26 23:56:32 +02:00

7.9 KiB

Admin Questions API - Pagination & Search Documentation

Endpoint

GET /api/admin/questions

Authentication Required: Admin only (Bearer token)

Description

Retrieves all questions with comprehensive pagination, filtering, and search capabilities. This endpoint is designed for admin dashboards to manage questions efficiently.

Query Parameters

Parameter Type Default Description Validation
page number 1 Page number for pagination Min: 1
limit number 10 Number of results per page Min: 1, Max: 100
search string '' Search term for question text, explanation, or tags -
category UUID '' Filter by category UUID Must be valid UUID
difficulty string '' Filter by difficulty level easy, medium, hard
sortBy string 'createdAt' Field to sort by See valid fields below
order string 'DESC' Sort order ASC or DESC

Valid Sort Fields

  • createdAt (default)
  • updatedAt
  • questionText
  • difficulty
  • points
  • timesAttempted

Response Structure

{
  "success": true,
  "count": 10,
  "total": 45,
  "page": 1,
  "totalPages": 5,
  "limit": 10,
  "filters": {
    "search": "javascript",
    "category": "68b4c87f-db0b-48ea-b8a4-b2f4fce785a2",
    "difficulty": "easy",
    "sortBy": "createdAt",
    "order": "DESC"
  },
  "data": [
    {
      "id": "uuid",
      "questionText": "What is a closure in JavaScript?",
      "questionType": "multiple",
      "options": [
        {
          "id": "a",
          "text": "Option A"
        }
      ],
      "correctAnswer": "a",
      "difficulty": "medium",
      "points": 10,
      "explanation": "Detailed explanation...",
      "tags": ["closures", "functions"],
      "keywords": ["closure", "scope"],
      "timesAttempted": 150,
      "timesCorrect": 120,
      "accuracy": 80,
      "isActive": true,
      "category": {
        "id": "uuid",
        "name": "JavaScript",
        "slug": "javascript",
        "icon": "code",
        "color": "#F7DF1E",
        "guestAccessible": true
      },
      "createdAt": "2025-11-19T10:00:00.000Z",
      "updatedAt": "2025-11-19T10:00:00.000Z"
    }
  ],
  "message": "Retrieved 10 of 45 questions"
}

Usage Examples

Basic Request

curl -X GET "http://localhost:3000/api/admin/questions" \
  -H "Authorization: Bearer YOUR_ADMIN_TOKEN"

With Pagination

curl -X GET "http://localhost:3000/api/admin/questions?page=2&limit=20" \
  -H "Authorization: Bearer YOUR_ADMIN_TOKEN"

Search Questions

curl -X GET "http://localhost:3000/api/admin/questions?search=async" \
  -H "Authorization: Bearer YOUR_ADMIN_TOKEN"

Filter by Category

curl -X GET "http://localhost:3000/api/admin/questions?category=68b4c87f-db0b-48ea-b8a4-b2f4fce785a2" \
  -H "Authorization: Bearer YOUR_ADMIN_TOKEN"

Filter by Difficulty

curl -X GET "http://localhost:3000/api/admin/questions?difficulty=easy" \
  -H "Authorization: Bearer YOUR_ADMIN_TOKEN"

Combined Filters

curl -X GET "http://localhost:3000/api/admin/questions?search=javascript&difficulty=medium&category=68b4c87f-db0b-48ea-b8a4-b2f4fce785a2&page=1&limit=15" \
  -H "Authorization: Bearer YOUR_ADMIN_TOKEN"

Custom Sorting

# Sort by points ascending
curl -X GET "http://localhost:3000/api/admin/questions?sortBy=points&order=ASC" \
  -H "Authorization: Bearer YOUR_ADMIN_TOKEN"

# Sort by difficulty descending
curl -X GET "http://localhost:3000/api/admin/questions?sortBy=difficulty&order=DESC" \
  -H "Authorization: Bearer YOUR_ADMIN_TOKEN"

JavaScript/Axios Examples

Basic Request

const axios = require('axios');

const response = await axios.get('http://localhost:3000/api/admin/questions', {
  headers: { Authorization: `Bearer ${adminToken}` }
});

console.log(`Total questions: ${response.data.total}`);
console.log(`Current page: ${response.data.page}`);
console.log(`Questions:`, response.data.data);

With All Filters

const params = {
  page: 1,
  limit: 20,
  search: 'async',
  category: '68b4c87f-db0b-48ea-b8a4-b2f4fce785a2',
  difficulty: 'medium',
  sortBy: 'points',
  order: 'DESC'
};

const response = await axios.get('http://localhost:3000/api/admin/questions', {
  params,
  headers: { Authorization: `Bearer ${adminToken}` }
});

Paginate Through All Questions

async function getAllQuestions(adminToken) {
  const allQuestions = [];
  let currentPage = 1;
  let totalPages = 1;

  do {
    const response = await axios.get('http://localhost:3000/api/admin/questions', {
      params: { page: currentPage, limit: 50 },
      headers: { Authorization: `Bearer ${adminToken}` }
    });

    allQuestions.push(...response.data.data);
    totalPages = response.data.totalPages;
    currentPage++;
  } while (currentPage <= totalPages);

  return allQuestions;
}

Error Responses

401 Unauthorized

{
  "success": false,
  "message": "Authentication required"
}

403 Forbidden

{
  "success": false,
  "message": "Admin access required"
}

500 Internal Server Error

{
  "success": false,
  "message": "An error occurred while retrieving questions",
  "error": "Error details (in development mode)"
}

Features

Pagination

  • Efficient offset-based pagination
  • Configurable page size (1-100)
  • Total count and pages metadata
  • Handles out-of-range pages gracefully
  • Full-text search across question text
  • Search in explanations
  • Search in tags
  • Case-insensitive matching
  • Handles special characters

Filtering

  • Filter by category (UUID)
  • Filter by difficulty (easy/medium/hard)
  • Combine multiple filters
  • Invalid UUIDs handled gracefully

Sorting

  • Sort by multiple fields
  • Ascending or descending order
  • Invalid sort fields default to createdAt
  • Consistent ordering

Response Data

  • Calculated accuracy percentage
  • Complete question details including correctAnswer (admin only)
  • Category information
  • Active/inactive status
  • Timestamps

Performance Considerations

  1. Limit: Maximum 100 questions per page to prevent performance issues
  2. Indexing: Database indexes on frequently queried fields (categoryId, difficulty, isActive)
  3. Pagination: Offset-based pagination is efficient for moderate dataset sizes
  4. Search: Uses SQL LIKE for search - consider full-text indexes for large datasets

Testing

Run the comprehensive test suite:

node test-admin-questions-pagination.js

The test suite covers:

  • Authorization (35 tests)
  • Pagination (8 tests)
  • Search functionality (4 tests)
  • Filtering (9 tests)
  • Combined filters (4 tests)
  • Sorting (5 tests)
  • Response structure (5 tests)
  • Edge cases and performance

Total: 35 comprehensive test cases

  • POST /api/admin/questions - Create a new question
  • PUT /api/admin/questions/:id - Update a question
  • DELETE /api/admin/questions/:id - Delete a question (soft delete)
  • GET /api/questions/category/:categoryId - Public endpoint for questions by category
  • GET /api/questions/search - Public search endpoint with guest filtering
  • GET /api/questions/:id - Get single question by ID

Notes

  • Admin Only: This endpoint requires admin authentication
  • correctAnswer: Admin responses include the correct answer (unlike public endpoints)
  • isActive: Includes both active and inactive questions for admin management
  • Accuracy: Calculated as (timesCorrect / timesAttempted) * 100
  • Category Filtering: Invalid UUIDs are silently ignored (returns all categories)
  • Search: Empty search string returns all questions

Changelog

Version 1.0.0 (2025-11-19)

  • Initial implementation
  • Pagination support (page, limit)
  • Search functionality (question text, explanation, tags)
  • Filtering by category and difficulty
  • Sorting by multiple fields
  • Comprehensive test suite