/** * Migration: Add Database Indexes for Performance Optimization * * This migration adds indexes to improve query performance for: * - QuizSession: userId, guestSessionId, categoryId, status, createdAt * - QuizSessionQuestion: quizSessionId, questionId * * Note: Other models (User, Question, Category, GuestSession, QuizAnswer, UserBookmark) * already have indexes defined in their models. */ module.exports = { up: async (queryInterface, Sequelize) => { console.log('Adding performance indexes...'); try { // QuizSession indexes await queryInterface.addIndex('quiz_sessions', ['user_id'], { name: 'idx_quiz_sessions_user_id' }); await queryInterface.addIndex('quiz_sessions', ['guest_session_id'], { name: 'idx_quiz_sessions_guest_session_id' }); await queryInterface.addIndex('quiz_sessions', ['category_id'], { name: 'idx_quiz_sessions_category_id' }); await queryInterface.addIndex('quiz_sessions', ['status'], { name: 'idx_quiz_sessions_status' }); await queryInterface.addIndex('quiz_sessions', ['created_at'], { name: 'idx_quiz_sessions_created_at' }); // Composite indexes for common queries await queryInterface.addIndex('quiz_sessions', ['user_id', 'created_at'], { name: 'idx_quiz_sessions_user_created' }); await queryInterface.addIndex('quiz_sessions', ['guest_session_id', 'created_at'], { name: 'idx_quiz_sessions_guest_created' }); await queryInterface.addIndex('quiz_sessions', ['category_id', 'status'], { name: 'idx_quiz_sessions_category_status' }); // QuizSessionQuestion indexes await queryInterface.addIndex('quiz_session_questions', ['quiz_session_id'], { name: 'idx_quiz_session_questions_session_id' }); await queryInterface.addIndex('quiz_session_questions', ['question_id'], { name: 'idx_quiz_session_questions_question_id' }); await queryInterface.addIndex('quiz_session_questions', ['quiz_session_id', 'question_order'], { name: 'idx_quiz_session_questions_session_order' }); // Unique constraint to prevent duplicate questions in same session await queryInterface.addIndex('quiz_session_questions', ['quiz_session_id', 'question_id'], { name: 'idx_quiz_session_questions_session_question_unique', unique: true }); console.log('✅ Performance indexes added successfully'); } catch (error) { console.error('❌ Error adding indexes:', error); throw error; } }, down: async (queryInterface, Sequelize) => { console.log('Removing performance indexes...'); try { // Remove QuizSession indexes await queryInterface.removeIndex('quiz_sessions', 'idx_quiz_sessions_user_id'); await queryInterface.removeIndex('quiz_sessions', 'idx_quiz_sessions_guest_session_id'); await queryInterface.removeIndex('quiz_sessions', 'idx_quiz_sessions_category_id'); await queryInterface.removeIndex('quiz_sessions', 'idx_quiz_sessions_status'); await queryInterface.removeIndex('quiz_sessions', 'idx_quiz_sessions_created_at'); await queryInterface.removeIndex('quiz_sessions', 'idx_quiz_sessions_user_created'); await queryInterface.removeIndex('quiz_sessions', 'idx_quiz_sessions_guest_created'); await queryInterface.removeIndex('quiz_sessions', 'idx_quiz_sessions_category_status'); // Remove QuizSessionQuestion indexes await queryInterface.removeIndex('quiz_session_questions', 'idx_quiz_session_questions_session_id'); await queryInterface.removeIndex('quiz_session_questions', 'idx_quiz_session_questions_question_id'); await queryInterface.removeIndex('quiz_session_questions', 'idx_quiz_session_questions_session_order'); await queryInterface.removeIndex('quiz_session_questions', 'idx_quiz_session_questions_session_question_unique'); console.log('✅ Performance indexes removed successfully'); } catch (error) { console.error('❌ Error removing indexes:', error); throw error; } } };