B2B SaaS System منصة عربية لتحويل ملفات CSV وXLS وXLSX إلى تقارير قابلة للقراءة، مع استكشاف للبيانات الخام، وتصفية، وتنظيف آمن على دفعات، وتصدير غير متزامن، ومستشار ذكي مرتبط بسياق التقرير. تعتمد المنصة على واجهة React منفصلة وخدمة Laravel API، لذلك يمكن تشغيلهما وتحديثهما بصورة مستقلة. 1 2
آخر تحديث للوثائق: 27 أغسطس 2026. يصف هذا الدليل النسخة التي تستخدم عمليات تنظيف وتصدير محفوظة في قاعدة البيانات، وتحديثاً دورياً للحالة من API مع دعم أحداث Pusher الاختيارية.
| الطبقة | التقنية | المسؤولية |
|---|---|---|
| الواجهة | React 19 وReact Router وTailwind وLaravel Echo | المصادقة، الصفحات، عرض البيانات، وحالة العمليات. 3 |
| API | Laravel 12 وSanctum | عزل الموارد حسب المستخدم، التحقق، وإتاحة نقاط النهاية. 1 |
| الأعمال الخلفية | Laravel Database Queue | استيراد الملفات، التنظيف على دفعات، وإنشاء ملفات التصدير. 4 5 |
| قاعدة البيانات | MySQL على XAMPP أو أي اتصال Laravel مدعوم | حفظ المستندات والصفوف والتقارير وحالة العمليات. 6 |
| البث الفوري | Pusher وLaravel Echo | إشعار الواجهة عند اكتمال العمليات؛ لا تعتمد الواجهة عليه وحده. 7 8 |
| المجال | التحديث |
|---|---|
| التنظيف | عملية محفوظة ذات معرّف UUID، ولقطة استعادة قبل التعديل، ودفعات حجمها 250 سجلًا، واستئناف من آخر دفعة مكتملة عند الفشل. 4 |
| التصدير | سجل تصدير محفوظ، وحالة قابلة للمتابعة، وتنزيل محمي بملكية المستخدم، وصلاحية افتراضية للملف تبلغ 24 ساعة بعد إنشائه. 5 9 |
| الواجهة | شرائط حالة مدمجة لا تحجب جدول البيانات، مع حساب تقدم التنظيف من عدد السجلات الفعلية، وتحديث الحالة عبر polling كل 1.5 ثانية. 3 |
| الاستجابة | يصبح الشريط الجانبي ثابتًا من عرض xl فما فوق؛ وتستخدم العروض المتوسطة قائمة جانبية حتى تبقى مساحة الجدول كافية. 10 |
| الاختبارات | اختبارات تغطي عقد البث، والعمليات المتواصلة، والتنزيل المصرح به، وتكوين المستشار الذكي. 11 |
flowchart LR
U[المستخدم] --> FE[React SPA]
FE -->|Bearer Token| API[Laravel API]
API --> DB[(MySQL)]
API --> Q1[عامل default]
API --> Q2[عامل cleaning]
Q1 --> I[استيراد / تصدير]
Q2 --> C[لقطة ثم تنظيف على دفعات]
API --> P[Pusher اختياري]
P --> FE
بعد رفع الملف، ترسل الخدمة مهمة معالجة خلفية. وفي تبويب البيانات الخام يمكن للمستخدم إرسال طلب تنظيف أو تصدير؛ يعيد API حالة مقبولة فورًا، ثم تستمر الواجهة في عرض الجدول ومتابعة حالة العملية من API. يساعد Pusher على تسريع الإشعار، لكنه ليس شرطًا لبقاء رابط التصدير أو تقدم التنظيف ظاهرين. 3 4 5
يلزم XAMPP مع Apache وMySQL، وPHP 8.2 أو أحدث، وComposer، وNode.js مع npm. تتضمن تبعيات الخادم حزمة Pusher PHP، وتتضمن الواجهة pusher-js وLaravel Echo. 12 13
شغّل Apache وMySQL من XAMPP Control Panel. افتح http://localhost/phpmyadmin، ثم أنشئ قاعدة بيانات جديدة باسم b2b_saas بترميز utf8mb4 وCollation مثل utf8mb4_unicode_ci.
لا تستخدم
php artisan migrate:freshعلى قاعدة MySQL التي تحتوي بيانات مهمة؛ أمر الترحيل العادي يحافظ على البيانات الموجودة ويضيف الجداول أو التعديلات الجديدة فقط.
من جذر المشروع في PowerShell، أنشئ ملف البيئة إن لم يكن موجودًا، ثم اضبط اتصال MySQL:
Copy-Item .env.example .env
composer install
php artisan key:generateضع القيم التالية في ملف .env المحلي. غيّر اسم قاعدة البيانات أو بيانات المستخدم إن كانت إعدادات XAMPP لديك مختلفة:
APP_ENV=local
APP_DEBUG=true
APP_URL=http://127.0.0.1:8000
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=b2b_saas
DB_USERNAME=root
DB_PASSWORD=
QUEUE_CONNECTION=database
DB_QUEUE_CONNECTION=mysql
DB_QUEUE_TABLE=jobs
DB_QUEUE=default
DB_QUEUE_RETRY_AFTER=660
CLEANING_QUEUE=cleaning
CLEANING_QUEUE_RETRY_AFTER=120
BROADCAST_CONNECTION=logبعد تعديل البيئة، امسح الإعدادات المخزنة ثم نفّذ الترحيلات. تتضمن الترحيلات الجديدة جداول عمليات التنظيف والتصدير، إضافة إلى جدول الوظائف الذي يستخدمه الطابور. 6 14
php artisan optimize:clear
php artisan migrate
php artisan serveاترك خادم Laravel يعمل في هذه النافذة على http://127.0.0.1:8000.
افتح نافذتي PowerShell جديدتين من جذر المشروع. العامل الأول يعالج الاستيراد والتصدير والمهام الافتراضية؛ العامل الثاني يعالج دفعات التنظيف فقط. هذا الفصل يمنع تنظيف ملف كبير من تأخير التصديرات أو أعمال الاستيراد.
# النافذة الأولى: الاستيراد والتصدير والمهام الافتراضية
php artisan queue:work database --queue=default --tries=3 --timeout=600 --sleep=1# النافذة الثانية: دفعات التنظيف المعزولة
php artisan queue:work cleaning --queue=cleaning --tries=3 --timeout=90 --sleep=1تعمل دفعة التنظيف ضمن حد 90 ثانية، مع ثلاث محاولات وفواصل تصاعدية. كما أن CLEANING_QUEUE_RETRY_AFTER=120 أكبر من مهلة الدفعة، وهو أمر ضروري حتى لا تلتقط عاملة أخرى الدفعة نفسها قبل انتهاء العاملة الأولى. 4 15
| العرض في الواجهة | ما يجب التحقق منه |
|---|---|
ملف عالق في queued |
وجود عامل default أو cleaning المناسب قيد التشغيل. |
| تنظيف متوقف | راجع العامل الثاني وstorage/logs/laravel.log، ثم استخدم استئناف من الواجهة إن ظهرت العملية بحالة فشل. |
| تصدير لم يكتمل | راجع العامل الأول؛ لا تعِد إرسال التصدير بينما حالته queued أو processing. |
| وظائف فاشلة | نفّذ php artisan queue:failed لمشاهدة الوظائف المسجلة. |
من مجلد frontend، أنشئ ملف frontend/.env.local محليًا إذا لم يكن لديك إعداد محلي، ولا ترفعه إلى Git:
REACT_APP_API_BASE_URL=http://127.0.0.1:8000/apiثم شغّل الواجهة:
cd frontend
npm ci --legacy-peer-deps
npm startتقرأ الواجهة REACT_APP_API_BASE_URL، وإلا ستستخدم /api. عند تشغيل React على المنفذ 3000 وLaravel على 8000، عيّن المتغير السابق لتجنب إرسال طلبات API إلى خادم React بالخطأ. 16
لا يلزم Pusher لتشغيل العمليات نفسها؛ فالواجهة تقرأ حالة التنظيف والتصدير من API بصورة دورية. فعّل Pusher إذا أردت أن تصل إشعارات الإكمال فورًا بدلاً من انتظار دورة المتابعة التالية. 3 7
أنشئ تطبيق Channels من لوحة Pusher، ثم انسخ قيم App ID وKey وSecret وCluster. هذه أسرار تشغيلية؛ احتفظ بها في .env فقط ولا تضعها في المستودع أو لقطات الشاشة أو سجلات المتصفح.
استبدل قيم Pusher في ملف .env المحلي فقط:
BROADCAST_CONNECTION=pusher
PUSHER_APP_ID=your-app-id
PUSHER_APP_KEY=your-app-key
PUSHER_APP_SECRET=your-app-secret
PUSHER_APP_CLUSTER=mt1
PUSHER_SCHEME=https
PUSHER_PORT=443تقرأ Laravel هذه القيم من config/broadcasting.php. أبقِ PUSHER_HOST فارغًا عند استخدام خدمة Pusher المستضافة؛ لا تضبطه إلا إذا كنت تستخدم مضيف WebSocket مخصصًا. 7
أضف المفتاح العام والـ cluster فقط؛ لا تضع PUSHER_APP_SECRET في الواجهة:
REACT_APP_API_BASE_URL=http://127.0.0.1:8000/api
REACT_APP_PUSHER_KEY=your-app-key
REACT_APP_PUSHER_CLUSTER=mt1
REACT_APP_PUSHER_FORCE_TLS=true
# اختياري فقط عند استخدام مضيف WebSocket مخصص
# REACT_APP_PUSHER_HOST=ws.example.test
# REACT_APP_PUSHER_PORT=443تنشئ الواجهة اتصال Echo فقط عندما يتوفر رمز Sanctum والمفتاح والـ cluster. يرسل Echo طلب تفويض القناة إلى POST /api/broadcasting/auth باستخدام رمز المستخدم الحالي. 8 17
بعد تغيير .env الخلفي، نفّذ:
php artisan optimize:clearأعد تشغيل خادم Laravel وعاملي الطابور. وبعد تغيير ملف بيئة React، أوقف npm start ثم شغّله من جديد لأن Create React App يقرأ المتغيرات عند البدء. عند نجاح التكوين، يفوض الخادم القناة الخاصة private-user.{id} للمستخدم المالك فقط، وقد تصل أحداث export.completed وcleansing.completed وcleansing.failed. 17 18
كل المسارات التالية محمية بـSanctum وترفض الوصول إلى ورقة لا يملكها المستخدم. 1
| الغرض | الطريقة والمسار |
|---|---|
| بدء التنظيف | POST /api/sheets/{sheetId}/cleanse |
| آخر عملية تنظيف | GET /api/sheets/{sheetId}/cleanse-operation |
| قراءة عملية تنظيف | GET /api/sheets/{sheetId}/cleanse-operations/{operationUuid} |
| استئناف تنظيف فاشل | POST /api/sheets/{sheetId}/cleanse-operations/{operationUuid}/resume |
| طلب تصدير | POST /api/sheets/{sheetId}/export |
| آخر تصدير | GET /api/sheets/{sheetId}/exports/latest |
| قراءة حالة تصدير | GET /api/sheets/{sheetId}/exports/{exportUuid} |
| تنزيل التصدير المكتمل | GET /api/sheets/{sheetId}/exports/{exportUuid}/download |
راجع الدليل التقني للتفاصيل التشغيلية، ومرجع API للحمولات وحالات الاستجابة، ودليل الاستخدام لرحلة المستخدم.
نفّذ اختبارًا صغيرًا بهذه الترتيب: سجّل الدخول، ارفع ملفًا بسيطًا، راقب أن يعالجه عامل default، افتح التقرير، ثم ابدأ تنظيفًا وتأكد من ظهور تقدم متزايد في شريط الحالة المدمج. بعدها اطلب تصديرًا، وانتظر الحالة completed، ثم نزّل الملف عبر زر التنزيل. اختبر Pusher بشكل منفصل: حتى إن لم يظهر حدث لحظي، يجب أن تتغير الحالة عبر المتابعة الدورية ما دام API والعمال يعملون.
لا ترفع .env أو database/database.sqlite أو bootstrap/cache إلى Git. استخدم حساب قاعدة بيانات محدود الصلاحيات في الإنتاج، وأبقِ مفاتيح Pusher ومزود الذكاء الاصطناعي في مدير أسرار. لا تعرض تواقيع المصادقة أو ترويسات Authorization أو أخطاء الخادم التفصيلية في الواجهة. تظل متابعة العمليات وملكية التنزيل محمية في API، ولا ينبغي تجاوز طبقة Sanctum عند إضافة أي مسار جديد. 1 9