'use strict'; /** @type {import('sequelize-cli').Migration} */ module.exports = { async up (queryInterface, Sequelize) { console.log('Creating guest_sessions table...'); await queryInterface.createTable('guest_sessions', { id: { type: Sequelize.CHAR(36), primaryKey: true, allowNull: false, comment: 'UUID primary key' }, guest_id: { type: Sequelize.STRING(100), allowNull: false, unique: true, comment: 'Unique guest identifier' }, session_token: { type: Sequelize.STRING(500), allowNull: false, unique: true, comment: 'JWT session token' }, device_id: { type: Sequelize.STRING(255), allowNull: true, comment: 'Device identifier (optional)' }, ip_address: { type: Sequelize.STRING(45), allowNull: true, comment: 'IP address (supports IPv6)' }, user_agent: { type: Sequelize.TEXT, allowNull: true, comment: 'Browser user agent string' }, quizzes_attempted: { type: Sequelize.INTEGER, allowNull: false, defaultValue: 0, comment: 'Number of quizzes attempted by guest' }, max_quizzes: { type: Sequelize.INTEGER, allowNull: false, defaultValue: 3, comment: 'Maximum quizzes allowed for this guest' }, expires_at: { type: Sequelize.DATE, allowNull: false, comment: 'Session expiration timestamp' }, is_converted: { type: Sequelize.BOOLEAN, allowNull: false, defaultValue: false, comment: 'Whether guest converted to registered user' }, converted_user_id: { type: Sequelize.CHAR(36), allowNull: true, references: { model: 'users', key: 'id' }, onUpdate: 'CASCADE', onDelete: 'SET NULL', comment: 'User ID if guest converted to registered user' }, 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('guest_sessions', ['guest_id'], { unique: true, name: 'idx_guest_sessions_guest_id' }); await queryInterface.addIndex('guest_sessions', ['session_token'], { unique: true, name: 'idx_guest_sessions_session_token' }); await queryInterface.addIndex('guest_sessions', ['expires_at'], { name: 'idx_guest_sessions_expires_at' }); await queryInterface.addIndex('guest_sessions', ['is_converted'], { name: 'idx_guest_sessions_is_converted' }); await queryInterface.addIndex('guest_sessions', ['converted_user_id'], { name: 'idx_guest_sessions_converted_user_id' }); await queryInterface.addIndex('guest_sessions', ['device_id'], { name: 'idx_guest_sessions_device_id' }); await queryInterface.addIndex('guest_sessions', ['created_at'], { name: 'idx_guest_sessions_created_at' }); console.log('✅ Guest sessions table created successfully with indexes'); }, async down (queryInterface, Sequelize) { console.log('Dropping guest_sessions table...'); await queryInterface.dropTable('guest_sessions'); console.log('✅ Guest sessions table dropped successfully'); } };