235 lines
12 KiB
Markdown
235 lines
12 KiB
Markdown
# خطة تنفيذ المعمارية الخلفية ونظام النشر المؤتمت — تطبيق نبيه (Nabeh)
|
||
|
||
<div dir="rtl" align="right">
|
||
|
||
توضح هذه الخطة التفاصيل الهيكلية والخطوات العملية لبناء النواة البرمجية للخلفية (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.
|
||
|
||
الهيكل المستهدف للمجلدات هو كالتالي:
|
||
|
||
</div>
|
||
|
||
```
|
||
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 وحزم التطبيق
|
||
```
|
||
|
||
<div dir="rtl" align="right">
|
||
|
||
---
|
||
|
||
## ثالثاً: تصميم النواة البرمجية (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` المقترح:
|
||
|
||
</div>
|
||
|
||
```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 "=========================================="
|
||
```
|
||
|
||
<div dir="rtl" align="right">
|
||
|
||
---
|
||
|
||
## خامساً: خطة إعداد الخادم والـ Subdomain
|
||
|
||
لتشغيل نظام الـ Front Controller والمسارات الديناميكية بشكل متوافق مع **Nginx** وبدون الحاجة لملفات `.htaccess` الخاصة بـ Apache، يجب إعداد ملف تهيئة الـ Subdomain (مثال: `api.nabeh.sa` أو `app.nabeh.sa`) ليوجه الطلبات إلى المجلد العام `backend/public/`:
|
||
|
||
إعداد Nginx المقترح للمخدم:
|
||
|
||
</div>
|
||
|
||
```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;
|
||
}
|
||
}
|
||
```
|
||
|
||
<div dir="rtl" align="right">
|
||
|
||
---
|
||
|
||
## سادساً: خطة التحقق والتدقيق (Verification Plan)
|
||
|
||
### التحقق الذاتي والمحلي:
|
||
1. **التحقق من المسارات (Router Testing)**: إنشاء طلبات محلية للتحقق من تشغيل المسارات المختلفة (GET/POST) وإرجاع بيانات JSON صحيحة.
|
||
2. **التحقق من حماية متغيرات البيئة (`.env` Security)**: محاولة استعراض ملف `.env` عبر المسار المباشر للتأكد من حظر الوصول العام إليه، وقراءته بنجاح من داخل تطبيق PHP.
|
||
3. **فحص التحميل التلقائي**: التحقق من استدعاء كلاسات الـ Controllers والموديلات دون الحاجة لكتابة `require_once` يدوياً لكل ملف.
|
||
|
||
---
|
||
|
||
## أسئلة للنقاش والمراجعة البرمجية
|
||
|
||
> [!NOTE]
|
||
> 1. **عنوان خادم الـ SSH والمسار**: هل تود ملء بيانات السيرفر الخاصة بك (اسم المستخدم، عنوان IP، المسار) مباشرة داخل ملف `deploy.sh` لتسهيل الاستخدام الفوري، أم نضعها كمتغيرات في ملف `.env` على أن يقرأها السكريبت؟
|
||
> 2. **النطاق الفرعي (Subdomain)**: ما هو الاسم المقترح للنطاق الفرعي لـ Backend؟ (مثال: `api.nabeh.sa` أو `core.nabeh.sa`)؟
|
||
> 3. **إصدار PHP على السيرفر**: ما هو إصدار PHP المفعل على خادم Nginx الحالي لديك للتأكد من تطابق التهيئة ودعم الـ Socket الصحيح؟
|
||
|
||
</div>
|