Files
nabeh/implementation_plan.md
2026-05-21 01:58:32 +03:00

17 KiB
Raw Blame History

خطة تنفيذ المعمارية الخلفية ونظام النشر المؤتمت — تطبيق نبيه (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 المقترح:

#!/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)

التحقق الذاتي والمحلي:

  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

  • إرجاع خطأ (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/ محلي (سهل الإعداد ومستقل)، أم نستخدم جدولاً مخصصاً في قاعدة البيانات؟