USE dating_app; -- Add the unified login field without deleting legacy data. SET @column_exists = ( SELECT COUNT(*) FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = 'users' AND column_name = 'email_or_phone' ); SET @statement = IF( @column_exists = 0, 'ALTER TABLE users ADD COLUMN email_or_phone VARCHAR(320) NULL AFTER id', 'SELECT 1' ); PREPARE migration_statement FROM @statement; EXECUTE migration_statement; DEALLOCATE PREPARE migration_statement; -- Copy existing accounts into the unified field. Email is normalized to lowercase. UPDATE users SET email_or_phone = CASE WHEN email IS NOT NULL THEN LOWER(TRIM(email)) ELSE TRIM(phone) END WHERE email_or_phone IS NULL; SET @index_exists = ( SELECT COUNT(*) FROM information_schema.statistics WHERE table_schema = DATABASE() AND table_name = 'users' AND column_name = 'email_or_phone' AND non_unique = 0 ); SET @statement = IF( @index_exists = 0, 'CREATE UNIQUE INDEX uq_users_email_or_phone ON users (email_or_phone)', 'SELECT 1' ); PREPARE migration_statement FROM @statement; EXECUTE migration_statement; DEALLOCATE PREPARE migration_statement; -- MVP has no OTP step, so previously pending accounts become usable immediately. UPDATE users SET status = 'active' WHERE status = 'pending'; ALTER TABLE users MODIFY COLUMN status VARCHAR(20) NOT NULL DEFAULT 'active'; -- Older schemas may require these legacy columns on INSERT. Keep them compatible -- while the application stops using them. SET @column_exists = ( SELECT COUNT(*) FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = 'users' AND column_name = 'email_verified' ); SET @statement = IF( @column_exists > 0, 'ALTER TABLE users MODIFY COLUMN email_verified BOOLEAN NOT NULL DEFAULT FALSE', 'SELECT 1' ); PREPARE migration_statement FROM @statement; EXECUTE migration_statement; DEALLOCATE PREPARE migration_statement; SET @column_exists = ( SELECT COUNT(*) FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = 'users' AND column_name = 'phone_verified' ); SET @statement = IF( @column_exists > 0, 'ALTER TABLE users MODIFY COLUMN phone_verified BOOLEAN NOT NULL DEFAULT FALSE', 'SELECT 1' ); PREPARE migration_statement FROM @statement; EXECUTE migration_statement; DEALLOCATE PREPARE migration_statement; -- Legacy email, phone, verification columns and verification_codes are intentionally -- retained so this migration does not destroy historical data. New code no longer uses them.