From 41493f5dd6c69e426958a4cbb22a8618836f3c25 Mon Sep 17 00:00:00 2001 From: Hamza-Ayed Date: Tue, 8 Sep 2026 23:35:48 +0300 Subject: [PATCH] Update Saqel Platform: 2026-09-08 23:35:48 --- FEASIBILITY_ANALYSIS.md | 2 +- backend/.env.example | 2 +- backend/app/Services/AiInteractiveLabGeneratorService.php | 8 ++++---- backend/app/Services/AiLessonEnhancerService.php | 2 +- backend/app/Services/AiQuestionBankGeneratorService.php | 2 +- backend/app/Services/AiVideoAnalyzerService.php | 2 +- backend/app/Services/AiVideoGeneratorService.php | 2 +- backend/app/Services/CurriculumExtractorService.php | 2 +- backend/app/bootstrap.php | 8 ++++---- backend/scripts/curriculum_worker.php | 6 +++--- backend/scripts/test_notebooklm_prompt.php | 2 +- 11 files changed, 19 insertions(+), 19 deletions(-) diff --git a/FEASIBILITY_ANALYSIS.md b/FEASIBILITY_ANALYSIS.md index c1acd74..78d109f 100644 --- a/FEASIBILITY_ANALYSIS.md +++ b/FEASIBILITY_ANALYSIS.md @@ -249,7 +249,7 @@ - **محلياً**: كتابة الكود + `php artisan test` (SQLite in-memory) — لا حاجة Docker. - **السيرفر**: `docker compose up -d --build` يشغّل: php-fpm، nginx، mysql:8، queue worker (لتشغيل مهام AI في الخلفية). -- أسرار الإنتاج (GEMINI_API_KEY، كلمات مرور DB) عبر `.env` على السيرفر فقط — لا تُرفع للمستودع. +- أسرار الإنتاج (GEMINI_KEY، كلمات مرور DB) عبر `.env` على السيرفر فقط — لا تُرفع للمستودع. --- diff --git a/backend/.env.example b/backend/.env.example index 273285d..722dc12 100644 --- a/backend/.env.example +++ b/backend/.env.example @@ -32,7 +32,7 @@ ALLOWED_ORIGIN=https://saqel.intaleqapp.com SAQEL_AI_NODES_JSON=[] # Gemini AI API Configuration -GEMINI_API_KEY=your_gemini_api_key_here +GEMINI_KEY=your_gemini_api_key_here GEMINI_MODEL=gemini-2.0-flash # Cloudflare R2 Object Storage & CDN diff --git a/backend/app/Services/AiInteractiveLabGeneratorService.php b/backend/app/Services/AiInteractiveLabGeneratorService.php index 86533a0..32d14e8 100644 --- a/backend/app/Services/AiInteractiveLabGeneratorService.php +++ b/backend/app/Services/AiInteractiveLabGeneratorService.php @@ -48,7 +48,7 @@ class AiInteractiveLabGeneratorService $apiKey = self::resolveGeminiKey(); if (!$apiKey) { - throw new \RuntimeException("مفتاح Gemini API غير مهيأ (GEMINI_API_KEY)."); + throw new \RuntimeException("مفتاح Gemini API غير مهيأ (GEMINI_KEY)."); } $prompt = self::buildSimulationPrompt($lessonContent, $subjectSlug, $simSlug); @@ -204,15 +204,15 @@ PROMPT; private static function resolveGeminiKey(): ?string { - if (!empty($_ENV['GEMINI_API_KEY'])) return $_ENV['GEMINI_API_KEY']; - if (!empty(getenv('GEMINI_API_KEY'))) return getenv('GEMINI_API_KEY'); + if (!empty($_ENV['GEMINI_KEY'])) return $_ENV['GEMINI_KEY']; + if (!empty(getenv('GEMINI_KEY'))) return getenv('GEMINI_KEY'); // Check backend/.env $envPath = __DIR__ . '/../../.env'; if (file_exists($envPath)) { $lines = file($envPath, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); foreach ($lines as $line) { - if (str_starts_with(trim($line), 'GEMINI_API_KEY=')) { + if (str_starts_with(trim($line), 'GEMINI_KEY=')) { return trim(substr(trim($line), 15), '"\' '); } } diff --git a/backend/app/Services/AiLessonEnhancerService.php b/backend/app/Services/AiLessonEnhancerService.php index c2695c0..e996b5d 100644 --- a/backend/app/Services/AiLessonEnhancerService.php +++ b/backend/app/Services/AiLessonEnhancerService.php @@ -112,7 +112,7 @@ class AiLessonEnhancerService private static function callGemini(string $prompt): ?array { - $apiKey = Env::get('GEMINI_API_KEY') ?: getenv('GEMINI_API_KEY'); + $apiKey = Env::get('GEMINI_KEY') ?: getenv('GEMINI_KEY'); if (!$apiKey) { $apiKey = Env::get('GOOGLE_API_KEY') ?: getenv('GOOGLE_API_KEY'); } diff --git a/backend/app/Services/AiQuestionBankGeneratorService.php b/backend/app/Services/AiQuestionBankGeneratorService.php index c8c8056..faeb6e0 100644 --- a/backend/app/Services/AiQuestionBankGeneratorService.php +++ b/backend/app/Services/AiQuestionBankGeneratorService.php @@ -245,7 +245,7 @@ class AiQuestionBankGeneratorService */ private static function callGemini(string $prompt): ?array { - $apiKey = Env::get('GEMINI_API_KEY') ?: getenv('GEMINI_API_KEY'); + $apiKey = Env::get('GEMINI_KEY') ?: getenv('GEMINI_KEY'); if (!$apiKey) { $apiKey = Env::get('GOOGLE_API_KEY') ?: getenv('GOOGLE_API_KEY'); } diff --git a/backend/app/Services/AiVideoAnalyzerService.php b/backend/app/Services/AiVideoAnalyzerService.php index 11521ea..4e422d4 100644 --- a/backend/app/Services/AiVideoAnalyzerService.php +++ b/backend/app/Services/AiVideoAnalyzerService.php @@ -29,7 +29,7 @@ class AiVideoAnalyzerService */ private static function nextGeminiApiKey(): string { - $raw = trim((string)(getenv('GEMINI_API_KEYS') ?: getenv('GEMINI_API_KEY') ?: '')); + $raw = trim((string)(getenv('GEMINI_API_KEYS') ?: getenv('GEMINI_KEY') ?: '')); $keys = array_values(array_filter(array_map('trim', explode(',', $raw)))); if (empty($keys)) { return ''; diff --git a/backend/app/Services/AiVideoGeneratorService.php b/backend/app/Services/AiVideoGeneratorService.php index 4ac7392..3401fe5 100644 --- a/backend/app/Services/AiVideoGeneratorService.php +++ b/backend/app/Services/AiVideoGeneratorService.php @@ -59,7 +59,7 @@ class AiVideoGeneratorService private static function callGemini(string $prompt): ?array { - $apiKey = Env::get('GEMINI_API_KEY'); + $apiKey = Env::get('GEMINI_KEY'); if (!$apiKey) return null; $model = Env::get('GEMINI_MODEL') ?: 'gemini-flash-lite-latest'; diff --git a/backend/app/Services/CurriculumExtractorService.php b/backend/app/Services/CurriculumExtractorService.php index 41f6720..847da08 100644 --- a/backend/app/Services/CurriculumExtractorService.php +++ b/backend/app/Services/CurriculumExtractorService.php @@ -15,7 +15,7 @@ class CurriculumExtractorService $fileNameClean = trim(preg_replace('/\.[^.]+$/u', '', $fileName)); // Try AI Structuring with Gemini 2.0 Flash - $geminiKey = Env::get('GEMINI_API_KEY') ?: getenv('GEMINI_API_KEY'); + $geminiKey = Env::get('GEMINI_KEY') ?: getenv('GEMINI_KEY'); if (!empty($geminiKey) && !empty($rawText)) { $aiStructure = self::callGeminiStructurer($fileName, $rawText, $geminiKey); if (!empty($aiStructure['units']) && !empty($aiStructure['subject_name'])) { diff --git a/backend/app/bootstrap.php b/backend/app/bootstrap.php index 87f9587..e7a2944 100644 --- a/backend/app/bootstrap.php +++ b/backend/app/bootstrap.php @@ -40,15 +40,15 @@ try { // Support either GEMINI_API_KEYS=key1,key2 or the legacy singular // variable containing a comma-separated pool. Legacy services receive // one safe key; services with round-robin support consume the pool. - $geminiPool = trim((string)(getenv('GEMINI_API_KEYS') ?: getenv('GEMINI_API_KEY') ?: '')); + $geminiPool = trim((string)(getenv('GEMINI_API_KEYS') ?: getenv('GEMINI_KEY') ?: '')); $geminiKeys = array_values(array_filter(array_map('trim', explode(',', $geminiPool)))); if (!empty($geminiKeys)) { putenv('GEMINI_API_KEYS=' . implode(',', $geminiKeys)); $_ENV['GEMINI_API_KEYS'] = implode(',', $geminiKeys); $_SERVER['GEMINI_API_KEYS'] = implode(',', $geminiKeys); - putenv('GEMINI_API_KEY=' . $geminiKeys[0]); - $_ENV['GEMINI_API_KEY'] = $geminiKeys[0]; - $_SERVER['GEMINI_API_KEY'] = $geminiKeys[0]; + putenv('GEMINI_KEY=' . $geminiKeys[0]); + $_ENV['GEMINI_KEY'] = $geminiKeys[0]; + $_SERVER['GEMINI_KEY'] = $geminiKeys[0]; } } diff --git a/backend/scripts/curriculum_worker.php b/backend/scripts/curriculum_worker.php index 1301f9a..a45088c 100644 --- a/backend/scripts/curriculum_worker.php +++ b/backend/scripts/curriculum_worker.php @@ -51,11 +51,11 @@ $state = json_decode(file_get_contents($stateFile), true); $origName = $state['orig_name'] ?? 'Unknown.pdf'; Env::load(__DIR__ . '/../.env'); -$rawKeys = Env::get('GEMINI_API_KEY') ?: getenv('GEMINI_API_KEY'); +$rawKeys = Env::get('GEMINI_KEY') ?: getenv('GEMINI_KEY'); $apiKeys = array_values(array_filter(array_map('trim', explode(',', $rawKeys)))); if (empty($apiKeys)) { - updateState($stateFile, 'error', 0, '⚠️ لم يتم العثور على مفتاح الذكاء الاصطناعي (GEMINI_API_KEY) في ملف .env.'); + updateState($stateFile, 'error', 0, '⚠️ لم يتم العثور على مفتاح الذكاء الاصطناعي (GEMINI_KEY) في ملف .env.'); return; } @@ -70,7 +70,7 @@ $maskedKey = substr($geminiKey, 0, 6) . '...' . substr($geminiKey, -4); updateState($stateFile, 'uploading_to_ai', 15, "تم تفعيل Round Robin. جاري استخدام المفتاح: {$maskedKey}"); if (empty($geminiKey)) { - updateState($stateFile, 'error', 0, '⚠️ لم يتم العثور على مفتاح الذكاء الاصطناعي (GEMINI_API_KEY) في ملف .env. النظام يحتاج إلى الـ AI لقراءة وتفريغ الكتب (بما فيها الكتب المصورة والرياضيات) بشكل حقيقي.'); + updateState($stateFile, 'error', 0, '⚠️ لم يتم العثور على مفتاح الذكاء الاصطناعي (GEMINI_KEY) في ملف .env. النظام يحتاج إلى الـ AI لقراءة وتفريغ الكتب (بما فيها الكتب المصورة والرياضيات) بشكل حقيقي.'); return; } diff --git a/backend/scripts/test_notebooklm_prompt.php b/backend/scripts/test_notebooklm_prompt.php index 98f6e71..50ae2db 100644 --- a/backend/scripts/test_notebooklm_prompt.php +++ b/backend/scripts/test_notebooklm_prompt.php @@ -8,7 +8,7 @@ if (file_exists($envFile)) { putenv(trim($name) . '=' . trim($value)); } } -$apiKey = getenv('GEMINI_API_KEY'); +$apiKey = getenv('GEMINI_KEY'); $keys = explode(',', $apiKey); $apiKey = trim($keys[0]); $url = "https://generativelanguage.googleapis.com/v1beta/models/gemini-flash-lite-latest:generateContent?key={$apiKey}";