add changes

This commit is contained in:
AD2025
2025-12-26 23:56:32 +02:00
parent 410c3d725f
commit e7d26bc981
127 changed files with 36162 additions and 0 deletions

348
config/swagger.js Normal file
View File

@@ -0,0 +1,348 @@
const swaggerJsdoc = require('swagger-jsdoc');
const options = {
definition: {
openapi: '3.0.0',
info: {
title: 'Interview Quiz Application API',
version: '1.0.0',
description: 'Comprehensive API documentation for the Interview Quiz Application. This API provides endpoints for user authentication, quiz management, guest sessions, bookmarks, and admin operations.',
contact: {
name: 'API Support',
email: 'support@interviewquiz.com'
},
license: {
name: 'MIT',
url: 'https://opensource.org/licenses/MIT'
}
},
servers: [
{
url: 'http://localhost:3000/api',
description: 'Development server'
},
{
url: 'https://api.interviewquiz.com/api',
description: 'Production server'
}
],
components: {
securitySchemes: {
bearerAuth: {
type: 'http',
scheme: 'bearer',
bearerFormat: 'JWT',
description: 'Enter your JWT token in the format: Bearer {token}'
}
},
schemas: {
Error: {
type: 'object',
properties: {
message: {
type: 'string',
description: 'Error message'
},
error: {
type: 'string',
description: 'Detailed error information'
}
}
},
User: {
type: 'object',
properties: {
id: {
type: 'integer',
description: 'User ID'
},
username: {
type: 'string',
description: 'Unique username'
},
email: {
type: 'string',
format: 'email',
description: 'User email address'
},
role: {
type: 'string',
enum: ['user', 'admin'],
description: 'User role'
},
isActive: {
type: 'boolean',
description: 'Account activation status'
},
createdAt: {
type: 'string',
format: 'date-time',
description: 'Account creation timestamp'
},
updatedAt: {
type: 'string',
format: 'date-time',
description: 'Last update timestamp'
}
}
},
Category: {
type: 'object',
properties: {
id: {
type: 'integer',
description: 'Category ID'
},
name: {
type: 'string',
description: 'Category name'
},
description: {
type: 'string',
description: 'Category description'
},
questionCount: {
type: 'integer',
description: 'Number of questions in category'
},
createdAt: {
type: 'string',
format: 'date-time'
}
}
},
Question: {
type: 'object',
properties: {
id: {
type: 'integer',
description: 'Question ID'
},
categoryId: {
type: 'integer',
description: 'Associated category ID'
},
questionText: {
type: 'string',
description: 'Question content'
},
difficulty: {
type: 'string',
enum: ['easy', 'medium', 'hard'],
description: 'Question difficulty level'
},
options: {
type: 'array',
items: {
type: 'string'
},
description: 'Answer options'
},
correctAnswer: {
type: 'string',
description: 'Correct answer (admin only)'
}
}
},
QuizSession: {
type: 'object',
properties: {
id: {
type: 'integer',
description: 'Quiz session ID'
},
userId: {
type: 'integer',
description: 'User ID (null for guest)'
},
guestSessionId: {
type: 'string',
format: 'uuid',
description: 'Guest session ID (null for authenticated user)'
},
categoryId: {
type: 'integer',
description: 'Quiz category ID'
},
totalQuestions: {
type: 'integer',
description: 'Total questions in quiz'
},
currentQuestionIndex: {
type: 'integer',
description: 'Current question position'
},
score: {
type: 'integer',
description: 'Current score'
},
isCompleted: {
type: 'boolean',
description: 'Quiz completion status'
},
completedAt: {
type: 'string',
format: 'date-time',
description: 'Completion timestamp'
},
startedAt: {
type: 'string',
format: 'date-time',
description: 'Start timestamp'
}
}
},
Bookmark: {
type: 'object',
properties: {
id: {
type: 'integer',
description: 'Bookmark ID'
},
userId: {
type: 'integer',
description: 'User ID'
},
questionId: {
type: 'integer',
description: 'Bookmarked question ID'
},
notes: {
type: 'string',
description: 'Optional user notes'
},
createdAt: {
type: 'string',
format: 'date-time'
},
Question: {
$ref: '#/components/schemas/Question'
}
}
},
GuestSession: {
type: 'object',
properties: {
guestSessionId: {
type: 'string',
format: 'uuid',
description: 'Unique guest session identifier'
},
convertedUserId: {
type: 'integer',
description: 'User ID after conversion (null if not converted)'
},
expiresAt: {
type: 'string',
format: 'date-time',
description: 'Session expiration timestamp'
},
createdAt: {
type: 'string',
format: 'date-time'
}
}
}
},
responses: {
UnauthorizedError: {
description: 'Authentication token is missing or invalid',
content: {
'application/json': {
schema: {
$ref: '#/components/schemas/Error'
},
example: {
message: 'No token provided'
}
}
}
},
ForbiddenError: {
description: 'User does not have permission to access this resource',
content: {
'application/json': {
schema: {
$ref: '#/components/schemas/Error'
},
example: {
message: 'Access denied. Admin only.'
}
}
}
},
NotFoundError: {
description: 'The requested resource was not found',
content: {
'application/json': {
schema: {
$ref: '#/components/schemas/Error'
},
example: {
message: 'Resource not found'
}
}
}
},
ValidationError: {
description: 'Request validation failed',
content: {
'application/json': {
schema: {
$ref: '#/components/schemas/Error'
},
example: {
message: 'Validation error',
error: 'Invalid input data'
}
}
}
}
}
},
security: [
{
bearerAuth: []
}
],
tags: [
{
name: 'Authentication',
description: 'User authentication and authorization endpoints'
},
{
name: 'Users',
description: 'User profile and account management'
},
{
name: 'Categories',
description: 'Quiz category management'
},
{
name: 'Questions',
description: 'Question management and retrieval'
},
{
name: 'Quiz',
description: 'Quiz session lifecycle and answer submission'
},
{
name: 'Bookmarks',
description: 'User question bookmarks'
},
{
name: 'Guest',
description: 'Guest user session management'
},
{
name: 'Admin',
description: 'Administrative operations (admin only)'
}
]
},
apis: ['./routes/*.js'] // Path to the API routes
};
const swaggerSpec = swaggerJsdoc(options);
module.exports = swaggerSpec;