add changes

This commit is contained in:
AD2025
2025-11-12 23:06:27 +02:00
parent c664d0a341
commit ec6534fcc2
42 changed files with 11854 additions and 299 deletions

View File

@@ -1,35 +1,419 @@
const express = require('express');
const router = express.Router();
const questionController = require('../controllers/question.controller');
const adminController = require('../controllers/admin.controller');
const { verifyToken, isAdmin } = require('../middleware/auth.middleware');
const { adminLimiter } = require('../middleware/rateLimiter');
const { cacheStatistics, cacheGuestAnalytics, cacheGuestSettings, invalidateCacheMiddleware, invalidateCache } = require('../middleware/cache');
/**
* @route POST /api/admin/questions
* @desc Create a new question (Admin only)
* @access Admin
* @body {
* questionText, questionType, options, correctAnswer,
* difficulty, points, explanation, categoryId, tags, keywords
* }
* @swagger
* /admin/statistics:
* get:
* summary: Get system-wide statistics for admin dashboard
* tags: [Admin]
* security:
* - bearerAuth: []
* responses:
* 200:
* description: Statistics retrieved successfully
* content:
* application/json:
* schema:
* type: object
* properties:
* users:
* type: object
* properties:
* total:
* type: integer
* active:
* type: integer
* inactiveLast7Days:
* type: integer
* quizzes:
* type: object
* properties:
* totalSessions:
* type: integer
* averageScore:
* type: number
* passRate:
* type: number
* content:
* type: object
* properties:
* totalCategories:
* type: integer
* totalQuestions:
* type: integer
* 401:
* $ref: '#/components/responses/UnauthorizedError'
* 403:
* $ref: '#/components/responses/ForbiddenError'
*
* /admin/guest-settings:
* get:
* summary: Get guest user settings
* tags: [Admin]
* security:
* - bearerAuth: []
* responses:
* 200:
* description: Guest settings retrieved successfully
* 401:
* $ref: '#/components/responses/UnauthorizedError'
* 403:
* $ref: '#/components/responses/ForbiddenError'
* put:
* summary: Update guest user settings
* tags: [Admin]
* security:
* - bearerAuth: []
* requestBody:
* content:
* application/json:
* schema:
* type: object
* properties:
* maxQuizzes:
* type: integer
* minimum: 1
* maximum: 100
* expiryHours:
* type: integer
* minimum: 1
* maximum: 168
* publicCategories:
* type: array
* items:
* type: integer
* featureRestrictions:
* type: object
* responses:
* 200:
* description: Settings updated successfully
* 401:
* $ref: '#/components/responses/UnauthorizedError'
* 403:
* $ref: '#/components/responses/ForbiddenError'
*
* /admin/guest-analytics:
* get:
* summary: Get guest user analytics
* tags: [Admin]
* security:
* - bearerAuth: []
* responses:
* 200:
* description: Analytics retrieved successfully
* content:
* application/json:
* schema:
* type: object
* properties:
* overview:
* type: object
* properties:
* totalGuestSessions:
* type: integer
* activeGuestSessions:
* type: integer
* convertedGuestSessions:
* type: integer
* conversionRate:
* type: number
* quizActivity:
* type: object
* behavior:
* type: object
* 401:
* $ref: '#/components/responses/UnauthorizedError'
* 403:
* $ref: '#/components/responses/ForbiddenError'
*
* /admin/users:
* get:
* summary: Get all users with pagination and filtering
* tags: [Admin]
* security:
* - bearerAuth: []
* parameters:
* - in: query
* name: page
* schema:
* type: integer
* default: 1
* - in: query
* name: limit
* schema:
* type: integer
* default: 10
* maximum: 100
* - in: query
* name: role
* schema:
* type: string
* enum: [user, admin]
* - in: query
* name: isActive
* schema:
* type: boolean
* - in: query
* name: sortBy
* schema:
* type: string
* enum: [createdAt, username, email]
* - in: query
* name: sortOrder
* schema:
* type: string
* enum: [asc, desc]
* responses:
* 200:
* description: Users retrieved successfully
* 401:
* $ref: '#/components/responses/UnauthorizedError'
* 403:
* $ref: '#/components/responses/ForbiddenError'
*
* /admin/users/{userId}:
* get:
* summary: Get user details by ID
* tags: [Admin]
* security:
* - bearerAuth: []
* parameters:
* - in: path
* name: userId
* required: true
* schema:
* type: integer
* responses:
* 200:
* description: User details retrieved successfully
* 401:
* $ref: '#/components/responses/UnauthorizedError'
* 403:
* $ref: '#/components/responses/ForbiddenError'
* 404:
* $ref: '#/components/responses/NotFoundError'
*/
// Apply admin rate limiter to all routes
router.use(adminLimiter);
router.get('/statistics', verifyToken, isAdmin, cacheStatistics, adminController.getSystemStatistics);
router.get('/guest-settings', verifyToken, isAdmin, cacheGuestSettings, adminController.getGuestSettings);
router.put('/guest-settings', verifyToken, isAdmin, invalidateCacheMiddleware(() => invalidateCache.guestSettings()), adminController.updateGuestSettings);
router.get('/guest-analytics', verifyToken, isAdmin, cacheGuestAnalytics, adminController.getGuestAnalytics);
router.get('/users', verifyToken, isAdmin, adminController.getAllUsers);
router.get('/users/:userId', verifyToken, isAdmin, adminController.getUserById);
/**
* @swagger
* /admin/users/{userId}/role:
* put:
* summary: Update user role
* tags: [Admin]
* security:
* - bearerAuth: []
* parameters:
* - in: path
* name: userId
* required: true
* schema:
* type: integer
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required:
* - role
* properties:
* role:
* type: string
* enum: [user, admin]
* responses:
* 200:
* description: User role updated successfully
* 401:
* $ref: '#/components/responses/UnauthorizedError'
* 403:
* $ref: '#/components/responses/ForbiddenError'
* 404:
* $ref: '#/components/responses/NotFoundError'
*
* /admin/users/{userId}/activate:
* put:
* summary: Reactivate deactivated user
* tags: [Admin]
* security:
* - bearerAuth: []
* parameters:
* - in: path
* name: userId
* required: true
* schema:
* type: integer
* responses:
* 200:
* description: User reactivated successfully
* 401:
* $ref: '#/components/responses/UnauthorizedError'
* 403:
* $ref: '#/components/responses/ForbiddenError'
* 404:
* $ref: '#/components/responses/NotFoundError'
*
* /admin/users/{userId}:
* delete:
* summary: Deactivate user (soft delete)
* tags: [Admin]
* security:
* - bearerAuth: []
* parameters:
* - in: path
* name: userId
* required: true
* schema:
* type: integer
* responses:
* 200:
* description: User deactivated successfully
* 401:
* $ref: '#/components/responses/UnauthorizedError'
* 403:
* $ref: '#/components/responses/ForbiddenError'
* 404:
* $ref: '#/components/responses/NotFoundError'
*
* /admin/questions:
* post:
* summary: Create a new question
* tags: [Questions]
* security:
* - bearerAuth: []
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required:
* - questionText
* - questionType
* - correctAnswer
* - difficulty
* - categoryId
* properties:
* questionText:
* type: string
* questionType:
* type: string
* enum: [multiple_choice, true_false, short_answer]
* options:
* type: array
* items:
* type: string
* correctAnswer:
* type: string
* difficulty:
* type: string
* enum: [easy, medium, hard]
* points:
* type: integer
* explanation:
* type: string
* categoryId:
* type: integer
* tags:
* type: array
* items:
* type: string
* keywords:
* type: array
* items:
* type: string
* responses:
* 201:
* description: Question created successfully
* 401:
* $ref: '#/components/responses/UnauthorizedError'
* 403:
* $ref: '#/components/responses/ForbiddenError'
*
* /admin/questions/{id}:
* put:
* summary: Update a question
* tags: [Questions]
* security:
* - bearerAuth: []
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: integer
* requestBody:
* content:
* application/json:
* schema:
* type: object
* properties:
* questionText:
* type: string
* options:
* type: array
* items:
* type: string
* correctAnswer:
* type: string
* difficulty:
* type: string
* enum: [easy, medium, hard]
* isActive:
* type: boolean
* responses:
* 200:
* description: Question updated successfully
* 401:
* $ref: '#/components/responses/UnauthorizedError'
* 403:
* $ref: '#/components/responses/ForbiddenError'
* 404:
* $ref: '#/components/responses/NotFoundError'
* delete:
* summary: Delete a question (soft delete)
* tags: [Questions]
* security:
* - bearerAuth: []
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: integer
* responses:
* 200:
* description: Question deleted successfully
* 401:
* $ref: '#/components/responses/UnauthorizedError'
* 403:
* $ref: '#/components/responses/ForbiddenError'
* 404:
* $ref: '#/components/responses/NotFoundError'
*/
// Apply admin rate limiter to all routes
router.use(adminLimiter);
router.put('/users/:userId/role', verifyToken, isAdmin, adminController.updateUserRole);
router.put('/users/:userId/activate', verifyToken, isAdmin, adminController.reactivateUser);
router.delete('/users/:userId', verifyToken, isAdmin, adminController.deactivateUser);
router.post('/questions', verifyToken, isAdmin, questionController.createQuestion);
/**
* @route PUT /api/admin/questions/:id
* @desc Update a question (Admin only)
* @access Admin
* @body {
* questionText?, questionType?, options?, correctAnswer?,
* difficulty?, points?, explanation?, categoryId?, tags?, keywords?, isActive?
* }
*/
router.put('/questions/:id', verifyToken, isAdmin, questionController.updateQuestion);
/**
* @route DELETE /api/admin/questions/:id
* @desc Delete a question - soft delete (Admin only)
* @access Admin
*/
router.delete('/questions/:id', verifyToken, isAdmin, questionController.deleteQuestion);
module.exports = router;