'use strict'; /** @type {import('sequelize-cli').Migration} */ module.exports = { async up(queryInterface, Sequelize) { await queryInterface.createTable('achievements', { id: { type: Sequelize.CHAR(36), primaryKey: true, allowNull: false, comment: 'UUID primary key' }, name: { type: Sequelize.STRING(100), allowNull: false, unique: true, comment: 'Unique name of the achievement' }, slug: { type: Sequelize.STRING(100), allowNull: false, unique: true, comment: 'URL-friendly slug' }, description: { type: Sequelize.TEXT, allowNull: false, comment: 'Description of the achievement' }, icon: { type: Sequelize.STRING(50), allowNull: true, comment: 'Icon identifier (e.g., emoji or icon class)' }, badge_color: { type: Sequelize.STRING(20), allowNull: true, defaultValue: '#FFD700', comment: 'Hex color code for the badge' }, category: { type: Sequelize.ENUM('quiz', 'streak', 'score', 'speed', 'milestone', 'special'), allowNull: false, defaultValue: 'milestone', comment: 'Category of achievement' }, requirement_type: { type: Sequelize.ENUM('quizzes_completed', 'quizzes_passed', 'perfect_score', 'streak_days', 'total_questions', 'category_master', 'speed_demon', 'early_bird'), allowNull: false, comment: 'Type of requirement to earn the achievement' }, requirement_value: { type: Sequelize.INTEGER.UNSIGNED, allowNull: false, comment: 'Value needed to satisfy requirement (e.g., 10 for "10 quizzes")' }, points: { type: Sequelize.INTEGER.UNSIGNED, allowNull: false, defaultValue: 10, comment: 'Points awarded when achievement is earned' }, is_active: { type: Sequelize.BOOLEAN, allowNull: false, defaultValue: true, comment: 'Whether this achievement is currently available' }, display_order: { type: Sequelize.INTEGER.UNSIGNED, allowNull: false, defaultValue: 0, comment: 'Display order in achievement list' }, created_at: { type: Sequelize.DATE, allowNull: false, defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'), comment: 'Record creation timestamp' }, updated_at: { type: Sequelize.DATE, allowNull: false, defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'), comment: 'Record last update timestamp' } }, { charset: 'utf8mb4', collate: 'utf8mb4_unicode_ci', comment: 'Defines available achievements users can earn' }); // Add indexes await queryInterface.addIndex('achievements', ['slug'], { name: 'idx_achievements_slug', unique: true }); await queryInterface.addIndex('achievements', ['category'], { name: 'idx_achievements_category' }); await queryInterface.addIndex('achievements', ['requirement_type'], { name: 'idx_achievements_requirement_type' }); await queryInterface.addIndex('achievements', ['is_active'], { name: 'idx_achievements_is_active' }); await queryInterface.addIndex('achievements', ['display_order'], { name: 'idx_achievements_display_order' }); console.log('✅ Achievements table created with 13 fields and 5 indexes'); }, async down(queryInterface, Sequelize) { await queryInterface.dropTable('achievements'); console.log('✅ Achievements table dropped'); } };