exec("ALTER TABLE users ADD COLUMN email_hash VARCHAR(64) AFTER email, ADD INDEX (email_hash)"); echo "[OK] Added email_hash column and index.\n"; } catch (\Exception $e) { echo "[SKIP] email_hash column might already exist.\n"; } // 2. Fetch all users to encrypt their data $stmt = $db->query("SELECT id, name, email FROM users"); $users = $stmt->fetchAll(); echo "Found " . count($users) . " users. Starting encryption...\n"; $updateStmt = $db->prepare("UPDATE users SET name = ?, email = ?, email_hash = ? WHERE id = ?"); foreach ($users as $user) { // Check if data is already encrypted (to avoid double encryption) $isAlreadyEncrypted = Encryption::decrypt($user['email']) !== false; if ($isAlreadyEncrypted) { echo "User ID {$user['id']} is already encrypted. Skipping.\n"; continue; } // Encrypt Name $encryptedName = Encryption::encrypt($user['name']); // Encrypt Email $encryptedEmail = Encryption::encrypt($user['email']); // Generate Hash for lookup $emailHash = hash('sha256', strtolower($user['email'])); $updateStmt->execute([ $encryptedName, $encryptedEmail, $emailHash, $user['id'] ]); echo "User ID {$user['id']} migrated successfully.\n"; } // 3. Create companies table (Updated to match production schema) try { $db->exec("CREATE TABLE IF NOT EXISTS companies ( id INT AUTO_INCREMENT PRIMARY KEY, tenant_id INT, name VARCHAR(255) NOT NULL, name_en VARCHAR(255), tax_identification_number VARCHAR(50), commercial_registration_number VARCHAR(50), address TEXT, city VARCHAR(100), contact_email VARCHAR(255), contact_phone VARCHAR(50), jofotara_client_id_encrypted TEXT, jofotara_secret_key_encrypted TEXT, jofotara_income_source_sequence VARCHAR(50), certificate_path VARCHAR(255), certificate_password_encrypted TEXT, is_jofotara_linked TINYINT(1) DEFAULT 0, is_active TINYINT(1) DEFAULT 1, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, deleted_at DATETIME DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4"); echo "[OK] Companies table synchronized with production schema.\n"; } catch (\Exception $e) { echo "[ERROR] Synchronizing companies table: " . $e->getMessage() . "\n"; } // 4. Create user_companies pivot table try { $db->exec("CREATE TABLE IF NOT EXISTS user_companies ( id INT AUTO_INCREMENT PRIMARY KEY, user_id INT NOT NULL, company_id INT NOT NULL, role VARCHAR(50) DEFAULT 'employee', created_at DATETIME DEFAULT CURRENT_TIMESTAMP, UNIQUE KEY user_company (user_id, company_id), FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE, FOREIGN KEY (company_id) REFERENCES companies(id) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4"); echo "[OK] User_companies table created or exists.\n"; } catch (\Exception $e) { echo "[ERROR] Creating user_companies table: " . $e->getMessage() . "\n"; } echo "--- Migration Complete ---\n";