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

@@ -0,0 +1,105 @@
/**
* 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;
}
}
};

View File

@@ -0,0 +1,61 @@
'use strict';
/** @type {import('sequelize-cli').Migration} */
module.exports = {
async up (queryInterface, Sequelize) {
console.log('Creating guest_settings table...');
await queryInterface.createTable('guest_settings', {
id: {
type: Sequelize.CHAR(36),
primaryKey: true,
allowNull: false,
comment: 'UUID primary key'
},
max_quizzes: {
type: Sequelize.INTEGER,
allowNull: false,
defaultValue: 3,
comment: 'Maximum number of quizzes a guest can take'
},
expiry_hours: {
type: Sequelize.INTEGER,
allowNull: false,
defaultValue: 24,
comment: 'Guest session expiry time in hours'
},
public_categories: {
type: Sequelize.JSON,
allowNull: false,
defaultValue: '[]',
comment: 'Array of category UUIDs accessible to guests'
},
feature_restrictions: {
type: Sequelize.JSON,
allowNull: false,
defaultValue: '{"allowBookmarks":false,"allowReview":true,"allowPracticeMode":true,"allowTimedMode":false,"allowExamMode":false}',
comment: 'Feature restrictions for guest users'
},
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')
}
}, {
comment: 'System-wide guest user settings'
});
console.log('✅ guest_settings table created successfully');
},
async down (queryInterface, Sequelize) {
console.log('Dropping guest_settings table...');
await queryInterface.dropTable('guest_settings');
console.log('✅ guest_settings table dropped successfully');
}
};