'use strict'; /** @type {import('sequelize-cli').Migration} */ module.exports = { async up (queryInterface, Sequelize) { console.log('Creating questions table...'); await queryInterface.createTable('questions', { id: { type: Sequelize.CHAR(36), primaryKey: true, allowNull: false, comment: 'UUID primary key' }, category_id: { type: Sequelize.CHAR(36), allowNull: false, references: { model: 'categories', key: 'id' }, onUpdate: 'CASCADE', onDelete: 'RESTRICT', comment: 'Foreign key to categories table' }, created_by: { type: Sequelize.CHAR(36), allowNull: true, references: { model: 'users', key: 'id' }, onUpdate: 'CASCADE', onDelete: 'SET NULL', comment: 'User who created the question (admin)' }, question_text: { type: Sequelize.TEXT, allowNull: false, comment: 'The question text' }, question_type: { type: Sequelize.ENUM('multiple', 'trueFalse', 'written'), allowNull: false, defaultValue: 'multiple', comment: 'Type of question' }, options: { type: Sequelize.JSON, allowNull: true, comment: 'Answer options for multiple choice (JSON array)' }, correct_answer: { type: Sequelize.STRING(255), allowNull: false, comment: 'Correct answer (index for multiple choice, true/false for boolean)' }, explanation: { type: Sequelize.TEXT, allowNull: true, comment: 'Explanation for the correct answer' }, difficulty: { type: Sequelize.ENUM('easy', 'medium', 'hard'), allowNull: false, defaultValue: 'medium', comment: 'Question difficulty level' }, points: { type: Sequelize.INTEGER, allowNull: false, defaultValue: 10, comment: 'Points awarded for correct answer' }, time_limit: { type: Sequelize.INTEGER, allowNull: true, comment: 'Time limit in seconds (optional)' }, keywords: { type: Sequelize.JSON, allowNull: true, comment: 'Search keywords (JSON array)' }, tags: { type: Sequelize.JSON, allowNull: true, comment: 'Tags for categorization (JSON array)' }, visibility: { type: Sequelize.ENUM('public', 'registered', 'premium'), allowNull: false, defaultValue: 'registered', comment: 'Who can see this question' }, guest_accessible: { type: Sequelize.BOOLEAN, allowNull: false, defaultValue: false, comment: 'Whether guests can access this question' }, is_active: { type: Sequelize.BOOLEAN, allowNull: false, defaultValue: true, comment: 'Question active status' }, times_attempted: { type: Sequelize.INTEGER, allowNull: false, defaultValue: 0, comment: 'Number of times question was attempted' }, times_correct: { type: Sequelize.INTEGER, allowNull: false, defaultValue: 0, comment: 'Number of times answered correctly' }, created_at: { type: Sequelize.DATE, allowNull: false, defaultValue: Sequelize.literal('CURRENT_TIMESTAMP') }, updated_at: { type: Sequelize.DATE, allowNull: false, defaultValue: Sequelize.literal('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP') } }, { charset: 'utf8mb4', collate: 'utf8mb4_unicode_ci', engine: 'InnoDB' }); // Add indexes await queryInterface.addIndex('questions', ['category_id'], { name: 'idx_questions_category_id' }); await queryInterface.addIndex('questions', ['created_by'], { name: 'idx_questions_created_by' }); await queryInterface.addIndex('questions', ['question_type'], { name: 'idx_questions_question_type' }); await queryInterface.addIndex('questions', ['difficulty'], { name: 'idx_questions_difficulty' }); await queryInterface.addIndex('questions', ['visibility'], { name: 'idx_questions_visibility' }); await queryInterface.addIndex('questions', ['guest_accessible'], { name: 'idx_questions_guest_accessible' }); await queryInterface.addIndex('questions', ['is_active'], { name: 'idx_questions_is_active' }); await queryInterface.addIndex('questions', ['created_at'], { name: 'idx_questions_created_at' }); // Composite index for common query patterns await queryInterface.addIndex('questions', ['category_id', 'is_active', 'difficulty'], { name: 'idx_questions_category_active_difficulty' }); await queryInterface.addIndex('questions', ['is_active', 'guest_accessible'], { name: 'idx_questions_active_guest' }); // Full-text search index await queryInterface.sequelize.query( 'CREATE FULLTEXT INDEX idx_questions_fulltext ON questions(question_text, explanation)' ); console.log('✅ Questions table created successfully with indexes and full-text search'); }, async down (queryInterface, Sequelize) { console.log('Dropping questions table...'); await queryInterface.dropTable('questions'); console.log('✅ Questions table dropped successfully'); } };