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;