17 KiB
خطة تنفيذ المعمارية الخلفية ونظام النشر المؤتمت — تطبيق نبيه (Nabeh)
توضح هذه الخطة التفاصيل الهيكلية والخطوات العملية لبناء النواة البرمجية للخلفية (Backend Base Architecture) باستخدام Pure PHP OOP وبناء نظام نشر تلقائي آمن عبر Git/SSH إلى السيرفر.
أولاً: تقسيم المشروع إلى مراحل (Milestones)
من أجل ضمان الانتقال السلس وبناء أساسات متينة وقابلة للتطوير، سنقسم العمل على الخلفية والنشر إلى المراحل التالية:
المرحلة 1: بناء نواة الـ MVC وتهيئة الهيكل البرمجي
- بناء هيكل المجلدات المنظم وفصل الملفات العامة (Public) عن الكود البرمجي الأساسي.
- إعداد نظام التحميل التلقائي للملفات (Autoloader) المتوافق مع معيار PSR-4.
- برمجة موجه الطلبات (Router) المتوافق مع خادم Nginx.
- برمجة قارئ ملفات البيئة المتطور والآمن (
.envReader) مع تخزينه خارج المسار العام لضمان أعلى مستويات الحماية.
المرحلة 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)
سنقوم بإنشاء سكربت النشر الذكي في الجذر الرئيسي للمشروع لتبسيط عملية الدفع والتحديث. سيقوم السكربت بالخطوات التالية بشكل تفاعلي وآمن:
- التأكد من كتابة تعليق الالتزام (Commit Message).
- إضافة كافة التغييرات محلياً والدفع إلى الفرع الرئيسي على GitHub/GitLab.
- الاتصال بالسيرفر عبر بروتوكول SSH بشكل آمن.
- التوجه إلى مجلد المشروع على السيرفر وسحب الكود البرمجي المحدث (
git pull origin main). - تطبيق أي أوامر تهيئة مثل تثبيت حزم الملحقات (
composer install) أو تنظيف الكاش.
محتوى سكربت deploy.sh المقترح:
#!/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 المقترح للمخدم:
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)
التحقق الذاتي والمحلي:
- التحقق من المسارات (Router Testing): إنشاء طلبات محلية للتحقق من تشغيل المسارات المختلفة (GET/POST) وإرجاع بيانات JSON صحيحة.
- التحقق من حماية متغيرات البيئة (
.envSecurity): محاولة استعراض ملف.envعبر المسار المباشر للتأكد من حظر الوصول العام إليه، وقراءته بنجاح من داخل تطبيق PHP. - فحص التحميل التلقائي: التحقق من استدعاء كلاسات الـ 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/loginGET /api/auth/me(مرفق بـAuthMiddleware)
User Review Required
Important
- هل ترغب بإنشاء مسار
POST /api/auth/registerمفتوح للجميع لإنشاء حسابات شركات جديدة؟ أم نكتفي حالياً بإنشاء مستخدم مدير (Admin) افتراضي يدوياً أو عبر سكربت ليكون النظام مغلقاً للشركات المعتمدة فقط؟- في عملية تسجيل الدخول، هل نحتاج لإرجاع بيانات الشركة المرتبطة بالمستخدم ضمن نفس الـ Response، أم نكتفي بإرجاع التوكن (Token) وبيانات المستخدم الأساسية فقط؟
المرحلة الخامسة: معالجة وإصلاح الثغرات الأمنية (Security Audit Remediation)
بناءً على التقرير الأمني الصادر، سنقوم بتطبيق التعديلات البرمجية لرفع مستوى أمان الخادم وحماية البيانات.
Proposed Changes
[MODIFY] Security.php
- إرجاع خطأ (Exception) فوراً في حال عدم وجود متغيرات البيئة (
ENCRYPTION_KEY,HMAC_SALT,JWT_SECRET) لمنع تشفير البيانات بمفاتيح فارغة.
[MODIFY] BaseModel.php
- تنظيف وفلترة أسماء الأعمدة ديناميكياً باستخدام مصفوفة بيضاء (Whitelist Regex) لمنع ثغرات الـ SQL Injection عبر أسماء الأعمدة في دالتي
create()وupdate().
[MODIFY] SecurityMiddleware.php
- إلغاء تطبيق
htmlspecialcharsوstrip_tagsعلى المدخلات الخام القادمة للخلفية لمنع تلف كلمات المرور والرموز الخاصة، وتأجيل التنظيف ليكون حصراً عند الطباعة/العرض (Output Encoding).
[MODIFY] AuthController.php
- إزالة التنظيف المزدوج (Double Encoding) لأسماء المستخدمين والشركات.
[MODIFY] Router.php
- إخفاء مسار الملفات الحقيقي من رسائل الخطأ 404 و 500 وإظهار رسائل عامة لمنع تسريب بنية المجلدات (Information Disclosure).
[MODIFY] Response.php
- جعل رابط الـ CORS ديناميكياً يعتمد على متغير بيئة
ALLOWED_ORIGINبدلاً من فتح النطاق للجميع عبر*.
[MODIFY] bootstrap.php
- تسجيل معالج أخطاء عام (
set_exception_handler/set_error_handler) لتحويل الأخطاء الفادحة غير المعالجة إلى استجابات JSON نظيفة ومخفية في الإنتاج، مع تسجيل التفاصيل التقنية في الـerror_logفقط.
[MODIFY] Request.php
- تعريف الخصائص المعرفية (
$user_id,$company_id,$role) بشكل صريح لتفادي مشاكل الخصائص الديناميكية (Dynamic Properties Deprecation) في إصدارات PHP 8.2+.
[NEW] RateLimitMiddleware.php
- بناء فلتر مخصص للحد من معدل الطلبات (Rate Limiting) على مسارات تسجيل الدخول والتسجيل لحماية التطبيق من محاولات التخمين العنيف (Brute Force).
[MODIFY] index.php
- تفعيل فلتر الحد من معدل الطلبات على مسارات الحماية.
User Review Required
Important
هل نعتمد نظام تخزين المحاولات للحد من معدل الطلبات (Rate Limiting) في ملفات مؤقتة داخل مجلد
storage/محلي (سهل الإعداد ومستقل)، أم نستخدم جدولاً مخصصاً في قاعدة البيانات؟