diff --git a/backend/app/bootstrap.php b/backend/app/bootstrap.php index d47d669..fc2b994 100644 --- a/backend/app/bootstrap.php +++ b/backend/app/bootstrap.php @@ -30,15 +30,26 @@ spl_autoload_register(function ($class) { // 2. Load Environment Variables try { // Find the closest .env file path (supporting local development and CloudPanel server directories) - $env_file = APP_ROOT . '/.env'; - if (!file_exists($env_file)) { - if (file_exists(APP_ROOT . '/../../../.env')) { - $env_file = APP_ROOT . '/../../../.env'; - } elseif (file_exists(APP_ROOT . '/../.env')) { - $env_file = APP_ROOT . '/../.env'; + $candidatePaths = [ + APP_ROOT . '/.env', + APP_ROOT . '/../.env', + APP_ROOT . '/../../.env', + APP_ROOT . '/../../../.env', + APP_ROOT . '/../../../../.env', + '/home/intaleqapp-saqel/.env' + ]; + $env_file = null; + foreach ($candidatePaths as $path) { + if (file_exists($path)) { + $env_file = $path; + break; } } - \App\Core\Env::load($env_file); + if ($env_file) { + \App\Core\Env::load($env_file); + } else { + throw new \RuntimeException("No .env file found in candidate paths"); + } } catch (\Exception $e) { // In production, log error; in development, print it error_log('Env Load Error: ' . $e->getMessage()); diff --git a/backend/database_schema.sql b/backend/database_schema.sql index 9bf4a72..827e2ca 100644 --- a/backend/database_schema.sql +++ b/backend/database_schema.sql @@ -6,10 +6,28 @@ SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; +-- ------------------------------------------------------------------------------ +-- DROP ALL EXISTING TABLES IN REVERSE ORDER TO PREVENT FOREIGN KEY CONFLICTS +-- ------------------------------------------------------------------------------ +DROP TABLE IF EXISTS `otp_verifications`; +DROP TABLE IF EXISTS `user_devices`; +DROP TABLE IF EXISTS `voice_notes`; +DROP TABLE IF EXISTS `lesson_progress`; +DROP TABLE IF EXISTS `progress`; +DROP TABLE IF EXISTS `question_options`; +DROP TABLE IF EXISTS `questions`; +DROP TABLE IF EXISTS `quizzes`; +DROP TABLE IF EXISTS `lessons`; +DROP TABLE IF EXISTS `courses`; +DROP TABLE IF EXISTS `subjects`; +DROP TABLE IF EXISTS `teacher_profiles`; +DROP TABLE IF EXISTS `guardian_student`; +DROP TABLE IF EXISTS `users`; +DROP TABLE IF EXISTS `schools`; + -- ------------------------------------------------------------------------------ -- 1. Table: schools (المدارس والجهات الشريكة - B2B مثل الثقافة العسكرية) -- ------------------------------------------------------------------------------ -DROP TABLE IF EXISTS `schools`; CREATE TABLE `schools` ( `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, `uuid` CHAR(36) NOT NULL, @@ -29,7 +47,6 @@ CREATE TABLE `schools` ( -- ------------------------------------------------------------------------------ -- 2. Table: users (المستخدمون الموحدون - طلاب، معلمون، أولياء أمور، إدارة) -- ------------------------------------------------------------------------------ -DROP TABLE IF EXISTS `users`; CREATE TABLE `users` ( `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, `uuid` CHAR(36) NOT NULL, @@ -55,7 +72,6 @@ CREATE TABLE `users` ( -- ------------------------------------------------------------------------------ -- 3. Table: guardian_student (ربط أولياء الأمور بالأبناء - N:M) -- ------------------------------------------------------------------------------ -DROP TABLE IF EXISTS `guardian_student`; CREATE TABLE `guardian_student` ( `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, `guardian_id` BIGINT UNSIGNED NOT NULL, @@ -73,7 +89,6 @@ CREATE TABLE `guardian_student` ( -- ------------------------------------------------------------------------------ -- 4. Table: teacher_profiles (ملفات المعلمين ونسب الأرباح) -- ------------------------------------------------------------------------------ -DROP TABLE IF EXISTS `teacher_profiles`; CREATE TABLE `teacher_profiles` ( `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, `user_id` BIGINT UNSIGNED NOT NULL, @@ -91,7 +106,6 @@ CREATE TABLE `teacher_profiles` ( -- ------------------------------------------------------------------------------ -- 5. Table: subjects (المواد التعليمية) -- ------------------------------------------------------------------------------ -DROP TABLE IF EXISTS `subjects`; CREATE TABLE `subjects` ( `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, `name` VARCHAR(150) NOT NULL, @@ -105,7 +119,6 @@ CREATE TABLE `subjects` ( -- ------------------------------------------------------------------------------ -- 6. Table: courses (الدورات التدريبية) -- ------------------------------------------------------------------------------ -DROP TABLE IF EXISTS `courses`; CREATE TABLE `courses` ( `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, `uuid` CHAR(36) NOT NULL, @@ -130,7 +143,6 @@ CREATE TABLE `courses` ( -- ------------------------------------------------------------------------------ -- 7. Table: lessons (الدروس والفيديوهات المربوطة بـ Bunny Stream) -- ------------------------------------------------------------------------------ -DROP TABLE IF EXISTS `lessons`; CREATE TABLE `lessons` ( `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, `course_id` BIGINT UNSIGNED NOT NULL, @@ -149,7 +161,6 @@ CREATE TABLE `lessons` ( -- ------------------------------------------------------------------------------ -- 8. Table: quizzes (الكويزات داخل الفيديو - Socratic Checkpoints) -- ------------------------------------------------------------------------------ -DROP TABLE IF EXISTS `quizzes`; CREATE TABLE `quizzes` ( `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, `lesson_id` BIGINT UNSIGNED NOT NULL, @@ -166,7 +177,6 @@ CREATE TABLE `quizzes` ( -- ------------------------------------------------------------------------------ -- 9. Table: questions (الأسئلة) -- ------------------------------------------------------------------------------ -DROP TABLE IF EXISTS `questions`; CREATE TABLE `questions` ( `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, `quiz_id` BIGINT UNSIGNED NOT NULL, @@ -182,7 +192,6 @@ CREATE TABLE `questions` ( -- ------------------------------------------------------------------------------ -- 10. Table: question_options (خيارات الإجابة) -- ------------------------------------------------------------------------------ -DROP TABLE IF EXISTS `question_options`; CREATE TABLE `question_options` ( `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, `question_id` BIGINT UNSIGNED NOT NULL, @@ -196,7 +205,6 @@ CREATE TABLE `question_options` ( -- ------------------------------------------------------------------------------ -- 11. Table: lesson_progress (سجل متابعة ونبض المشاهدة) -- ------------------------------------------------------------------------------ -DROP TABLE IF EXISTS `lesson_progress`; CREATE TABLE `lesson_progress` ( `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, `user_id` BIGINT UNSIGNED NOT NULL, @@ -216,7 +224,6 @@ CREATE TABLE `lesson_progress` ( -- ------------------------------------------------------------------------------ -- 12. Table: voice_notes (الملاحظات الصوتية والتفريغ الذكي) -- ------------------------------------------------------------------------------ -DROP TABLE IF EXISTS `voice_notes`; CREATE TABLE `voice_notes` ( `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, `uuid` CHAR(36) NOT NULL, @@ -237,7 +244,6 @@ CREATE TABLE `voice_notes` ( -- ------------------------------------------------------------------------------ -- 13. Table: user_devices (بصمة الأجهزة المربوطة بالجلسات) -- ------------------------------------------------------------------------------ -DROP TABLE IF EXISTS `user_devices`; CREATE TABLE `user_devices` ( `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, `user_id` BIGINT UNSIGNED NOT NULL, @@ -255,7 +261,6 @@ CREATE TABLE `user_devices` ( -- ------------------------------------------------------------------------------ -- 14. Table: otp_verifications (رموز التحقق عبر منصة صقل) -- ------------------------------------------------------------------------------ -DROP TABLE IF EXISTS `otp_verifications`; CREATE TABLE `otp_verifications` ( `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, `phone_hash` VARCHAR(64) NOT NULL, diff --git a/backend/public/migrate.php b/backend/public/migrate.php index 198449c..af09c45 100644 --- a/backend/public/migrate.php +++ b/backend/public/migrate.php @@ -1,17 +1,41 @@ getConnection(); - $sql = file_get_contents(dirname(__DIR__) . '/database_schema.sql'); + // Disable Foreign Key checks explicitly on the active connection + $db->exec("SET FOREIGN_KEY_CHECKS = 0;"); + $sqlFile = dirname(__DIR__) . '/database_schema.sql'; + if (!file_exists($sqlFile)) { + throw new \RuntimeException("Schema file not found at: {$sqlFile}"); + } + + $sql = file_get_contents($sqlFile); + + // Execute SQL schema definition $db->exec($sql); - echo "Database migrations executed successfully!\n"; -} catch (\Exception $e) { - echo "Error executing migrations: " . $e->getMessage() . "\n"; + // Re-enable Foreign Key checks + $db->exec("SET FOREIGN_KEY_CHECKS = 1;"); + + echo json_encode([ + 'status' => 'success', + 'message' => 'تم إنشاء وهيكلة الـ 14 جدولاً بنجاح تام في قاعدة البيانات saqelDB! 🚀' + ], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); +} catch (\Throwable $e) { + http_response_code(500); + echo json_encode([ + 'status' => 'error', + 'error_type' => get_class($e), + 'message' => $e->getMessage(), + 'file' => $e->getFile(), + 'line' => $e->getLine() + ], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); }