322 lines
7.9 KiB
Markdown
322 lines
7.9 KiB
Markdown
# 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
|
|
|
|
```json
|
|
{
|
|
"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
|
|
|
|
```bash
|
|
curl -X GET "http://localhost:3000/api/admin/questions" \
|
|
-H "Authorization: Bearer YOUR_ADMIN_TOKEN"
|
|
```
|
|
|
|
### With Pagination
|
|
|
|
```bash
|
|
curl -X GET "http://localhost:3000/api/admin/questions?page=2&limit=20" \
|
|
-H "Authorization: Bearer YOUR_ADMIN_TOKEN"
|
|
```
|
|
|
|
### Search Questions
|
|
|
|
```bash
|
|
curl -X GET "http://localhost:3000/api/admin/questions?search=async" \
|
|
-H "Authorization: Bearer YOUR_ADMIN_TOKEN"
|
|
```
|
|
|
|
### Filter by Category
|
|
|
|
```bash
|
|
curl -X GET "http://localhost:3000/api/admin/questions?category=68b4c87f-db0b-48ea-b8a4-b2f4fce785a2" \
|
|
-H "Authorization: Bearer YOUR_ADMIN_TOKEN"
|
|
```
|
|
|
|
### Filter by Difficulty
|
|
|
|
```bash
|
|
curl -X GET "http://localhost:3000/api/admin/questions?difficulty=easy" \
|
|
-H "Authorization: Bearer YOUR_ADMIN_TOKEN"
|
|
```
|
|
|
|
### Combined Filters
|
|
|
|
```bash
|
|
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
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```javascript
|
|
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
|
|
|
|
```javascript
|
|
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
|
|
|
|
```javascript
|
|
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
|
|
|
|
```json
|
|
{
|
|
"success": false,
|
|
"message": "Authentication required"
|
|
}
|
|
```
|
|
|
|
### 403 Forbidden
|
|
|
|
```json
|
|
{
|
|
"success": false,
|
|
"message": "Admin access required"
|
|
}
|
|
```
|
|
|
|
### 500 Internal Server Error
|
|
|
|
```json
|
|
{
|
|
"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
|
|
|
|
### ✅ Search
|
|
- 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:
|
|
|
|
```bash
|
|
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
|
|
|
|
## Related Endpoints
|
|
|
|
- `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
|