# خطة تنفيذ المعمارية الخلفية ونظام النشر المؤتمت — تطبيق نبيه (Nabeh)
توضح هذه الخطة التفاصيل الهيكلية والخطوات العملية لبناء النواة البرمجية للخلفية (Backend Base Architecture) باستخدام **Pure PHP OOP** وبناء نظام نشر تلقائي آمن عبر **Git/SSH** إلى السيرفر. --- ## أولاً: تقسيم المشروع إلى مراحل (Milestones) من أجل ضمان الانتقال السلس وبناء أساسات متينة وقابلة للتطوير، سنقسم العمل على الخلفية والنشر إلى المراحل التالية: ### المرحلة 1: بناء نواة الـ MVC وتهيئة الهيكل البرمجي - بناء هيكل المجلدات المنظم وفصل الملفات العامة (Public) عن الكود البرمجي الأساسي. - إعداد نظام التحميل التلقائي للملفات (Autoloader) المتوافق مع معيار PSR-4. - برمجة موجه الطلبات (Router) المتوافق مع خادم Nginx. - برمجة قارئ ملفات البيئة المتطور والآمن (`.env` Reader) مع تخزينه خارج المسار العام لضمان أعلى مستويات الحماية. ### المرحلة 2: تصميم قاعدة البيانات ونواة الاتصال (Database & Core) - تصميم ملف تهيئة الاتصال بقاعدة البيانات باستخدام PDO. - بناء الموديل الرئيسي (Base Model) والمتحكم الرئيسي (Base Controller) لإدارة المدخلات والمخرجات (JSON Responses). - بناء مخطط الجداول الأساسية لقاعدة البيانات (الهيكل متعدد المستأجرين - Multi-Tenant Prep). ### المرحلة 3: نظام النشر التلقائي للسيرفر (`deploy.sh`) - كتابة سكربت النشر الآمن لرفع التحديثات لـ Git وعمل Pull تلقائي وإعادة بناء التهيئات على السيرفر. - إعداد البنية التحتية للمجلدات على السيرفر وربط الـ Subdomain. --- ## ثانياً: معمارية مجلدات الخلفية المقترحة (Directory Structure) سنقوم بتنظيم كود الخلفية داخل مجلد `backend/` لحماية كود التطبيق وملف البيانات الحساسة (`.env`) من الوصول المباشر من المتصفح، حيث سيكون مجلد `public/` هو المجلد الوحيد المتاح للعامة والمربوط بالـ Document Root في Nginx. الهيكل المستهدف للمجلدات هو كالتالي:
``` nabeh/ ├── backend/ │ ├── app/ │ │ ├── Controllers/ # متحكمات معالجة الطلبات │ │ │ ├── BaseController.php │ │ │ └── AuthController.php │ │ ├── Models/ # موديلات قواعد البيانات │ │ │ ├── BaseModel.php │ │ │ └── Tenant.php │ │ ├── Core/ # نواة التطبيق البرمجية │ │ │ ├── Router.php │ │ │ ├── Database.php │ │ │ ├── Request.php │ │ │ ├── Response.php │ │ │ └── Env.php │ │ └── Middlewares/ # فلاتر التحقق والوساطة │ │ └── AuthMiddleware.php │ ├── config/ # ملفات الإعدادات العامة │ │ └── app.php │ ├── public/ # المجلد الوحيد المتاح للمتصفح │ │ └── index.php # نقطة الدخول الموحدة (Front Controller) │ ├── .env # ملف البيئة الحساس (مخفي تماماً) │ ├── .env.example │ └── composer.json # لإدارة التحميل التلقائي PSR-4 وحزم التطبيق ```
--- ## ثالثاً: تصميم النواة البرمجية (Core Architecture) ### 1. نقطة الدخول الموحدة `backend/public/index.php` يقوم هذا الملف بتهيئة بيئة العمل، تحميل الملفات تلقائياً، قراءة متغيرات البيئة، ثم تمرير الطلب إلى الـ Router. ### 2. قارئ البيئة الآمن `backend/app/Core/Env.php` يقرأ ملف `.env` المتواجد خارج المجلد العام ويقوم بتحميل المتغيرات داخل `$_ENV` و `getenv()` بأمان تام. ### 3. نظام توجيه الطلبات `backend/app/Core/Router.php` نظام توجيه خفيف وقوي يدعم تعبيرات Regex، ويتيح تعريف مسارات من نوع GET و POST و PUT و DELETE وتمرير البارامترات للمتحكمات (Controllers) وتطبيق فلاتر الوساطة (Middlewares). --- ## رابعاً: نظام النشر المؤتمت (`deploy.sh`) سنقوم بإنشاء سكربت النشر الذكي في الجذر الرئيسي للمشروع لتبسيط عملية الدفع والتحديث. سيقوم السكربت بالخطوات التالية بشكل تفاعلي وآمن: 1. التأكد من كتابة تعليق الالتزام (Commit Message). 2. إضافة كافة التغييرات محلياً والدفع إلى الفرع الرئيسي على GitHub/GitLab. 3. الاتصال بالسيرفر عبر بروتوكول SSH بشكل آمن. 4. التوجه إلى مجلد المشروع على السيرفر وسحب الكود البرمجي المحدث (`git pull origin main`). 5. تطبيق أي أوامر تهيئة مثل تثبيت حزم الملحقات (`composer install`) أو تنظيف الكاش. محتوى سكربت `deploy.sh` المقترح:
```bash #!/bin/bash # ========================================== # سكريبت النشر الآلي وتحديث السيرفر - تطبيق نبيه # ========================================== # 1. إعدادات السيرفر والمتغيرات الأساسية SERVER_USER="hamza" # اسم مستخدم السيرفر SERVER_IP="your-server-ip" # عنوان السيرفر SERVER_PATH="/var/www/nabeh" # مسار المشروع على السيرفر GIT_BRANCH="main" # الفرع الرئيسي للنشر echo "==========================================" echo "🚀 بدء عملية النشر والتحديث لتطبيق (نبيه)..." echo "==========================================" # 2. التأكد من حالة التغييرات المحلية if [ -z "$(git status --porcelain)" ]; then echo "ℹ️ لا توجد تغييرات برمجية غير محفوظة للنشر." else # طلب وصف للتحديثات (Commit Message) echo "✍️ الرجاء إدخال رسالة الالتزام (Commit Message):" read commit_msg if [ -z "$commit_msg" ]; then commit_msg="Update: Automatic deployment via deploy.sh" fi # الإضافة والالتزام البرمجي git add . git commit -m "$commit_msg" fi # 3. الدفع إلى Git Remote echo "📤 دفع التحديثات إلى المستودع البعيد (Git Push)..." git push origin $GIT_BRANCH if [ $? -ne 0 ]; then echo "❌ فشلت عملية الدفع البرمجي (Git Push). تم إلغاء النشر." exit 1 fi echo "✅ تم رفع الكود بنجاح إلى المستودع البرمجي." # 4. الاتصال بالسيرفر وتحديث الكود (Git Pull) echo "🌐 الاتصال بالسيرفر وسحب الكود المحدث (Git Pull)..." ssh ${SERVER_USER}@${SERVER_IP} << EOF cd ${SERVER_PATH} echo "📁 الانتقال إلى مجلد المشروع: ${SERVER_PATH}" echo "📥 سحب التحديثات من الفرع ${GIT_BRANCH}..." git pull origin ${GIT_BRANCH} if [ -f "backend/composer.json" ]; then echo "📦 تحديث الحزم البرمجية والتحميل التلقائي (Composer)..." cd backend composer install --no-dev --optimize-autoloader cd .. fi echo "🎉 تم تحديث السيرفر وتثبيت التحديثات بنجاح!" EOF echo "==========================================" echo "✨ تمت عملية النشر والتحديث بالكامل بنجاح!" echo "==========================================" ```
--- ## خامساً: خطة إعداد الخادم والـ Subdomain لتشغيل نظام الـ Front Controller والمسارات الديناميكية بشكل متوافق مع **Nginx** وبدون الحاجة لملفات `.htaccess` الخاصة بـ Apache، يجب إعداد ملف تهيئة الـ Subdomain (مثال: `api.nabeh.sa` أو `app.nabeh.sa`) ليوجه الطلبات إلى المجلد العام `backend/public/`: إعداد Nginx المقترح للمخدم:
```nginx server { listen 80; listen [::]:80; server_name api.nabeh.sa; # النطاق الفرعي للتطبيق # تحديد مسار المجلد العام فقط root /var/www/nabeh/backend/public; index index.php index.html; charset utf-8; # توجيه كافة الطلبات إلى index.php لدعم الـ Router location / { try_files $uri $uri/ /index.php?$query_string; } location = /favicon.ico { access_log off; log_not_found off; } location = /robots.txt { access_log off; log_not_found off; } error_page 404 /index.php; # تشغيل ملفات PHP وتكاملها مع PHP-FPM location ~ \.php$ { fastcgi_pass unix:/var/run/php/php8.2-fpm.sock; # حسب إصدار PHP المثبت fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; include fastcgi_params; } # منع الوصول تماماً لأي ملفات حساسة أو مخفية location ~ /\.(?!well-known).* { deny all; } } ```
--- ## سادساً: خطة التحقق والتدقيق (Verification Plan) ### التحقق الذاتي والمحلي: 1. **التحقق من المسارات (Router Testing)**: إنشاء طلبات محلية للتحقق من تشغيل المسارات المختلفة (GET/POST) وإرجاع بيانات JSON صحيحة. 2. **التحقق من حماية متغيرات البيئة (`.env` Security)**: محاولة استعراض ملف `.env` عبر المسار المباشر للتأكد من حظر الوصول العام إليه، وقراءته بنجاح من داخل تطبيق PHP. 3. **فحص التحميل التلقائي**: التحقق من استدعاء كلاسات الـ Controllers والموديلات دون الحاجة لكتابة `require_once` يدوياً لكل ملف. --- ## المرحلة الرابعة: نظام التوثيق والمصادقة (Authentication Phase) بناءً على النواة الأمنية التي تم تجهيزها (JWT, AES-256-GCM, Bcrypt, HMAC Blind Index)، سنقوم ببناء نظام المصادقة ليكون جاهزاً لإدارة جلسات المستخدمين. ### Proposed Changes #### [NEW] `backend/app/Models/User.php` - كلاس يمتد من `BaseModel` لإدارة جدول `users`. - يحتوي على دالة `findByEmail` التي تقوم بتوليد (Blind Index HMAC) للبريد الإلكتروني للبحث السريع في قاعدة البيانات دون فك التشفير. - دالة `createSecure` لإنشاء مستخدم جديد مع تشفير بريده الإلكتروني وكلمة مروره. #### [NEW] `backend/app/Controllers/AuthController.php` - دالة `login`: تستقبل البريد الإلكتروني وكلمة المرور، تتحقق منها عبر الموديل، وتولد JWT Token. - دالة `register` (اختيارية كأداة تطوير مبدئية أو للأدمن): إنشاء حساب موظف جديد. - دالة `me`: جلب بيانات المستخدم الحالي باستخدام الـ `AuthMiddleware` لاختبار سلامة الجلسة. #### [MODIFY] `backend/public/index.php` - إضافة المسارات الخاصة بنظام التوثيق: - `POST /api/auth/login` - `GET /api/auth/me` (مرفق بـ `AuthMiddleware`) ### User Review Required > [!IMPORTANT] > - هل ترغب بإنشاء مسار `POST /api/auth/register` مفتوح للجميع لإنشاء حسابات شركات جديدة؟ أم نكتفي حالياً بإنشاء مستخدم مدير (Admin) افتراضي يدوياً أو عبر سكربت ليكون النظام مغلقاً للشركات المعتمدة فقط؟ > - في عملية تسجيل الدخول، هل نحتاج لإرجاع بيانات الشركة المرتبطة بالمستخدم ضمن نفس الـ Response، أم نكتفي بإرجاع التوكن (Token) وبيانات المستخدم الأساسية فقط؟ --- ## المرحلة الخامسة: معالجة وإصلاح الثغرات الأمنية (Security Audit Remediation) بناءً على التقرير الأمني الصادر، سنقوم بتطبيق التعديلات البرمجية لرفع مستوى أمان الخادم وحماية البيانات. ### Proposed Changes #### [MODIFY] [Security.php](file:///Users/hamzaaleghwairyeen/development/App/nabeh/backend/app/Core/Security.php) - إرجاع خطأ (Exception) فوراً في حال عدم وجود متغيرات البيئة (`ENCRYPTION_KEY`, `HMAC_SALT`, `JWT_SECRET`) لمنع تشفير البيانات بمفاتيح فارغة. #### [MODIFY] [BaseModel.php](file:///Users/hamzaaleghwairyeen/development/App/nabeh/backend/app/Models/BaseModel.php) - تنظيف وفلترة أسماء الأعمدة ديناميكياً باستخدام مصفوفة بيضاء (Whitelist Regex) لمنع ثغرات الـ SQL Injection عبر أسماء الأعمدة في دالتي `create()` و `update()`. #### [MODIFY] [SecurityMiddleware.php](file:///Users/hamzaaleghwairyeen/development/App/nabeh/backend/app/Middlewares/SecurityMiddleware.php) - إلغاء تطبيق `htmlspecialchars` و `strip_tags` على المدخلات الخام القادمة للخلفية لمنع تلف كلمات المرور والرموز الخاصة، وتأجيل التنظيف ليكون حصراً عند الطباعة/العرض (Output Encoding). #### [MODIFY] [AuthController.php](file:///Users/hamzaaleghwairyeen/development/App/nabeh/backend/app/Controllers/AuthController.php) - إزالة التنظيف المزدوج (Double Encoding) لأسماء المستخدمين والشركات. #### [MODIFY] [Router.php](file:///Users/hamzaaleghwairyeen/development/App/nabeh/backend/app/Core/Router.php) - إخفاء مسار الملفات الحقيقي من رسائل الخطأ 404 و 500 وإظهار رسائل عامة لمنع تسريب بنية المجلدات (Information Disclosure). #### [MODIFY] [Response.php](file:///Users/hamzaaleghwairyeen/development/App/nabeh/backend/app/Core/Response.php) - جعل رابط الـ CORS ديناميكياً يعتمد على متغير بيئة `ALLOWED_ORIGIN` بدلاً من فتح النطاق للجميع عبر `*`. #### [MODIFY] [bootstrap.php](file:///Users/hamzaaleghwairyeen/development/App/nabeh/backend/app/bootstrap.php) - تسجيل معالج أخطاء عام (`set_exception_handler` / `set_error_handler`) لتحويل الأخطاء الفادحة غير المعالجة إلى استجابات JSON نظيفة ومخفية في الإنتاج، مع تسجيل التفاصيل التقنية في الـ `error_log` فقط. #### [MODIFY] [Request.php](file:///Users/hamzaaleghwairyeen/development/App/nabeh/backend/app/Core/Request.php) - تعريف الخصائص المعرفية (`$user_id`, `$company_id`, `$role`) بشكل صريح لتفادي مشاكل الخصائص الديناميكية (Dynamic Properties Deprecation) في إصدارات PHP 8.2+. #### [NEW] [RateLimitMiddleware.php](file:///Users/hamzaaleghwairyeen/development/App/nabeh/backend/app/Middlewares/RateLimitMiddleware.php) - بناء فلتر مخصص للحد من معدل الطلبات (Rate Limiting) على مسارات تسجيل الدخول والتسجيل لحماية التطبيق من محاولات التخمين العنيف (Brute Force). #### [MODIFY] [index.php](file:///Users/hamzaaleghwairyeen/development/App/nabeh/backend/public/index.php) - تفعيل فلتر الحد من معدل الطلبات على مسارات الحماية. ### User Review Required > [!IMPORTANT] > هل نعتمد نظام تخزين المحاولات للحد من معدل الطلبات (Rate Limiting) في ملفات مؤقتة داخل مجلد `storage/` محلي (سهل الإعداد ومستقل)، أم نستخدم جدولاً مخصصاً في قاعدة البيانات؟