الوثائق / v1

من أول طلب
إلى النشر في الإنتاج.

ابدأ بتثبيت محلي، واربط المدفوعات والخدمات الخارجية، وانشر على بنيتك التحتية، وحافظ على تحديث المنصة. تتضمن أدلة المبتدئين النقرات على لوحة تحكم كل مزوّد، وليس متغيرات البيئة فقط.

27 دليلًا 6 مسارات AR المصدر
ابدأ من هناقراءة 8 دقائق

نظرة عامة على المنصة

FastRestful منصة منتجات API موجهة للإنتاج. تجمع سوقًا عامًا وإصدارات API مُصدّرة وبوابة محدودة الاستخدام واشتراكات وفوترة ووثائق ووحدة تحكم للمستهلك واستوديو للمورّد ومستوى تحكم للموظفين في نظام واحد مبني على Django + الواجهة الأمامية.

جديد هنا؟ اتبع مسار المبتدئين: ثبّت محليًا، ثم أرسل أول طلب عبر البوابة. اتصل المدفوعات فقط عندما تريد تحصيل الأموال، واقرأ النشر قبل الإطلاق العلني.

ما هو FastRestful

FastRestful ليس API واحدة. إنه البنية التحتية للمنتجات حول واجهات API: واجهة المتجر، وحدود العقد، ومسار الطلب، والمال، والمحتوى، والعمليات. يمكن لفريق تشغيل API واحدة أو سوق متعدد المورّدين من التثبيت نفسه.

الواجهةمن يستخدمهاما تملكه
الموقع العامالزوار والمشترونالسوق وصفحات تفاصيل API والوثائق والأسعار والمدونة والحالة وملفات المورّدين والصفحات القانونية.
لوحة المستهلكمشتركو APIالتطبيقات والمفاتيح والاشتراكات والمستكشف والطلبات والتحليلات والفواتير والفريق والدعم.
استوديو المورّدناشرو APIالمنتجات والإصدارات ونقاط النهاية والخطط والمستهلكون وتحقيق الدخل والدفعات والبوابة والدعم.
مستوى تحكم الموظفينمشغلو المنصةحركة المرور والمورّدون والفوترة والدفعات والدعم والإشراف و CMS والإعلانات واللغات والتدقيق.

أوضاع المورّد الواحد وتعدد المورّدين

تبدأ المنصة في وضع المورّد الواحد. لا يمكن إلا للمؤسسة المحددة كمورّد المنصة نشر واجهات API عامة. يمكن للمستخدم الخارق تفعيل وضع تعدد المورّدين في إعدادات الموقع، وبعد ذلك يمكن لأي مؤسسة لديها ملف مورّد معتمد أن تنشر.

  • مورّد واحد: نشاط API واحد منسق، ومورّد منصة واحد، وحوكمة أبسط.
  • تعدد المورّدين: سوق على نمط RapidAPI حيث يدرج المورّدون المستقلون واجهات API الخاصة بهم ويسعّرونها ويدعمونها.
  • يُفرض التبديل على مستوى النموذج، لذا تتوافق API والإدارة واستوديو المورّد.
  • تبقى تهيئة المورّدين ومراجعة الملفات وفصل المهام نشطة في الوضعين.

البنية في لمحة

مسار الطلب
Browser / SDK
   │
   ├── public site + consoles ──► Django REST API ──► PostgreSQL
   │                                  │
   │                                  ├── Redis (cache, throttles, Celery)
   │                                  ├── S3 / CloudFront (media, specs)
   │                                  └── provider webhooks (payments, payouts)
   │
   └── API product request ──► metered gateway ──► vendor upstream
                                  │
                                  ├── API key + subscription
                                  ├── quota + rate limit + entitlement
                                  ├── SSRF checks + idempotency + retries
                                  └── usage event + redacted request log

المكدس التقني

الطبقةالتقنية
الواجهة الخلفيةDjango 5.1+, Django REST Framework, SimpleJWT, drf-spectacular, Celery
الواجهة الأماميةReact 19, Next-compatible app router, Vite, TypeScript, Tailwind/shadcn primitives
قاعدة البياناتSQLite للتطوير المحلي؛ PostgreSQL 16 في الإنتاج
التخزين المؤقت / قائمة الانتظارLocMem محليًا؛ Redis في الإنتاج؛ عامل Celery + beat للأعمال المجدولة
التخزيننظام الملفات المحلي افتراضيًا؛ يُوصى بـ S3 + CloudFront في الإنتاج
المدفوعاتStripe, PayPal, Flutterwave, Paystack, Razorpay
البريد الإلكترونيSMTP وSES وMailgun وSendGrid وPostmark وBrevo وMailjet وSparkPost وResend

مبادئ المنتج

  • عزل المستأجرين من جانب الخادم. مساحة العمل النشطة صريحة، ويُعاد التحقق من أذونات الكائنات، والمُسلسِلات العامة منفصلة عن الخاصة.
  • الإصدارات غير قابلة للتغيير. لا يمكن تعديل عقد مباشر في مكانه؛ أنشئ إصدارًا جديدًا ورقّه.
  • حقيقة المزوّد هي الفاصل. إنشاء عملية الدفع لا يمنح الاستحقاق أبدًا؛ تُسوّي webhooks المزوّد الموقعة حالة الأموال.
  • المفاتيح أسرار. تُعرض مفاتيح API الخام مرة واحدة، وتُجزّأ للبحث، وتُشفّر لاستخدام البوابة من جانب الخادم.
  • العمليات تترك دليلًا. أحداث التدقيق وإيصالات webhook وسجلات الطلبات وقرارات الإشراف للإضافة فقط حيث يهم ذلك.
  • نظام تصميم واحد. رموز Signal Grid والأسطح الدلالية والبيانات الوصفية أحادية العرض والحالات التي يمكن الوصول إليها عبر كل سطح.

إلى أين تذهب بعد ذلك

اختر المسار الذي يناسب ما تقوم به. لا تحتاج إلى قراءة مجموعة الوثائق كاملة بالترتيب.

أريد أن…اقرأ هذه الأدلة بالترتيب
شاهده يعمل محليًاالتثبيت → البدء السريع
حصّل المدفوعات من العملاءبوابات الدفع → الفوترة والدفعات
اربط البريد الإلكتروني أو التخزين أو SSOالتكاملات الخارجية
ضعه على خادم عامالنشر → الأمان → النسخ الاحتياطي والترقيات
ثبّت التحديثات الرسميةالترخيص والتحديثات الرسمية
شغّل المنصة يومًا بيومالعمليات → الرصد → استكشاف الأخطاء وإصلاحها

تقيّم المنتج؟ اقرأ جرد الميزات. تبحث عن endpoint محدد؟ استخدم مرجع API.

ابدأ من هناقراءة 10 دقائق

ثبّت FastRestful على حاسوبك

تثبيت أول كامل لمن لم يشغّل تطبيق Django أو Node من قبل. اتبع الخطوات بالترتيب. تنتهي كل خطوة بفحص تعرف به أنها نجحت قبل المتابعة.

قبل أن تبدأ

لا تحتاج إلى Docker أو Redis أو التخزين السحابي أو حساب دفع للعرض التوضيحي المحلي. يحافظ SQLite والتخزين المؤقت في الذاكرة على بساطة التشغيل الأول.

تحتاج إلىالسببكيف تتحقق
Python 3.11يشغّل الواجهة الخلفية Django.python3.11 --version
Node.js 22.13+يشغّل الواجهة الأمامية وأدوات البناء.node --version
Gitينزّل الشيفرة المصدرية.git --version
نافذتان طرفيتانواحدة تشغّل الواجهة الخلفية والأخرى تشغّل الواجهة الأمامية.افتح Terminal مرتين.
أبقِ كلا الخادمين قيد التشغيل. الخلفية والواجهة الأمامية عمليتان منفصلتان. إغلاق الطرفية يوقف تلك العملية. استخدم Ctrl+C في طرفية لإيقاف الخادم عند الانتهاء.

1. تحقق من أدواتك

نفّذ هذه الأوامر في الطرفية. إذا كان أحدها مفقودًا، فثبّته أولًا وأعد فتح الطرفية.

تحقق من الإصدارات
python3.11 --version
node --version
npm --version
git --version

يجب أن ترى Python 3.11 وNode 22.13 أو أحدث وإصدار npm. إذا لم يُعثر على python3.11، فثبّت Python 3.11 من python.org. إذا كان Node أقدم من 22.13، فثبّت إصدار LTS الحالي من nodejs.org.

Windows: استخدم py -3.11 حيثما يذكر هذا الدليل python3.11، ونشّط البيئة باستخدام .venv\Scripts\Activate.ps1.

2. نزّل الشيفرة

shell
git clone <your-fastrestful-repository> fastrestful
cd fastrestful
npm ci

يثبّت npm ci إصدارات تبعيات الواجهة الأمامية الدقيقة من ملف القفل. قد يستغرق بضع دقائق. يجب أن ينتهي بمجلد node_modules دون رسالة خطأ.

3. أنشئ بيئة الواجهة الخلفية

تحافظ البيئة الافتراضية على حزم Python الخاصة بـ FastRestful منفصلة عن بقية حاسوبك.

shell
cd backend
python3.11 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

في Windows PowerShell، فعّل باستخدام .venv\Scripts\Activate.ps1 بدلًا من source .venv/bin/activate. عندما تكون البيئة نشطة، يبدأ موجّه الأوامر عادةً بـ (.venv).

نقطة التحقق: شغّل python3.11 -m django --version. ينبغي أن يطبع إصدار Django 5.x. إذا فشل، فالبيئة الافتراضية غير نشطة أو لم يكتمل التثبيت.

4. أنشئ ملف إعداد الواجهة الخلفية

انسخ ملف المثال، ثم أنشئ سرّين والصقهما في backend/.env.

shell
cp .env.example .env
python3.11 -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"
python3.11 -c "import secrets; print(secrets.token_urlsafe(64))"
  1. افتح backend/.env في أي محرر نصوص.
  2. الصق الناتج الأول في FIELD_ENCRYPTION_KEY=. هذا يشفّر مفاتيح API وأسرار المزوّدين.
  3. الصق الناتج الثاني في DJANGO_SECRET_KEY=.
  4. اترك DJANGO_DEBUG=True وDATABASE_URL=sqlite:///db.sqlite3 وFRONTEND_URL=http://localhost:5055 للتطوير المحلي.
لا تُدرج .env أبدًا في المستودع. يحتوي على أسرار. يتجاهله المستودع بالفعل. إذا غيّرت منفذ الواجهة الأمامية لاحقًا، فحدّث FRONTEND_URL, CORS_ALLOWED_ORIGINS، و CSRF_TRUSTED_ORIGINS ليتطابقا.

5. أنشئ قاعدة البيانات وبيانات العرض

تأكد من أن البيئة الافتراضية لا تزال نشطة وأنك داخل backend/.

shell
python3.11 manage.py migrate
python3.11 manage.py seed_demo
python3.11 manage.py seed_apis
python3.11 manage.py seed_docs
python3.11 manage.py seed_engagement

ينشئ migrate جداول قاعدة البيانات. تنشئ أوامر التهيئة سوقًا تجريبيًا ومنتجات API ومحتوى وثائق وملفات مجتمعية. يؤدي هذا إلى إنشاء ملف backend/db.sqlite3 محلي.

بيانات اعتماد محلية فقط. seed_demo ينشئ مستخدمًا خارقًا admin / Admin12345!. تنشئ بذور التفاعل ملفات بنّائين بكلمة مرور Demo12345!. لا تُعد استخدام بيانات الاعتماد هذه في الإنتاج أبدًا.

6. ابدأ الواجهة الخلفية

الطرفية 1
# inside backend/, with the virtual environment active
python3.11 manage.py runserver 127.0.0.1:5056

اترك هذه الطرفية مفتوحة. تكون الواجهة الخلفية جاهزة عندما تطبع Starting development server at http://127.0.0.1:5056/. تحقق منها في طرفية أخرى باستخدام:

تحقق من الواجهة الخلفية
curl http://127.0.0.1:5056/api/health/live

7. ابدأ الواجهة الأمامية

افتح الطرفية الثانية وعد إلى جذر المستودع. يجب أن تظل الواجهة الخلفية قيد التشغيل في الطرفية 1.

الطرفية 2
cd /path/to/fastrestful
npm run dev -- --port 5055 --host 127.0.0.1

يمرر خادم تطوير Vite مسارات Django (/api/v1، /api/health، /api/schema، /api/docs، /admin، /static، /media) إلى الواجهة الخلفية على المنفذ 5056. لا تزال صفحات المنتجات العامة مثل /api/{slug} تُقدَّم من الواجهة الأمامية.

8. افتح التطبيق وسجّل الدخول

افتح هذه العناوين في متصفحك:

الصفحةالعنوانما هي
الموقع العامhttp://127.0.0.1:5055السوق وموقع التسويق.
مستوى التحكمhttp://127.0.0.1:5055/admin/إدارة Django وعمليات FastRestful.
وثائق APIhttp://127.0.0.1:5056/api/docs/واجهة Swagger UI لواجهة API الخاصة بالمنصة.
فحص السلامةhttp://127.0.0.1:5056/api/health/readyالجاهزية لفحوص النشر.

سجّل الدخول إلى مستوى التحكم باستخدام admin / Admin12345!.

قائمة التحقق للتشغيل الأول

  • يُحمَّل الموقع العام ويظهر كتالوج السوق.
  • يفتح مستوى التحكم ويمكنك تسجيل الدخول باسم admin.
  • تُفتح إعدادات الموقع وخطط المنصة وقسم محتوى الموقع دون أخطاء.
  • يمكن لحساب مستهلك إنشاء تطبيق ومفتاح API.
  • يظهر طلب عبر البوابة في سجلات الطلبات.

ما يجب فعله بعد ذلك

مشكلات التثبيت الشائعة

العَرَضالسبب المحتملالحل
python3.11: command not foundPython 3.11 غير مثبت أو غير موجود في PATH.ثبّت Python 3.11، وأعد فتح الطرفية، ثم نفّذ الفحص مجددًا.
يفشل npm ci بخطأ محركNode.js أقدم من 22.13.ثبّت Node 22.13+ ونفّذ npm ci مجددًا.
ModuleNotFoundError: djangoالبيئة الافتراضية غير نشطة.نفّذ source .venv/bin/activate داخل backend/.
خطأ FIELD_ENCRYPTION_KEYالمفتاح مفقود أو لم يُلصق بشكل صحيح.أنشئ مفتاح Fernet جديدًا والصق القيمة الكاملة دون علامات اقتباس.
المنفذ 5055 أو 5056 مستخدم بالفعلعملية أخرى تستخدم المنفذ.أوقف العملية الأخرى، أو اختر منافذ جديدة وحدّث FRONTEND_URL وقيم CORS و CSRF.
تُحمَّل الصفحة لكن تفشل استدعاءات APIالواجهة الخلفية لا تعمل.ابدأ الطرفية 1 باستخدام runserver وتأكد من عنوان فحص السلامة.
يُرفض تسجيل دخول المسؤوللم تُنفّذ تهيئة العرض التوضيحي أو أن قاعدة بيانات أخرى قيد الاستخدام.نفّذ seed_demo، أو أنشئ حسابك باستخدام python3.11 manage.py createsuperuser.
إعادة تعيين محلية. إذا أردت البدء من جديد على جهازك المحلي فقط، فأوقف الخلفية، واحذف backend/db.sqlite3، ثم أعد تشغيل migrate وأوامر البذور. لا تحذف قاعدة بيانات الإنتاج أبدًا.
ابدأ من هناقراءة 8 دقائق

البدء السريع: أول طلب عبر البوابة

انتقل من تثبيت محلي نظيف إلى استدعاء API محدود الاستخدام. ستشترك في API تجريبية، وتنشئ مفتاحًا، وترسل طلبًا، وترى حدث الاستخدام وسجل الطلب.

قبل أن تبدأ: أكمل التثبيت وأبقِ الطرفيتين قيد التشغيل. يجب أن تكون الخلفية على 127.0.0.1:5056 والواجهة الأمامية على 127.0.0.1:5055.

1. سجّل الدخول واختر مساحة عمل

افتح http://127.0.0.1:5055 وسجّل الدخول باستخدام admin / Admin12345!، أو أنشئ حسابًا جديدًا. تجمع مساحة العمل (المؤسسة) تطبيقاتك ومفاتيحك واشتراكاتك وفواتيرك.

تنتقل مساحة العمل النشطة في ترويسة X-Organization لاستدعاءات API. تضبطها وحدة تحكم المتصفح تلقائيًا. عند استدعاء API بنفسك، يجب تضمينها ما لم يستخدم الطلب مفتاح API بدلًا من جلسة المتصفح.

2. اشترك في منتج

افتح السوق، واختر منتجًا له إصدار مباشر، وحدد خطة. لمنتج SignalStack المهيأ إصدار مباشر 2.4.0 وثلاث خطط.

إذا كانت الخطة مجانية، فالتفعيل فوري. إذا كانت مدفوعة، يفتح FastRestful مزوّد الدفع المُعد. إعادة توجيه المتصفح لا تمنح الوصول بحد ذاتها: لا يُفعّل الاشتراك إلا بعد أن يسوّي webhook مزوّد موقّع الفاتورة الأولى.

لا يوجد مزوّد دفع بعد؟ استخدم خطة مجانية لطلبك الأول. لبيع خطط مدفوعة، اتبع بوابات الدفع خطوة بخطوة أولًا.

3. أنشئ تطبيقًا ومفتاحًا

في وحدة تحكم المستهلك، أنشئ تطبيقًا ثم أصدر مفتاح API. يُعرض المفتاح الخام مرة واحدة، لذا انسخه فورًا إلى مدير كلمات المرور أو ملف .env محلي.

شكل المفتاح الخام
fr_live_<random-secret>

# Store it in a secret manager or local .env file.
# Never commit it to a repository or paste it into a public issue.

النطاقات هي full أو execute أو read. اختر أضيق نطاق يكفي. إذا فقدت المفتاح، فأبطله وأصدر مفتاحًا جديدًا؛ يتوقف المفتاح القديم عن العمل فورًا.

4. أرسل طلبًا عبر البوابة

استبدل fr_live_… بالمفتاح الذي أنشأته للتو. يستخدم هذا المثال منتج SignalStack المهيأ واسم المسار البديل الخاص به.

curl عبر اسم المسار البديل للمنتج
curl --request GET \
  --url 'http://127.0.0.1:5055/api/v1/signal-stack/v2/deliveries?limit=10' \
  --header 'X-API-Key: fr_live_…' \
  --header 'Idempotency-Key: quickstart-001'

مع تفعيل توجيه مضيف المنتج، يستخدم الطلب نفسه https://{product-slug}.{FASTRESTFUL_API_HOST_SUFFIX}/.... تشترك كلتا الواجهتين في المسار نفسه للاشتراك والحصة وحد المعدل وidempotency والقياس وسجل الطلبات.

تبويب اختبار API في FastRestful مع قائمة endpoints ولافتة بوابة آمنة وعناصر تحكم للطلبات المباشرة
تحتفظ صفحة API العامة بالمختبر وعقد endpoint وسياق الطلب في علامة تبويب واحدة.

5. افحص النتيجة

  • حدث الاستخدام: يُسجَّل من جانب الخادم مع الحالة وزمن الاستجابة.
  • العداد الشهري: يزداد لفرض الحصة والتجاوز.
  • سجل الطلبات: معاينات طلب واستجابة منقّحة مرئية للمستهلك والمورّد.
  • لوحة التحكم: الطلبات ومعدل النجاح والإنفاق وزمن الاستجابة وأفضل واجهات API والنشاط الأخير.

افتح لوحة تحكم المستهلك وسجل الطلبات. يجب أن ترى الطلب الذي أرسلته للتو. إذا لم تراه، فافحص الطرفية التي تشغّل الواجهة الخلفية بحثًا عن traceback.

6. انشر إصدارًا (اختياري)

في استوديو المورّد، افتح منصة عمل المنتج، واستورد عقد OpenAPI إلى إصدار مسودة، وطابق وثائق endpoint، وشغّل الفرق، وقدّم للمراجعة، ثم رقِّ. يتطلب الإصدار المباشر عقد OpenAPI مدعومًا وغير فارغ وكتالوج endpoint مطابقًا تمامًا.

لدورة الحياة الكاملة، اقرأ منتجات API والإصدارات.

إذا فشل الطلب

الاستجابةما تعنيه عادةًما يجب فعله
401المفتاح مفقود أو مُبطل أو مشوّه.انسخ المفتاح الكامل مجددًا. لا تُضمّن علامات اقتباس أو مسافة زائدة.
403الاشتراك غير نشط أو نطاق المفتاح ضيق جدًا.تأكد من أن الخطة نشطة وأن المفتاح لديه نطاق execute أو full.
404لا تتطابق الطريقة والمسار مع الإصدار المباشر.افحص endpoint في صفحة API وتأكد من أن الإصدار مباشر.
429تم تجاوز حصة الخطة أو حد المعدل.اقرأ retry_after وانتظر، أو استخدم خطة أكبر.
خطأ CORS أو CSRF في المتصفحأصل المتصفح غير موثوق.أضف أصل الواجهة الأمامية إلى CORS_ALLOWED_ORIGINS وCSRF_TRUSTED_ORIGINS. استدعاءات البوابة التي تستخدم X-API-Key لا تستخدم ملفات تعريف ارتباط المتصفح.
ابدأ من هناقراءة 14 دقيقة

الإعداد دون إرهاق

تحتاج معظم عمليات التثبيت إلى مجموعة صغيرة من الإعدادات للتشغيل. ابدأ بالحد الأدنى أدناه، ثم أضف التكاملات التي تستخدمها فعلًا. الجداول الطويلة أدناه مرجعية، وليست قائمة تحقق.

أين توجد الإعدادات

المكاناستخدمه لـمتى يُطبَّق
backend/.envالأسرار وقاعدة البيانات وRedis ومفاتيح الدفع وSSO والتخزين.أعد تشغيل الواجهة الخلفية بعد تغييره.
الإدارة → بوابات الدفعبيانات اعتماد الدفع والدفعات.يتجاوز قيم .env المطابقة حقلًا بحقل. دون إعادة تشغيل.
الإدارة → النشرة البريدية → إعدادات البريدمزوّد البريد للحملات وهوية المرسل.يتجاوز مرسل البيئة للحملات.
الإدارة → إعدادات الموقعالهوية البصرية والتنقل وتوجيه المضيف ووضع الصيانة وسلوك الموقع.يُطبَّق فورًا ما لم يكن الإعداد مخزنًا مؤقتًا أو مدمجًا في الواجهة الأمامية.
متغيرات بناء الواجهة الأماميةقيم NEXT_PUBLIC_* مثل عنوان API العام.تُدمج وقت البناء. أعد بناء الواجهة الأمامية بعد تغييرها.

الحد الأدنى للإعدادات المحلية

بعد نسخ .env.example، هذه هي القيم الوحيدة التي يجب تغييرها للعرض المحلي:

backend/.env
DJANGO_DEBUG=True
DJANGO_SECRET_KEY=<generated-random-value>
FIELD_ENCRYPTION_KEY=<generated-fernet-key>
DATABASE_URL=sqlite:///db.sqlite3
FRONTEND_URL=http://localhost:5055
CORS_ALLOWED_ORIGINS=http://localhost:5055,http://127.0.0.1:5055
CSRF_TRUSTED_ORIGINS=http://localhost:5055,http://127.0.0.1:5055

أنشئ المفتاحين بالأوامر في التثبيت → إنشاء ملف إعداد الواجهة الخلفية.

الحد الأدنى لإعدادات الإنتاج

يضيف الإنتاج PostgreSQL وRedis واسم مضيف حقيقي وأصول HTTPS. استبدل كل عنصر نائب بقيمك.

بيئة الواجهة الخلفية للإنتاج
DJANGO_DEBUG=False
DJANGO_SECRET_KEY=<50-plus-random-characters>
DJANGO_ALLOWED_HOSTS=api.example.com,www.example.com
DATABASE_URL=postgresql://user:password@db-host:5432/fastrestful
REDIS_URL=redis://redis-host:6379/0
FRONTEND_URL=https://www.example.com
CORS_ALLOWED_ORIGINS=https://www.example.com
CSRF_TRUSTED_ORIGINS=https://www.example.com
FIELD_ENCRYPTION_KEY=<fernet-key>
لا تستخدم SQLite في الإنتاج. عندما DJANGO_DEBUG=False، يتطلب FastRestful PostgreSQL وعنوان URL مشتركًا لـ Redis. راجع النشر لمعرفة التسلسل الكامل.

كيف تغيّر الإعدادات بأمان

  1. غيّر تكاملًا واحدًا في كل مرة.

    اضبط واختبر وتحقق قبل الانتقال إلى المزوّد التالي. هذا يجعل الأعطال واضحة.

  2. حرّر backend/.env على الخادم.

    لا تحرّر ملفات داخل حاوية قيد التشغيل ستُستبدل. احتفظ بالأسرار في مخزن أسرار منصة النشر عندما يكون ذلك ممكنًا.

  3. أعد تشغيل الواجهة الخلفية والعمال.

    تُقرأ تغييرات البيئة عند بدء العملية. أعد تشغيل Gunicorn وعامل Celery وCelery beat بعد تحرير .env.

  4. أعد بناء الواجهة الأمامية لتغييرات NEXT_PUBLIC_*.

    تُجمَّع القيم العامة للواجهة الأمامية في البناء. إعادة تشغيل الواجهة الأمامية لا تكفي.

  5. شغّل إجراء الاختبار الخاص بالمزوّد.

    استخدم عملية الدفع التجريبية أو البريد التجريبي أو سجل تسليم webhook قبل إرسال حركة مباشرة.

مرجع البيئة الأساسي

المتغيرالافتراضيالغرض
DJANGO_SECRET_KEYمفتاح للتطوير فقطيجب أن يكون 50 حرفًا أو أكثر في الإنتاج.
DJANGO_DEBUGTrueعيّن False في الإنتاج. يفعّل سلوك ملفات تعريف الارتباط الآمنة وHSTS وHTTPS.
DJANGO_ALLOWED_HOSTSlocalhost,127.0.0.1,testserverأسماء مضيفين مفصولة بفواصل. ضمّن مضيفي API البدلاء عند استخدام نطاقات فرعية للمنتجات.
DATABASE_URLsqlite:///db.sqlite3SQLite محليًا؛ PostgreSQL في الإنتاج. يفشل الإنتاج دون PostgreSQL.
REDIS_URLفارغالتخزين المؤقت المشترك ووسيط Celery الافتراضي. مطلوب في الإنتاج.
CELERY_BROKER_URLREDIS_URLعنوان URL اختياري لوسيط منفصل.
FRONTEND_URLhttp://localhost:5055أصل الواجهة الأمامية العام وقاعدة عودة الدفع واحتياطي التتبع. يجب أن يكون HTTPS في الإنتاج.
FRONTEND_PREVIEW_URLFRONTEND_URLعنوان URL الأساسي المستخدم لمعاينات الأصول المخصصة في الإدارة.
FIELD_ENCRYPTION_KEYفارغمفتاح Fernet لمفاتيح API المشفرة وأسرار المزوّدين. مطلوب في الإنتاج.
CORS_ALLOWED_ORIGINSمحلي 3000/5055/5173أصول متصفح مفصولة بفواصل مسموح لها باستدعاء API.
CSRF_TRUSTED_ORIGINSيطابق CORSأصول متصفح موثوقة ببيانات اعتماد للطلبات التي تغيّر الحالة.
SECURE_REFERRER_POLICYstrict-origin-when-cross-originترويسة سياسة المُحيل.

بيئة الواجهة الأمامية

المتغيرالغرض
NEXT_PUBLIC_API_URLأصل API الخاص بـ Django للنشر المنفصل. اتركه فارغًا لمسارات الأصل نفسه.
NEXT_PUBLIC_SITE_URLأصل الواجهة الأمامية العام الأساسي للبيانات الوصفية وsitemap وrobots وعناوين Open Graph.
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEYمفتاح Stripe القابل للنشر لواجهة البطاقة المدمجة. يُحمَّل Stripe.js من CDN؛ دون اعتماد npm.
FASTRESTFUL_DEV_BACKEND_URLهدف وكيل تطوير اختياري. الافتراضي http://127.0.0.1:5056.
FASTRESTFUL_ADMIN_ORIGINSأصول الإدارة المسموح بها لمعاينات iframe للأصول المخصصة.

البوابة وتوجيه المضيف

المتغيرالافتراضيالغرض
GATEWAY_TIMEOUT_SECONDS15مهلة طلب المنبع.
GATEWAY_MAX_BODY_BYTES262144الحد الأقصى لحجم النص الوارد.
GATEWAY_MAX_UPLOAD_BYTES5242880الحد الأقصى لرفع multipart المدمج.
GATEWAY_MAX_RETRIES1ميزانية إعادة المحاولة للأعطال العابرة الآمنة.
GATEWAY_RETRY_BACKOFF_SECONDS0.05التأخير بين المحاولات.
GATEWAY_IDEMPOTENCY_TTL_SECONDS86400مدة ذاكرة إعادة التشغيل المؤقتة.
GATEWAY_CIRCUIT_FAILURE_THRESHOLD3الأعطال قبل فتح الدائرة.
GATEWAY_CIRCUIT_WINDOW_SECONDS60نافذة عدّ الأعطال.
GATEWAY_CIRCUIT_COOLDOWN_SECONDS30مدة تبريد الدائرة المفتوحة.
GATEWAY_TRUSTED_PROXY_CIDRSفارغالوكلاء الموثوقون المسموح لهم بتقديم ترويسات IP العميل.
GATEWAY_MEDIA_PREVIEW_BYTES1500000الحد الأقصى لمعاينة الوسائط base64 الملتقطة لوحدة التحكم.
FASTRESTFUL_API_HOST_SUFFIXفارغيفعّل التوجيه المباشر {product}.{suffix}. يبقي الفراغ اسم المسار البديل فقط.

المصادقة و SSO

المتغيرالغرض
SSO_ISSUERعنوان URL لمُصدر OIDC. إلغاء التعيين يخفي زر OIDC.
SSO_CLIENT_ID / SSO_CLIENT_SECRETبيانات اعتماد عميل OIDC.
SSO_SAML_ENABLEDفعّل نقاط نهاية SAML 2.0 SP. يتطلب lxml.
SSO_SAML_ENTITY_IDمعرّف كيان مزوّد خدمة SAML. الافتراضي fastrestful.
SSO_SAML_SSO_URLعنوان URL لـ SSO الخاص بمزوّد الهوية.
SSO_SAML_IDP_CERTشهادة X.509 PEM لمزوّد الهوية.
SSO_SAML_AUDIENCEتقييد جمهور اختياري.
ORGANIZATION_INVITE_DAYSمدة الدعوة بالأيام. الافتراضي 7.

البريد الإلكتروني والنشرة البريدية

المتغيرالغرض
EMAIL_BACKENDخلفية وحدة التحكم في وضع التصحيح؛ خلفية SMTP في الإنتاج افتراضيًا.
EMAIL_HOST / EMAIL_PORTمضيف ومنفذ SMTP.
EMAIL_HOST_USER / EMAIL_HOST_PASSWORDبيانات اعتماد SMTP.
EMAIL_USE_TLSفعّل STARTTLS. الافتراضي true.
ALERT_FROM_EMAILالمرسل الافتراضي وهوية التنبيهات.
NEWSLETTER_TRACKING_BASE_URLالأصل العام لبكسلات التتبع وإعادة توجيه النقرات وروابط إلغاء الاشتراك. يعود إلى FRONTEND_URL.

يمكن أيضًا تخزين إعدادات SMTP للنشرة البريدية في استوديو النشرة البريدية وتتجاوز مرسل البيئة للحملات. راجع استوديو النشرة البريدية.

مرجع المدفوعات والدفعات

تبحث عن تعليمات الإعداد؟ المتغيرات أدناه مرجع فقط. للحصول على خطوات لوحة تحكم المزوّد خطوة بخطوة، وأحداث webhook، والتحقق من webhook الخاص بـ PayPal، وعمليات الدفع التجريبية، استخدم بوابات الدفع خطوة بخطوة.
مجموعة المتغيراتالمتغيرات
StripeSTRIPE_SECRET_KEY، STRIPE_WEBHOOK_SECRET، STRIPE_API_BASE اختياري
PayPalPAYPAL_CLIENT_ID، PAYPAL_CLIENT_SECRET، PAYPAL_WEBHOOK_ID، PAYPAL_ENV، PAYPAL_API_BASE اختياري
FlutterwaveFLUTTERWAVE_PUBLIC_KEY، FLUTTERWAVE_SECRET_KEY، FLUTTERWAVE_WEBHOOK_SECRET، FLUTTERWAVE_API_BASE اختياري
PaystackPAYSTACK_PUBLIC_KEY، PAYSTACK_SECRET_KEY، PAYSTACK_WEBHOOK_SECRET، PAYSTACK_API_BASE اختياري
RazorpayRAZORPAY_KEY_ID، RAZORPAY_KEY_SECRET، RAZORPAY_WEBHOOK_SECRET، RAZORPAY_API_BASE اختياري
الدفعاتPAYOUT_PROVIDER قائمة سماح اختيارية مفصولة بفواصل: stripe، paypal

يخزّن الإدارة → بوابات الدفع بيانات الاعتماد نفسها في قاعدة البيانات. يتجاوز سجل قاعدة البيانات حقل البيئة حقلًا بحقل، ويؤدي تعطيله إلى إيقاف المزوّد في كل مكان حتى لو بقيت مفاتيح البيئة مضبوطة.

تخزين الوسائط والمواصفات

المتغيرالغرض
MEDIA_STORAGElocal أو s3.
MEDIA_S3_BUCKET / MEDIA_S3_REGIONحزمة S3 والمنطقة.
MEDIA_S3_ENDPOINT_URLendpoint مخصص متوافق مع S3.
MEDIA_S3_ACLACL مباشر لـ S3 اختياري. اتركه فارغًا عند استخدام CloudFront مع OAC.
MEDIA_CDN_DOMAINنطاق CloudFront أو CDN آخر.
MEDIA_CDN_DISTRIBUTION_IDيفعّل إجراءات الإبطال لكل أصل.
SPEC_STORAGEdb أو s3 لكتل عقد OpenAPI.
SPEC_S3_BUCKET / SPEC_S3_PREFIX / SPEC_S3_REGIONوجهة كتلة المواصفات وبادئتها. يحتاج وضع S3 إلى boto3.

يعيّن SHORTLINK_BASE_URL أصل الرابط القصير العام، على سبيل المثال https://go.example.com. عند الفراغ يعود إلى NEWSLETTER_TRACKING_BASE_URL، ثم FRONTEND_URL. يمكن جدولة الأمر checklinks من cron أو Celery beat.

الأولوية وإعادة التحميل

  • توفر قيم البيئة افتراضيات النشر؛ وتتجاوز سجلات بوابة الإدارة القيم حقلًا بحقل.
  • تتطلب تغييرات بيئة الواجهة الخلفية إعادة تشغيل العملية. تُمسح بعض الإعدادات المخزنة مؤقتًا (علامة الصيانة، لغة المصدر) تلقائيًا عند حفظ النموذج.
  • تُدمج المتغيرات العامة للواجهة الأمامية وقت البناء. أعد البناء بعد تغيير قيم NEXT_PUBLIC_*.
  • بعد تغيير lib/i18n/*.json، نفّذ npm run export:i18n وأعد تشغيل الواجهة الخلفية حتى تكون حزمة المصدر المخزنة مؤقتًا حديثة.
النشر والتشغيلقراءة 16 دقيقة

النشر

انقل FastRestful من عرض SQLite محلي إلى نشر إنتاجي باستخدام PostgreSQL وRedis وتخزين كائنات وخادم WSGI وTLS وواجهة أمامية ثابتة. صُممت المنصة لتُستضاف ذاتيًا.

قبل النشر

  • اسم نطاق ووصول DNS لمضيفي الواجهة الأمامية وAPI.
  • قاعدة بيانات PostgreSQL 16 ومثيل Redis 7.
  • إنهاء HTTPS، إما عند الوكيل أو عند الحافة.
  • DJANGO_SECRET_KEY مولّد وFIELD_ENCRYPTION_KEY منسوخ احتياطيًا.
  • خطة لتخزين الوسائط: القرص المحلي مقبول فقط لتجربة خادم واحد؛ استخدم تخزينًا متوافقًا مع S3 للنشر الحقيقي.
  • وجهة نسخ احتياطي خارج خادم التطبيق.

الترتيب الموصى به

  1. انشر الواجهة الخلفية وقاعدة البيانات.

    اجعل /api/health/ready ينجح قبل المساس بالواجهة الأمامية.

  2. انشر الواجهة الأمامية.

    وجّهها إلى أصل API وأضف أصل الواجهة الأمامية إلى إعدادات CORS وCSRF.

  3. اضبط البريد الإلكتروني والتخزين.

    استخدم التكاملات الخارجية. تحقق من بريد تجريبي ورفع تجريبي.

  4. اربط المدفوعات فقط عندما تكون مستعدًا للبيع.

    استخدم بوابات الدفع خطوة بخطوة وأكمل الدفع التجريبي أولًا.

  5. فعّل الترخيص وجدولة نبضات الحياة.

    استخدم الترخيص والتحديثات الرسمية.

  6. أعدّ النسخ الاحتياطي والمراقبة.

    استخدم النسخ الاحتياطي والترقيات والرصد.

الطوبولوجيا الموصى بها

طوبولوجيا الإنتاج
Internet
  │
  ├── app.example.com ──► frontend (static/CDN or Node runtime)
  │                           │
  │                           └── /api/* ──► reverse proxy ──► Gunicorn / Django
  │
  ├── api.example.com ──► reverse proxy ──► Gunicorn / Django
  ├── *.api.example.com ──► wildcard product gateway
  │
  ├── PostgreSQL 16 (primary)
  ├── Redis 7 (cache + Celery broker)
  ├── S3 + CloudFront (media, optional specs)
  └── Celery worker + beat (billing, moderation, email, availability)

يمكنك تقديم الواجهة الأمامية وAPI من أصل واحد أو فصلهما. إذا فصلتهما، فعيّن NEXT_PUBLIC_API_URL إلى أصل API، وأضف أصل الواجهة الأمامية إلى CORS_ALLOWED_ORIGINS وCSRF_TRUSTED_ORIGINS، وعيّن FRONTEND_URL إلى أصل الواجهة الأمامية العام.

Docker Compose

يتضمن المستودع ملف Compose مع PostgreSQL وAPI وRedis وملفات تعريف اختيارية للعامل وbeat.

يشغّل Compose حزمة الواجهة الخلفية، لا الواجهة الأمامية. ابنِ الواجهة الأمامية بشكل منفصل واستضفها على مضيفك الثابت أو CDN، أو أضف خدمة واجهة أمامية إلى ملف Compose الخاص بك. تشغّل حاوية API الترحيلات وGunicorn على المنفذ 8000.
shell
export DJANGO_SECRET_KEY="$(openssl rand -base64 64 | tr -d '\n')"
export FIELD_ENCRYPTION_KEY="$(python3.11 -c 'from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())')"
export DJANGO_ALLOWED_HOSTS="api.example.com,.api.example.com"
export CORS_ALLOWED_ORIGINS="https://app.example.com"
export CSRF_TRUSTED_ORIGINS="https://app.example.com"
export FRONTEND_URL="https://app.example.com"
export POSTGRES_PASSWORD="$(openssl rand -hex 24)"

docker compose up --build -d
docker compose --profile scheduler up --build -d

نفّذ الترحيلات والتهيئة داخل حاوية API بعد أن تصبح قاعدة البيانات سليمة:

shell
docker compose exec api python manage.py migrate --noinput
docker compose exec api python manage.py seed_demo
docker compose exec api python manage.py seed_apis
docker compose exec api python manage.py seed_docs
docker compose exec api python manage.py collectstatic --noinput
غيّر كلمة مرور التهيئة فورًا لأي نشر متاح على الإنترنت. لا تشغّل بذور العرض التجريبي في الإنتاج ما لم تكن تنوي الاحتفاظ ببيانات العرض.

إعداد الإنتاج اليدوي

الواجهة الخلفية

shell
cd /srv/fastrestful/backend
python3.11 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
pip install gunicorn>=22.0 boto3 django-storages  # optional: S3 media

cp .env.example .env
# Fill production values, then:
python3.11 manage.py migrate --noinput
python3.11 manage.py collectstatic --noinput
python3.11 manage.py check --deploy

Gunicorn + systemd

/etc/systemd/system/fastrestful.service
[Unit]
Description=FastRestful Django API
After=network.target postgresql.service redis.service

[Service]
User=fastrestful
Group=fastrestful
WorkingDirectory=/srv/fastrestful/backend
EnvironmentFile=/srv/fastrestful/backend/.env
ExecStart=/srv/fastrestful/backend/.venv/bin/gunicorn \
  config.wsgi:application \
  --bind 127.0.0.1:8000 \
  --workers 3 \
  --timeout 60
Restart=always
RestartSec=3

[Install]
WantedBy=multi-user.target
shell
sudo systemctl daemon-reload
sudo systemctl enable --now fastrestful
sudo systemctl status fastrestful

وكيل Nginx العكسي

/etc/nginx/sites-available/fastrestful
server {
    listen 443 ssl http2;
    server_name api.example.com;

    ssl_certificate     /etc/letsencrypt/live/api.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem;

    client_max_body_size 8m;

    location /static/ {
        alias /srv/fastrestful/backend/staticfiles/;
        expires 30d;
        access_log off;
    }

    location /media/ {
        alias /srv/fastrestful/backend/media/;
        expires 7d;
        access_log off;
    }

    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_read_timeout 65s;
    }
}

server {
    listen 80;
    server_name api.example.com;
    return 301 https://$host$request_uri;
}

مضيف منتج بنطاق بدل

/etc/nginx/sites-available/fastrestful-products
server {
    listen 443 ssl http2;
    server_name *.api.example.com;

    ssl_certificate     /etc/letsencrypt/live/api.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_set_header Host $host;  # product slug comes from this host
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

أضف سجل DNS بدلًا، وأصدر شهادة بدلًا بتحدٍ DNS-01، وضمّن المضيف البدل في DJANGO_ALLOWED_HOSTS. عيّن FASTRESTFUL_API_HOST_SUFFIX=api.example.com.

بناء الواجهة الأمامية واستضافتها

shell
export NEXT_PUBLIC_API_URL="https://api.example.com"
export NEXT_PUBLIC_SITE_URL="https://app.example.com"
export NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY="pk_live_..."
npm run build

انشر ناتج البناء على مضيفك الثابت أو بيئة تشغيل متوافقة مع Node. البناء مكتفٍ بذاته ولا يتطلب مستوى تحكم موقع مُدار. إذا استخدمت Cloudflare، فاربط D1/Images فقط عندما يحتاج النشر إلى تلك الميزات.

الملفات الثابتة والوسائط

  • الثابت: نفّذ collectstatic، وقدّم /static/ من Nginx أو CDN.
  • الوسائط المحلية: قدّم /media/ من Nginx للنشرات الصغيرة.
  • وسائط الإنتاج: استخدم S3 + CloudFront مع OAC، وأبقِ الحزمة خاصة، وعيّن MEDIA_STORAGE=s3، ولا تعيّن MEDIA_S3_ACL إلا عند التقديم مباشرة من S3.
  • المواصفات: اترك SPEC_STORAGE=db لتثبيت صغير؛ استخدم S3 لأرشيفات العقود الأكبر.

فحوص السلامة

الفحصالمتوقع
GET /api/health/liveحيوية العملية. دون اعتماد على قاعدة البيانات.
GET /api/health/readyجاهزية قاعدة البيانات والتخزين المؤقت المشترك. يعيد 503 مع التبعية الفاشلة.
GET /api/schema/مخطط OpenAPI. مفيد لفحوص دخان النشر.

الترقيات والنسخ الاحتياطي

تسلسل ترقية آمن
# 1. Back up PostgreSQL and media
pg_dump --format=custom "$DATABASE_URL" > fastrestful-$(date +%F).dump

# 2. Pull code and install dependencies
git pull --ff-only
pip install -r backend/requirements.txt
npm ci

# 3. Apply migrations and rebuild assets
python3.11 backend/manage.py migrate
npm run build

# 4. Restart API and workers
sudo systemctl restart fastrestful
sudo systemctl restart fastrestful-worker fastrestful-beat

# 5. Verify
curl -f https://api.example.com/api/health/ready

بوابات الإنتاج

  • DJANGO_DEBUG=False، سر بطول 50+ حرفًا، مفتاح Fernet صالح.
  • PostgreSQL وRedis وأصول HTTPS ومضيفون مسموحون صراحة.
  • بيانات اعتماد المسؤول مغيّرة؛ مستخدمو العرض محذوفون أو معطّلون.
  • webhooks الدفع والدفعات مسجلة بالسر الموقّع الصحيح.
  • بيانات اعتماد SMTP والمزوّدين مختبرة؛ نطاق المرسل موثّق.
  • S3/CloudFront مُعد إذا كانت عمليات رفع الوسائط مفعّلة.
  • عامل المجدول + beat قيد التشغيل أو مكافئات cron مثبتة.
  • النسخ الاحتياطي مختبر بالاستعادة في بيئة منفصلة.
  • تغطي المراقبة الجاهزية ومعدل 5xx وزمن استجابة البوابة وأعطال webhook وعمق قائمة الانتظار.
  • الصفحات القانونية والشروط والخصوصية وجهة اتصال الدعم راجعها المشغّل.
النشر والتشغيلقراءة 10 دقائق

العمليات

التسوية المجدولة وتسليم الإشعارات وفحوص التوفر والاحتفاظ بالقياسات وفحوص السلامة والأوامر التشغيلية التي تحافظ على صحة FastRestful.

جدول Celery

المهمةالجدولالغرض
settle_periodالأول من كل شهر، 00:05 UTCأنشئ الفواتير والدفعات للفترة السابقة.
escalate_moderation_casesكل 15 دقيقةصعّد حالات الإشراف والاستئناف المتأخرة.
deliver_notification_email_queueكل 15 دقيقةسلّم رسائل البريد الإشعارية المصطفة مع استرداد المطالبات القديمة.
schedule_daily_api_availability_checksيوميًا، 00:20 UTCأرسل فحوص توفر المنتجات.
shell
celery -A config worker -l info -Q billing,celery
celery -A config beat -l info

دون وسيط، يعمل Celery بحماس داخل العملية. في الإنتاج، عيّن REDIS_URL أو CELERY_BROKER_URL وشغّل العامل وbeat كخدمتين منفصلتين.

الأوامر التشغيلية

الأمرما يفعله
generate_invoices --period YYYY-MMإنشاء فواتير متوافق مع idempotency لفترة.
generate_payouts --period YYYY-MMإنشاء دفعات متوافق مع idempotency مع تطبيق الاستردادات والرسوم.
prune_telemetryالاحتفاظ بسجلات الطلبات وأحداث الاستخدام.
check_api_availabilityشغّل فحوص صحة المنتج يدويًا.
escalate_moderationصعّد الحالات المتأخرة دون Celery beat.
deliver_notification_emailsفرّغ تراكم رسائل البريد الإشعارية المصطفة.
checklinksأعد فحص وجهات الروابط القصيرة بحثًا عن عناوين URL معطلة.
shell
python3.11 manage.py generate_invoices --period 2026-10
python3.11 manage.py generate_payouts --period 2026-10
python3.11 manage.py prune_telemetry --request-log-days 90 --usage-event-days 365
python3.11 manage.py check_api_availability
python3.11 manage.py checklinks --limit 200 --timeout 6

وضع الصيانة

فعّل عمليات المنصة → وضع الصيانة في إعدادات الموقع. تعيد الواجهة الأمامية صفحة 503 بهوية العلامة، وتعيد استدعاءات API والبوابة للعملاء استجابة maintenance_mode قابلة للقراءة آليًا مع Retry-After: 300، وتُوقف الوثائق/Swagger.

تظل إدارة الموظفين وفحوص السلامة وعمليات رد نداء مزوّد الهوية وwebhooks الدفع/الدفعات الموقعة متاحة حتى تتعافى المنصة بأمان ولا يُسقط المزوّدون.

المراقبة

  • فحص جاهزية قاعدة البيانات + التخزين المؤقت المشترك.
  • معدل 5xx لـ API وزمن الاستجابة p95 حسب مساحة الأسماء.
  • معدل أخطاء منبع البوابة وأحداث فتح الدائرة.
  • قائمة انتظار أعطال webhook واستثناءات الدفعات.
  • عمق قائمة انتظار Celery ونبض beat.
  • معدلات الارتداد/الشكاوى للبريد ومعدل إلغاء الاشتراك.
  • نمو تخزين الوسائط ونسبة إصابة ذاكرة CDN المؤقتة.
  • اتصالات PostgreSQL والاستعلامات البطيئة والقرص ونجاح النسخ الاحتياطي.

النسخ الاحتياطي

البياناتاستراتيجية النسخ الاحتياطي
PostgreSQLتفريغ منطقي ليلي مع نسخ احتياطي مستمر من المزوّد. اختبر الاستعادة كل ثلاثة أشهر.
وسائط S3فعّل إصدارات الحزمة والنسخ المتماثل عبر المناطق إذا لزم الأمر.
المواصفات في قاعدة البياناتمضمّنة في نسخ PostgreSQL الاحتياطية.
أسرار البيئةخزّنها في مدير أسرار؛ وانسخها احتياطيًا مع ضوابط الوصول وسجل التدوير.
أدلة التدقيقاحتفظ بها وفق السياسة؛ يمكن لمهام التصدير إنشاء أرشيفات غير قابلة للتغيير.

ملاحظات التوسع

  • شغّل عدة مثيلات Gunicorn/Django خلف موازن تحميل؛ أبقِ الجلسات والتخزين المؤقت على Redis.
  • شغّل عمال Celery منفصلين عن عمليات الويب ووسّع قوائم انتظار الفوترة والافتراضية بشكل مستقل.
  • تستخدم حدود معدل البوابة التخزين المؤقت المشترك؛ يعيد انقطاع التخزين المؤقت 503 قابلة لإعادة المحاولة بدلًا من الفشل المفتوح.
  • استخدم تجميع اتصالات PostgreSQL إذا زاد عدد العمال.
  • انقل الوسائط إلى S3/CloudFront قبل أن تجعل حركة المرور دورة حياة القرص المحلي مؤلمة.
  • أبقِ الاحتفاظ بالقياسات صريحًا؛ سجلات الطلبات وأحداث الاستخدام ليست مخصصة للنمو إلى الأبد.
النشر والتشغيلقراءة 12 دقيقة

الأمان

سلوك حرج أمنيًا في FastRestful: حفظ المفاتيح، وعزل المستأجرين، وحماية SSRF في البوابة، وسياسة أصل المتصفح، وتخزين الأسرار، وأدلة التدقيق، وقائمة تقوية الإنتاج.

حفظ مفاتيح API

  • تُعاد المفاتيح الخام مرة واحدة فقط عند الإنشاء أو التدوير. ولا تُعرض مجددًا بواسطة المُسلسِلات أو الإدارة.
  • الأشكال المخزنة: بادئة بحث، وتجزئة SHA-256 للمقارنة بزمن ثابت، ونسخة مشفرة بـ Fernet لاستخدام البوابة من جانب الخادم.
  • يلغي التدوير المفتاح القديم ويصدر مفتاحًا جديدًا في استدعاء واحد. لا يمكن استخدام مفتاح مُبطل لإصدار بدائل.
  • تضيّق النطاقات الوصول: full أو execute أو read. يمكن للتحديثات تضييق النطاق فقط، ولا توسيعه أبدًا.
  • يرتبط المفتاح بتطبيقه واشتراكه؛ ولا يمكنه عبور التطبيقات أو مساحات العمل.

عزل المستأجرين

  • يحدد X-Organization المستأجر النشط. تعيد الأذونات من جانب الخادم التحقق من العضوية لكل كائن.
  • قراءات المورّد ثنائية النطاق: يرى المورّد منتجاته واشتراكاته وفواتيره وسجلاته؛ ويرى المستهلك مساحة عمله فقط.
  • حقول الملكية غير قابلة للتغيير عبر API.
  • المُسلسِلات العامة صريحة، وليست قوائم بيضاء لنموذج خاص. تبقى المقاييس التشغيلية والحقول الخاصة خارج الاستجابات المجهولة.
  • يمكن للمستخدمين الخارقين القراءة عبر المستأجرين للدعم، لكن الكتابات لا تزال تتطلب النطاق المالك الصحيح باستثناء عمليات المنصة الصريحة.

أمان البوابة

  • يجب أن تستخدم المنابع HTTPS، وتُحل إلى عناوين عامة، وتبقى على المضيف الأصلي، وتتجنب أنماط الاجتياز.
  • لا تُتبع إعادة التوجيه. تُفحص إجابات DNS ويُثبَّت عنوان IP العام المختار عبر اتصال TLS لمنع إعادة الربط.
  • تُفرض المهلات وحدود النص وحدود الرفع والمحاولات المحدودة قبل التمرير.
  • تُرفق أسرار المورّد من جانب الخادم فقط؛ ولا تصل إلى المتصفح أبدًا.
  • تُخزَّن مفاتيح idempotency كتجزئات رموز مع بصمة طلب واستجابة منقّحة، وليس أجسام طلبات خام أبدًا.
  • تُحدّ معاينات الاستجابة بالطول وتنقّح Set-Cookie وAuthorization وX-API-Key.
  • يعيد انقطاع التخزين المؤقت المشترك 503 قابلة لإعادة المحاولة قبل حجز الحصة؛ ولا تفشل البوابة مفتوحة.

أمان المتصفح والأصل

  • يفرض الإنتاج HTTPS وHSTS وملفات تعريف ارتباط آمنة وسياسة مُحيل صارمة.
  • يجب أن يسمّي CORS_ALLOWED_ORIGINS وCSRF_TRUSTED_ORIGINS الواجهة الأمامية العامة بدقة.
  • يمكن للواجهة الأمامية قراءة ملفات تعريف ارتباط CSRF لأن جلسة Django المشتركة تُستخدم لكتابات الإدارة ووحدة التحكم؛ لا تعرّضها عبر الأصول أبدًا.
  • أصول CSS/JS المخصصة محتوى مشغّل موثوق. استخدم nonce لـ CSP، وعاين قبل التفعيل، وراجع سجل المراجعات.
  • يبقي وضع الصيانة عمليات رد نداء المزوّد ومسارات مزوّد الهوية متاحة.

إدارة الأسرار

السرالتخزين
DJANGO_SECRET_KEYمدير أسرار أو ملف بيئة قابل للقراءة بواسطة مستخدم الخدمة فقط. دوّر بحذر.
FIELD_ENCRYPTION_KEYمدير أسرار. انسخه احتياطيًا: فقدانه يجعل المفاتيح المشفرة وأسرار المزوّدين غير قابلة للاسترداد.
مفاتيح المزوّدسجلات بوابة الإدارة أو البيئة. يُفضّل سجلات الإدارة للتدوير التشغيلي دون نشر.
بيانات اعتماد SMTPاستوديو النشرة البريدية أو البيئة. استخدم هوية إرسال مخصصة.
عنوان URL لقاعدة البياناتمدير أسرار. استخدم TLS ودور قاعدة بيانات بأقل صلاحية.

تقوية المصادقة

  • فعّل المصادقة الثنائية المطلوبة للموظفين واختياريًا لجميع الحسابات في إعدادات الموقع.
  • استخدم OIDC أو SAML لهوية المؤسسة؛ يمكن أن يبقى تسجيل الدخول بكلمة المرور كبديل.
  • أبقِ رموز الوصول قصيرة العمر (15 دقيقة) ورموز التحديث المدوّرة في القائمة السوداء بعد التدوير.
  • الدعوات مجزأة وأحادية الاستخدام ومرتبطة بالبريد وتنتهي بعد سبعة أيام.
  • يتطلب وصول المسؤول is_staff؛ ومساحة العمل admin ليست دور موظف منصة.
  • لا تكشف استجابات إعادة تعيين كلمة المرور ما إذا كان الحساب موجودًا.

التدقيق والأدلة

  • تُنتج إجراءات الإدارة وقرارات الإشراف وتغييرات حالة الفوترة وتسوية الدفعات وتغييرات الإعدادات واستعادة الحسابات أحداث تدقيق.
  • إيصالات أحداث المزوّد قابلة للإضافة فقط وترفض تعارضات الحمولة، ما يجعل إعادة المحاولات آمنة.
  • قيود دفتر الأستاذ قابلة للإضافة فقط. تنشئ عمليات الاسترداد بعد الدفعة قيود استرداد الأموال وعكس الرسوم.
  • تدعم مهام تصدير التدقيق الاحتفاظ والمراجعة دون وصول مباشر إلى قاعدة البيانات.

قائمة التحقق للإنتاج

shell
DJANGO_DEBUG=0 \
DATABASE_URL=postgresql://… \
REDIS_URL=redis://… \
FRONTEND_URL=https://app.example.com \
DJANGO_ALLOWED_HOSTS=api.example.com,.api.example.com \
CORS_ALLOWED_ORIGINS=https://app.example.com \
CSRF_TRUSTED_ORIGINS=https://app.example.com \
DJANGO_SECRET_KEY=<50+ chars> \
FIELD_ENCRYPTION_KEY=<fernet key> \
python3.11 manage.py check --deploy
  • إزالة حسابات العرض التجريبي والبيانات الأولية من الإنتاج.
  • التحقق بخطوتين إلزامي للموظفين؛ وSSO مُختبر من البداية إلى النهاية.
  • التحقق من webhooks الدفع باستخدام السر الموقّع الخاص بالمزوّد.
  • حاوية الوسائط خاصة؛ وCDN OAC مهيأ؛ ولا وصول كتابة شامل.
  • النسخ الاحتياطية مشفرة ومُختبرة الاستعادة.
  • تستبعد السجلات الأسرار وتُخفي حمولات المستهلك.
  • تصحيح صور التبعيات والحاويات وفق جدول منتظم.
  • نشر جهة اتصال الحوادث ومسار الإفصاح عن الثغرات.
النشر والتشغيلقراءة 16 دقيقة

الترخيص والتحديثات الرسمية

FastRestful شفرة مصدرية مرخّصة تُباع عبر Dakidarts. اربط مفتاح الشراء بـ LicenseHub للتحقق من الإصدارات الرسمية الموقّعة، أو تثبيت إصدار أحدث، أو الرجوع إلى إصدار أقدم. تظل البوابة قيد التشغيل تعمل إذا تعذّر الوصول إلى LicenseHub مؤقتًا.

ما يفعله مركز التحديثات

المهمةأين
ربط ترخيص الشراء وعرض تواريخ الاستحقاقAdmin → التحديثات البرمجية (/admin/updates/)
فحص الإصدارات وتنزيلها والتحقق منها وتثبيتهاالصفحة نفسها، أو الأمر fastrestful_update
تجديد إجازة الترخيص وفق جدول منتظمpython3.11 manage.py license_heartbeat
عرض سجل التحديثات وسجلات المثبّتنشاط التنزيل والتثبيت في صفحة التحديث
عرض حالة الترخيص في نظرة عامة على العملياتAdmin → نظرة عامة على العمليات
قبل التحديث: خذ نسخة احتياطية من قاعدة البيانات والوسائط. يأخذ محدّث النظام لقطة من المصدر وSQLite افتراضيًا، لكن النسخة الاحتياطية الموثقة تبقى شبكة أمانك. راجع النسخ الاحتياطية والترقيات.

الجزء 1 — تفعيل ترخيصك

  1. شراء FastRestful وافتح لوحة تحكم Dakidarts.

    انتقل إلى Dashboard → التراخيص وانسخ المفتاح كاملًا. يبدأ بـ DK-FRST-….

  2. افتح مركز التحديثات.

    سجّل الدخول بصفة موظف وافتح https://your-domain/admin/updates/. يُسمّى في الشريط الجانبي التحديثات البرمجية.

  3. الصق مفتاح الترخيص.

    استخدم المفتاح كاملًا، بما في ذلك أي شرطات. يُشفّر عند التخزين ولا يُعرض بعد التفعيل سوى شكل مقنّع.

  4. أكّد عنوان LicenseHub.

    القيمة الافتراضية هي https://dakidarts.com. أبقِها ما لم يمنحك Dakidarts أصلًا مختلفًا. يلزم HTTPS خارج تصحيح الأخطاء المحلي.

  5. اختر البيئة.

    Production تستهلك مقعد إنتاج. Staging وDevelopment تستهلكان مقاعد غير إنتاجية. اختر ما يطابق هذا التثبيت.

  6. أضف نطاق الإنتاج اختياريًا.

    على سبيل المثال api.example.com. يساعدك هذا على تمييز التثبيت في بوابة العملاء.

  7. اختر قناة إصدار.

    ابدأ بـ Stable. استخدم Beta أو Preview فقط في بيئة اختبار مؤقتة.

  8. انقر فوق تفعيل الترخيص.

    ينشئ التفعيل installation_id دائمًا أو يعيد استخدامه ويربط مقعدًا واحدًا. تعرض الصفحة بعد ذلك النسخة، ونوافذ التحديث والدعم، وعدد مرات التفعيل، وآخر نبضة.

إذا فشل التفعيل، يظهر الخطأ في الصفحة. الأسباب الأكثر شيوعًا هي مفتاح منتهي الصلاحية، أو بلوغ حد المقاعد، أو مفتاح نُسخ مع مسافة زائدة.

الجزء 2 — تثبيت تحديث من لوحة الإدارة

  1. خذ نسخة احتياطية.

    انسخ احتياطيًا PostgreSQL والوسائط و.env وأي ملفات مخصصة. تأكد من نجاح استعادة النسخة الاحتياطية قبل أن تحتاج إليها.

  2. افتح Admin → التحديثات البرمجية.

    تعرض الصفحة الإصدار قيد التشغيل، والإصدار المثبّت، وحالة الاتصال.

  3. انقر فوق التحقق من التحديثات.

    يعيد LicenseHub كل إصدار تغطيه نافذة التحديث لديك: الإصدارات الأحدث والحالي والأقدم.

  4. انقر فوق تنزيل وتجهيز على الإصدار الهدف.

    ينزّل FastRestful كل أصل، ويتحقق من SHA-256، ويتحقق من توقيع بيان Ed25519، ويستخرج الحزمة إلى FASTRESTFUL_UPDATE_DIR/<version>/bundle/.

  5. انقر فوق تثبيت.

    تبدأ لوحة الإدارة عاملًا منفصلًا كي لا تتجاوز الترحيلات أو عملية البناء مهلة طلب الويب. تُحدّث الصفحة أثناء تشغيله.

  6. انتظر ظهور «مثبّت» ولافتة إعادة التشغيل.

    لا تزال العملية قيد التشغيل تستخدم الشفرة القديمة حتى تعيد التشغيل. تعرض الصفحة مثبّت … · إعادة التشغيل مطلوبة.

  7. أعد تشغيل الخدمات.

    أعد تشغيل Gunicorn أو خادم تطبيقك، وعامل Celery وbeat، وعملية الواجهة الأمامية إذا كانت تعمل على المضيف نفسه. استخدم مدير الخدمات لديك، لا صفحة الإدارة. أمثلة على أوامر systemd:

    مثال systemd
    sudo systemctl restart fastrestful
    sudo systemctl restart fastrestful-worker fastrestful-beat
    # restart your frontend process too if it runs on this host
  8. تحقّق.

    أكّد الإصدار في مركز التحديثات، وافتح /api/health/ready، ونفّذ طلب اختبار واحد عبر البوابة.

الحزم الكبيرة: إجراء تنزيل وتجهيز توجد في

الجزء 3 — التحديث من سطر الأوامر

استخدم هذا عندما تكون لوحة الإدارة غير متاحة أو عندما تريد التثبيت في جلسة طرفية.

shell
cd /srv/fastrestful/backend
source .venv/bin/activate

python3.11 manage.py fastrestful_update status
python3.11 manage.py fastrestful_update check
python3.11 manage.py fastrestful_update download --release-version 1.2.0
python3.11 manage.py fastrestful_update install --release-version 1.2.0

تثبيت CLI متزامن ويطبع سجل المثبّت الملتقط. أما تثبيت لوحة الإدارة فغير متزامن. يتحقق كلاهما من الأصول الموقّعة نفسها قبل تشغيل المثبّت.

أبقِ إجازة الترخيص حديثة

مدة صلاحية شهادة الترخيص 24 ساعة. وترك نبضة كل ست ساعات مساحة للانقطاعات العابرة. ويكفي فحص يومي لاكتشاف الإصدارات.

مثال cron
17 */6 * * * cd /srv/fastrestful/backend && /srv/fastrestful/.venv/bin/python manage.py license_heartbeat --check-updates >> /var/log/fastrestful-license.log 2>&1

تسجّل النبضة الفاشلة الخطأ في لوحة الإدارة لكنها لا توقف البوابة.

الجزء 4 — الرجوع إلى إصدار أقدم

  1. افتح قائمة الإصدارات.

    تظهر الإصدارات الأقدم التي تغطيها نافذة التحديث لديك إلى جانب الإصدار الحالي.

  2. انقر فوق تثبيت إصدار أقدم على الإصدار الهدف.

    يميّز مركز التحديثات التثبيت بذلك الإصدار. هذا تثبيت إصدار عادي، وليس إعادة تعيين مدمّرة.

  3. أعد تشغيل الخدمات.

    تلتقط العملية المعاد تشغيلها شجرة المصدر الأقدم.

  4. افحص قاعدة البيانات.

    إذا طبّق الإصدار الأحدث ترحيلًا غير قابل للتراجع، فاستعد النسخة الاحتياطية لقاعدة البيانات السابقة للتحديث. احتفظ بنسخة قاعدة البيانات ونسخة المصدر معًا.

لقطات المصدر اقرأ FASTRESTFUL_UPDATE_DIR/backups/. تُنسخ SQLite؛ وتُفرّغ PostgreSQL باستخدام pg_dump عند توفرها. قد يتطلب التراجع عبر ترحيل غير قابل للعكس استعادة قاعدة البيانات على أي حال.

الجزء 5 — القنوات والبيئات

القناةاستخدمه لـ
stableإصدارات الإنتاج. هذه هي القناة الافتراضية.
betaإصدارات معاينة لبيئة Staging.
previewإصدارات مبكرة. استخدمها فقط مع بيئة مؤقتة.

تُخزّن القناة في الاتصال وتُرسل مع كل فحص. غيّرها في صفحة التحديث أو أثناء التفعيل.

الجزء 6 — Docker والنشر القائم على الصور

يحدّث المثبّت الافتراضي نسخة مصدرية مستخرجة. وفي حاوية، لا تكون تغييرات نظام الملفات دائمة عند إعادة إنشاء الحاوية. اختر أحد هذه البدائل بدلًا من ذلك:

  • ابنِ صورة جديدة من الإصدار المنزّل وانشرها عبر خط الأنابيب المعتاد لديك.
  • عيّن FASTRESTFUL_UPDATE_INSTALL_SCRIPT مخصصًا يسحب الصورة الجديدة أو يطلق طرح منصتك.
  • استخدم fastrestful_update download لجلب الإصدار والتحقق منه، ثم طبّقه خارج الحاوية قيد التشغيل.
لا تُركّب دليل التحديث أبدًا فوق ملفات مصدر التطبيق. يكتب محدّث النظام الحزم والنسخ الاحتياطية في ذلك الدليل؛ ويمكن أن يؤدي نسخ المصدر فوقها إلى إفساد كليهما.

الجزء 7 — التهيئة

المتغيرالافتراضيالغرض
FASTRESTFUL_VERSION1.0.0الإصدار المعروض على LicenseHub والمقارن بالإصدارات. تضبطه عمليات بناء الإصدارات الرسمية.
DAKIDARTS_LICENSEHUB_URLhttps://dakidarts.comأصل LicenseHub للتفعيل والنبضات والفحوص.
FASTRESTFUL_UPDATE_DIR<repo>/updatesدليل تجهيز خاص للأصول والحزم والنسخ الاحتياطية.
FASTRESTFUL_UPDATE_TIMEOUT_SECONDS900الحد الأقصى لمدة تشغيل المثبّت.
FASTRESTFUL_UPDATE_INSTALL_SCRIPTinstall.shمسار المثبّت نسبةً إلى الحزمة المستخرجة.
FIELD_ENCRYPTION_KEYمطلوب في الإنتاجيشفّر مفتاح الشراء. انسخه احتياطيًا. فقدانه يتطلب إعادة ربط الترخيص.

الجزء 8 — استكشاف الأخطاء وإصلاحها

العَرَضما الذي يجب فحصه
license_key_requiredالمفتاح مفقود أو تم مسحه. أعد الاتصال من /admin/updates/.
activation_not_foundأُلغي تفعيل التثبيت في بوابة العملاء أو استُبدل. أعد الاتصال أو أعد التفعيل.
updates_expiredجدّد استحقاق التحديث في بوابة Dakidarts. يبقى التثبيت الحالي قيد التشغيل.
activation_limitألغِ تفعيل تثبيت قديم في بوابة Dakidarts، ثم أعد المحاولة.
فشل المجموع الاختباري للتنزيلأعد المحاولة. افحص وجود وكيل أو ذاكرة تخزين مؤقت تفسد الأصول. لا تشغّل الحزمة.
لا يوجد سكربت تثبيتحزمة الإصدار غير مكتملة. استخدم سير عمل النشر لديك أو أعد بناء الإصدار باستخدام scripts/install-release.sh.
نجح التثبيت لكن الإصدار لم يتغيّرأعد تشغيل الواجهة الخلفية والعاملات والواجهة الأمامية. لا تزال العملية قيد التشغيل تستخدم الشفرة السابقة.
تفشل فحوص السلامة بعد تحديثاقرأ سجل التحديث، ثم استعد نسخة المصدر السابقة الاحتياطية من FASTRESTFUL_UPDATE_DIR/backups/ ونسخة قاعدة البيانات المطابقة إذا لزم الأمر.

الجزء 9 — ملاحظات الأمان

  • لا يمكن فتح مركز التحديثات إلا للموظفين الذين يملكون licensing.change_licenseconnection.
  • حماية CSRF مفروضة على كل إجراء.
  • مفتاح الشراء مشفّر عند التخزين ولا يُعرض أبدًا بعد التفعيل.
  • تستخدم التنزيلات رموز LicenseHub قصيرة العمر. ويُتحقق من الأصول عبر SHA-256 وتوقيع بيان Ed25519 قبل الاستخراج أو التنفيذ.
  • يرفض استخراج الأرشيف المسارات المطلقة والاجتياز والروابط الرمزية والروابط الصلبة.
  • أبقِ دليل التحديث خاصًا. لا تخدمه من Nginx أو تخزين الكائنات.
  • لا يؤدي انقطاع LicenseHub أو انتهاء نافذة التحديث إلى إخراج بوابة قيد التشغيل من الخدمة. الإلغاء يحجب التنزيلات الرسمية؛ لكنه لا يوقف عن بُعد تثبيتًا دائمًا قائمًا.

لمسؤولي الإصدارات

الإصدارات الرسمية أصول خاصة في LicenseHub. قد تحتوي الحزمة على أرشيف مصدر واحد أو عدة أصول (المصدر، والترحيلات، والواجهة الأمامية، والوثائق). تُستخرج كل الأصول إلى الدليل bundle/ نفسه بالترتيب الذي يعيده LicenseHub.

يجب أن تتضمن الحزمة مثبّتًا في أحد هذه المسارات:

  • install.sh
  • scripts/install.sh
  • scripts/install-release.sh
  • المسار في FASTRESTFUL_UPDATE_INSTALL_SCRIPT

scripts/install-release.sh في هذا المستودع هو التنفيذ المرجعي. انسخه إلى جذر حزمة الإصدار باسم install.sh. يأخذ لقطة للمصدر وقاعدة البيانات السابقين، ويغطّي المصدر الجديد، ويحافظ على الأسرار والوسائط وملفات قاعدة البيانات المحلية، ويثبّت تبعيات الواجهة الخلفية، ويشغّل ترحيلات Django، ويطبع متطلب إعادة التشغيل.

يتلقى المثبّت FASTRESTFUL_RELEASE_DIR، وFASTRESTFUL_BUNDLE_DIR، وFASTRESTFUL_UPDATE_DIR، وFASTRESTFUL_APP_ROOT، وFASTRESTFUL_FROM_VERSION، وFASTRESTFUL_TO_VERSION، وFASTRESTFUL_PYTHON، وFASTRESTFUL_INSTALL_LOG. ويعمل باستخدام bash، مع مهلة وسجل ملتقط. يجب أن يكون غير تفاعلي وأن يبقي التثبيت قابلًا للاستعادة إذا فشل.

النشر والتشغيلقراءة 8 دقائق

استكشاف الأخطاء وإصلاحها

الأخطاء التي تواجهها الفرق غالبًا — والفحوص التي تحلّها.

تعيد API رمز 401 أو 403

  • 401: رمز bearer مفقود/منتهي الصلاحية، أو X-API-Key مفقود، أو مفتاح لا يُحلّ. حدّث JWT أو أصدر مفتاحًا جديدًا.
  • 403: مصادق عليه لكن غير مسموح. افحص عضوية مساحة العمل والدور وحالة الاشتراك واستحقاق endpoint.
  • يجب أن تستخدم استدعاءات البوابة الخارجية X-API-Key (أو مفتاح bearer fr_live_…)، لا JWT الخاص بلوحة التحكم.
  • تحتاج استدعاءات لوحة التحكم إلى Authorization: Bearer <access> وX-Organization: <uuid> معًا.

تفشل طلبات المتصفح بسبب CORS أو CSRF

  • أضف أصل الواجهة الأمامية الدقيق إلى CORS_ALLOWED_ORIGINS وCSRF_TRUSTED_ORIGINS.
  • استخدم المخطط والمضيف والمنفذ نفسها التي يستخدمها المتصفح. localhost و127.0.0.1 أصلان مختلفان.
  • أعد بناء الواجهة الأمامية بعد تغيير NEXT_PUBLIC_API_URL أو NEXT_PUBLIC_SITE_URL.
  • لاستدعاءات البوابة من أصول مستهلكين عشوائية، هيّئ تعبيرات CORS النمطية أو CORS المتساهل على مضيف API الخاص بالمنتج فقط.

يفشل طلب البوابة

العَرَضالفحص
429بلوغ الحصة الشهرية أو حد المعدل لكل دقيقة. افحص استخدام الاشتراك وحدود الخطة.
409إعادة استخدام مفتاح idempotency بمدخل طلب مختلف. استخدم مفتاحًا جديدًا أو أعد الطلب الأصلي.
503 قابل لإعادة المحاولةذاكرة التخزين المؤقت المشتركة غير متاحة، أو الدائرة مفتوحة، أو وضع الصيانة. افحص Redis وتوافر المنصة.
فشل TLS/DNS في المنبعتأكد من أن منبع المورّد HTTPS عام ويُحلّ دون عمليات إعادة توجيه.
مفتاح مرفوضالمفتاح ملغى أو منتهي الصلاحية أو مرتبط بتطبيق آخر، أو اشتراكه غير نشط.
endpoint غير موجوديجب أن يطابق الأسلوب + المسار endpoint في الإصدار المباشر. افحص الإصدار واستحقاق الخطة.

تفشل الترحيلات أو المخطط متأخر

shell
python3.11 manage.py showmigrations
python3.11 manage.py makemigrations --check --dry-run
python3.11 manage.py migrate --noinput
python3.11 manage.py check

إذا تعارض ترحيل مع فرع مخصص، فاحله على نسخة من قاعدة البيانات ولا تعدّل أبدًا ترحيلًا مطبّقًا مسبقًا في الإنتاج.

تعيد الوسائط 404 أو أصل CDN قديمًا

  • الوضع المحلي: تأكد من أن MEDIA_ROOT قابل للكتابة وأن Nginx يخدم /media/.
  • وضع S3: تحقق من أذونات الحاوية والمنطقة وendpoint وأصل CDN. أبقِ الحاوية خاصة عند استخدام OAC.
  • بعد استبدال أصل، أفرغ توزيع CDN أو استخدم إجراء الإفراغ في لوحة الإدارة.
  • تأكد من أن MEDIA_CDN_DOMAIN لا يحتوي على مسار لاحق وأنه يطابق الشهادة.

تفشل webhooks الدفع

ابدأ بالإعداد الخاص بكل مزوّد في بوابات الدفع خطوة بخطوة. ثم افحص ما يلي بالترتيب:

  1. عنوان URL دقيق وعام. سجّل /api/v1/billing/stripe-webhook/ أو /paypal-webhook/ أو /flutterwave-webhook/ أو /paystack-webhook/ أو /razorpay-webhook/ على اسم المضيف نفسه الذي يصل إليه المستخدمون. لن يعمل localhost.
  2. لا تُخلط قيم الاختبار والقيم الحية. مفتاح اختبار مع معرّف webhook حي (أو العكس) يفشل في كل تسليم.
  3. السر من النوع الصحيح. يحتاج Stripe إلى سر توقيع endpoint (whsec_…)، لا مفتاح API السري. ويحتاج Flutterwave إلى تجزئة السر التي أنشأتها. ويحتاج Razorpay إلى سر توقيع webhook.
  4. يستخدم PayPal معرّف webhook، لا سرًا. ضع المعرّف من تطبيق PayPal والبيئة نفسيهما في PAYPAL_WEBHOOK_ID. يتحقق FastRestful من كل حدث عبر API التحقق من توقيع PayPal. ويؤدي معرّف مفقود أو خاطئ إلى Bad signature. راجع استكشاف أخطاء webhook في PayPal.
  5. لا يحتاج Paystack عادةً إلى سر webhook. اترك PAYSTACK_WEBHOOK_SECRET فارغًا؛ يتحقق FastRestful باستخدام PAYSTACK_SECRET_KEY.
  6. أنواع الأحداث محددة. webhook قابل للوصول لكنه غير مشترك في حدث التسوية يترك الفاتورة مفتوحة.
  7. وكيلك يحافظ على رؤوس المزوّد. يجب أن تمرر Nginx وCloudflare وموازنات الأحمال رؤوس التوقيع دون تغيير.
  8. المبلغ والعملة متطابقان. يرفض FastRestful أي تسوية لا تطابق الفاتورة.
  9. افحص الإيصال. افتح Admin → أحداث الدفع؛ تُؤكَّد معرّفات الأحداث المكررة دون تسوية مزدوجة. أعد إرسال الحدث الفاشل من لوحة تحكم المزوّد.

لا يُرسَل البريد الإلكتروني

  • يستخدم التطوير خلفية البريد الإلكتروني في وحدة التحكم. افحص مخرجات الطرفية.
  • يستخدم الإنتاج SMTP افتراضيًا. اختبر المضيف والمنفذ وTLS واسم المستخدم وكلمة المرور.
  • يمكن لإعدادات النشرة الإخبارية تجاوز مرسل البيئة؛ تأكد من المزوّد النشط في الاستوديو.
  • افحص SPF وDKIM وDMARC قبل إلقاء اللوم على قائمة الانتظار. معدلات الارتداد والشكاوى تمنع الإرسال مستقبلًا.

مشكلات بناء الواجهة الأمامية أو المسارات

  • نفّذ npm run typecheck وnpm test قبل تصحيح أخطاء النشر.
  • غالبًا ما تعني صفحة فارغة مدفوعة بـ API أن أصل API غير قابل للوصول أو أن CORS غير مكتمل.
  • إذا كانت صفحات المنتج العامة تعمل لكن /api/{slug} يعيد 404، فتأكد من أن الوكيل يمرر فقط مساحات أسماء Django وليس مسار المنتج المملوك للواجهة الأمامية.
  • بعد تغييرات i18n، نفّذ npm run export:i18n وأعد تشغيل Django.

لا تظهر تعديلات اللغة

  • تُحمّل الفرنسية المضمّنة من حزمة الواجهة الأمامية؛ وتأتي طبقات الإدارة من API اللغة النشطة.
  • احفظ طبقة الإدارة، وتأكد من أن اللغة نشطة، ثم أعد تحميل المتصفح بقوة.
  • بعد تغيير fr.json، صدّر مصدر الواجهة الخلفية وأعد تشغيل API لمسح ذاكرة التخزين المؤقت للعملية.
  • افحص وجود تفضيل لغة قديم في localStorage.
المنصةقراءة 10 دقائق

المصادقة والوصول

يستخدم FastRestful رموز وصول JWT قصيرة العمر، ورموز تحديث دوّارة، وجلسة متصفح Django مشتركة. ويمكن لتسجيل الدخول نفسه فتح وحدة تحكم المستهلك واستوديو المورّد ولوحة إدارة الموظفين.

مسارات المصادقة

المسارendpointالنتيجة
تسجيل الدخول بكلمة المرورPOST /api/v1/auth/token/رمز وصول + رمز تحديث وجلسة Django.
التسجيلPOST /api/v1/auth/register/المستخدم، ومساحة عمل اختيارية، وزوج JWT، وجلسة.
التحديثPOST /api/v1/auth/token/refresh/رمز وصول جديد؛ وتضع الدورة رمز التحديث القديم في القائمة السوداء.
تسجيل الخروجPOST /api/v1/auth/logout/يمسح الجلسة؛ واختياريًا يضع رمز تحديث مقدّمًا في القائمة السوداء.
إعادة تعيين كلمة المرورPOST /api/v1/auth/password-reset/بريد إعادة تعيين لا يكشف وجود الحساب.
تأكيد إعادة التعيينPOST /api/v1/auth/password-reset/confirm/يحل رمز أحادي الاستخدام محل كلمة المرور.
OIDC/api/v1/auth/sso/status|start|callback/تسجيل دخول المزوّد وتبادل الرمز.
SAML 2.0/api/v1/auth/saml/status|metadata|start/مسار مزوّد الخدمة بربط POST.

رؤوس الطلب

طلب API من لوحة التحكم
Authorization: Bearer <access-token>
X-Organization: <organization-uuid>
Content-Type: application/json
طلب بوابة خارجي
X-API-Key: fr_live_…
# backwards-compatible alternative:
Authorization: Bearer fr_live_…

تستخدم لوحة التحكم JWT مع رأس مساحة العمل النشطة الصريح. ويستخدم المستهلكون الخارجيون مفتاح API منتج مشتركًا. لا يجوز استخدام JWT لوحة التحكم مفتاح API للعميل، ولا يجوز إرسال مفتاح API خام إلى endpoints لوحة التحكم.

أدوار مساحة العمل

الدورالوصول المعتاد
المالكتحكم كامل بمساحة العمل، والفوترة، والفريق، وعمليات المورّد. المالك الأخير محمي.
Adminالفريق، والتطبيقات، والمفاتيح، والاشتراكات، والنشر، والفوترة، والدعم.
Developerالتطبيقات، والمفاتيح، واختبار endpoints، ونشر المنتجات حيث يُسمح.
الفوترةالفواتير، وطرق الدفع، والكوبونات، والاسترداد، والدفعات.
Viewerوصول للقراءة فقط إلى موارد مساحة العمل.

وصول موظفي المنصة منفصل: يتطلب is_staff ولا ينتج أبدًا عن دور admin في مساحة العمل. وتُفرض أذونات الموظفين لكل نموذج Django وإجراء إداري.

المصادقة الثنائية

  • تسجيل أداة مصادقة TOTP مع رمز QR/URI التهيئة ورموز استرداد أحادية الاستخدام.
  • تُعرض رموز الاسترداد مرة واحدة، وتُجزّأ عند التخزين، وتُعاد إنشاؤها كمجموعة.
  • يمكن للمستخدم الخارق فرض المصادقة الثنائية على كل حساب في إعدادات الموقع.
  • يمكن تقييد وصول الإدارة حتى تأكيد التسجيل؛ وتعرض وحدة التحكم بوابة إعداد مخصصة.

دعوات مساحة العمل

يدعو المالكون ومسؤولو الإدارة عبر البريد الإلكتروني ويخصصون دورًا. رموز الدعوة مجزأة وأحادية الاستخدام ومرتبطة بالبريد الإلكتروني وتنتهي بعد سبعة أيام ويمكن إعادة إرسالها أو إلغاؤها. ويتطلب قبول الدعوة مستخدمًا مصادقًا عليه ببريد إلكتروني مطابق، ويمكنه إعادة تفعيل عضوية غير نشطة.

API الفريق
GET  /api/v1/organization-invites/
POST /api/v1/organization-invites/          {"email": "...", "role": "developer"}
POST /api/v1/organization-invites/{id}/resend/
POST /api/v1/organization-invites/{id}/revoke/
POST /api/v1/auth/invites/accept/           {"token": "..."}

تهيئة SSO

OIDC

backend/.env
SSO_ISSUER=https://login.example.com/realms/acme
SSO_CLIENT_ID=fastrestful
SSO_CLIENT_SECRET=...
FRONTEND_URL=https://app.example.com

سجّل عنوان URL للاستدعاء https://api.example.com/api/v1/auth/sso/callback/ لدى مزوّد الهوية. تبقى الوجهات النسبية الآمنة ورموز الدعوة عبر رحلة الذهاب والإياب.

SAML 2.0

backend/.env
SSO_SAML_ENABLED=1
SSO_SAML_ENTITY_ID=fastrestful
SSO_SAML_SSO_URL=https://idp.example.com/sso
SSO_SAML_IDP_CERT="-----BEGIN CERTIFICATE-----..."
SSO_SAML_AUDIENCE=fastrestful

ثبّت lxml قبل تمكين SAML. تُخدم البيانات الوصفية على /api/v1/auth/saml/metadata/؛ وهيّئ IdP باستخدام عنوان URL لخدمة مستهلك التأكيد من endpoint البداية.

دورة حياة مفتاح API

  • أنشئ مفتاحًا في التطبيق المحدد؛ يظهر المفتاح الخام مرة واحدة.
  • أرسله كـ X-API-Key أو كبيانات اعتماد bearer fr_live_….
  • دوّر المفتاح لإلغاء القديم وإصدار مفتاح جديد ذريًا.
  • ألغِ المفتاح فورًا عند فقدان بيانات الاعتماد؛ ولا يمكن استرداد القيمة الخام.
  • استخدم نطاق execute أو read لأقل امتياز حيث لا يحتاج العميل إلى إدارة كاملة.
المنصةقراءة 12 دقيقة

منتجات API والإصدارات

المنتج هو الهوية العامة. والإصدار هو العقد غير القابل للتغيير. وتسير endpoints والوثائق وسياسة البوابة واستحقاقات الخطط جميعًا ضمن حدود ذلك الإصدار.

نموذج المنتج

الكيانيملك
Categoryتنقل السوق وتجميعه.
ApiProductالاسم العام، والمعرّف النصي (slug)، والشعار، والفئة، والمورّد، والمنبع، والظهور، والموقع الإلكتروني، وفحص السلامة.
ApiVersionرقم الإصدار، وسجل التغييرات، وعقد OpenAPI، والحالة، وملاحظات الإصدار.
Endpointالأسلوب، والمسار، والملخص، والمعلمات، ووثائق الطلب/الاستجابة، والسياسات، وحد المعدل.
Planالسعر، والفاصل الزمني، والحصة، والتجاوز، والفترة التجريبية، والميزات، واستحقاق endpoint.

إنشاء منتج ونشره

  1. في استوديو المورّد، أنشئ المنتج بالاسم والمعرّف النصي والفئة والعبارة التعريفية وREADME وعنوان URL للمنبع.
  2. أنشئ إصدارًا مسودًّا واستورد عقد OpenAPI 3.x أو Swagger 2.0.
  3. راجع كتالوج endpoints الموفّق ووثائق endpoints.
  4. أنشئ خطة عامة واحدة على الأقل وهيّئ الحصص وحدود المعدل والاستحقاق.
  5. شغّل جاهزية النشر؛ يجب أن تنجح الفحوص الأربعة جميعًا.
  6. أرسل الإصدار للمراجعة، ثم رقّه إلى مباشر.
  7. انشر المنتج. يتقاعد الإصدار المباشر السابق تلقائيًا.

استيراد OpenAPI

shell
curl --request POST \
  --url 'https://api.example.com/api/v1/products/signal-stack/import-spec/' \
  --header 'Authorization: Bearer <access>' \
  --header 'X-Organization: <vendor-org-uuid>' \
  --header 'Content-Type: application/json' \
  --data '{
    "version": "2.5.0",
    "openapi": { "openapi": "3.0.3", "paths": { } },
    "changelog": "Add delivery scheduling."
  }'

ينشئ الاستيراد إصدارًا مسودًّا أو يحدّثه، ويوفّق صفوف endpoints من paths، ويبلّغ عن endpoints المنشأة/المحدّثة/المحذوفة، ويحافظ على حقول سياسة البوابة في العمليات المحتفظ بها. ويُرفض استيراد إصدار مباشر.

جاهزية النشر

البوابةالمتطلب
بيانات تعريف القائمةالاسم والمعرّف النصي والعبارة التعريفية والفئة وREADME موجودة.
المنبعتم تهيئة منبع HTTPS صالح.
إصدار مباشرإصدار مباشر واحد على الأقل بعقد OpenAPI مدعوم وendpoints مطابقة.
خطة عامةخطة عامة واحدة على الأقل متاحة.

آلة حالة الإصدار

تدفق الحالة
draft ──submit_review──► review ──promote──► live ──deprecate──► deprecated
  └───────────────────────promote────────────────┘

# product visibility
draft ──publish──► public ──unpublish──► draft
                       └──retire──► retired ──restore──► draft
  • الإصدارات المباشرة غير قابلة للتغيير: تُرفض التعديلات على مستوى النموذج والمُسلسِل.
  • تقاعد الترقية الإصدار المباشر السابق للحفاظ على ثبات إصدار مباشر واحد.
  • يجب أن يتطابق العقد وكتالوج endpoints تطابقًا تامًا قبل الترقية.
  • تُعاد تعيين استحقاقات endpoints في الخطط حسب الأسلوب + المسار عندما يستبدل إصدار مباشر جديد الإصدار القديم.

تقارير التغييرات الكاسرة

shell
GET /api/v1/versions/{version_id}/diff/?against={previous_version_id}

# Review added, removed, and changed operations before promotion.
# A release can be promoted only after the contract is validated.

توجيه مضيف المنتج

لكل منتج منشور مدخلان متكافئان:

البيئةعنوان URL الأساسي
الإنتاج مع DNS نمطيhttps://{product-slug}.api.example.com
مضيف واحد / التطويرhttps://api.example.com/api/v1/{product-slug}

يقرأ الوسيط أول تسمية في المضيف كمعرّف نصي للمنتج. وتُسجّل أسماء المسارات المستعارة كمسار لاحق، لذا تفوز مسارات API المسماة دائمًا. وتعرض المنتجات غير المعروفة 404 مع تلميح؛ وتعيد الطلبات بلا مفتاح إلى منتجات غير معروفة 401 لتجنب الاستكشاف.

استحقاقات الخطة

  • يمنح all كل endpoint عام في الإصدار المباشر.
  • يمنح selected مجموعة endpoints المهيأة فقط.
  • تُفرض الاستحقاقات المحددة عند البوابة، بما في ذلك طلبات المسار الخام التي تتجاوز كتالوج endpoints.
  • تُقفل الشروط التجارية بعد أول اشتراك؛ أنشئ خطة بديلة بدلًا من تعديل خطة مشترك بها.
المنصةقراءة 11 دقيقة

البوابة والقياس

البوابة هي المسار الوحيد إلى منابع المورّد. فهي تحل المنتج، وتصادق المفتاح، وتفرض سياسة الاشتراك والخطة، وتحجز الحصة، وتمرر بأمان، وتقيس الاستخدام، وتكتب تتبعًا منقّحًا.

خط أنابيب الطلب

  1. حل المنتج من المضيف أو اسم المسار المستعار والعثور على endpoint الإصدار المباشر حسب الأسلوب + المسار.
  2. المصادقة باستخدام JWT/جلسة لوحة التحكم أو بيانات اعتماد خارجية X-API-Key / bearer fr_live_….
  3. حل الاشتراك للمنتج والتطبيق. الاشتراكات النشطة وتجريبية فقط.
  4. التحقق من ربط المفتاح وطبع last_used_at. لا يمكن للمفتاح عبور التطبيقات أو مساحات العمل.
  5. حجز الحصة مقابل العداد الشهري وفرض حدود المعدل لكل endpoint ذريًا.
  6. تشغيل فحوص أمان الشبكة: HTTPS، وDNS عام، ولا إعادة توجيه، ولا اجتياز، وعنوان IP مثبّت.
  7. التمرير مع مهلة وحدود للجسم والتحميل وإعادة محاولات محدودة.
  8. القياس: حدث استخدام، وعداد شهري، وسجل طلب منقّح، ومعاينة استجابة.

استدعاءات المنتج المباشرة

مضيف المنتج
curl --request POST \
  --url 'https://signal-stack.api.example.com/v2/deliveries' \
  --header 'X-API-Key: fr_live_…' \
  --header 'Content-Type: application/json' \
  --data '{"recipient":"maya@example.dev","template":"welcome"}'
اسم مسار مستعار
curl --request GET \
  --url 'https://api.example.com/api/v1/signal-stack/v2/deliveries?limit=10' \
  --header 'X-API-Key: fr_live_…'

يبقى الغلاف القديم POST /api/v1/gateway/execute/ للتكاملات وأدوات وحدة التحكم الحالية. وتستخدم المقاطع الجديدة الصيغة المباشرة.

رؤوس البوابة

الرأسالغرض
X-API-Keyمفتاح منتج مشترك. موصى به للعملاء الخارجيين.
Authorization: Bearer fr_live_…صيغة مفتاح متوافقة مع الإصدارات السابقة.
Idempotency-Keyمفتاح آمن لإعادة التشغيل للاستجابات المكتملة، مدة الصلاحية الافتراضية 24 ساعة.
X-Organizationمساحة عمل لوحة التحكم فقط؛ ليس لعملاء البوابة الخارجيين.

الحصص وحدود المعدل

  • الحصة الشهرية تُحجز قبل التمرير وتُحتسب الطلبات الموجّهة، بما فيها فشل المنبع.
  • الحصة غير المحدودة تزيل الحد الشهري فقط؛ ويظل حد الدقيقة واستحقاق endpoint ساريين.
  • حد المعدل لكل endpoint يستخدم نافذة ثابتة ذرية في ذاكرة التخزين المؤقت. ويعيد انقطاع الذاكرة المشتركة 503 قابلًا لإعادة المحاولة قبل حجز الحصة.
  • التجاوز يُفوتر لكل 1,000 طلب عند تهيئته؛ ويعني الصفر التنبيه فقط.

idempotency وإعادة المحاولات

  • تُخزّن الاستجابات المكتملة مع تجزئة رمز SHA-256 وبصمة الطلب واستجابة منقّحة لمدة الصلاحية المهيأة.
  • تعيد عمليات إعادة التشغيل الاستجابة المخزنة قبل حجز الحصة أو استدعاء المنبع.
  • إعادة استخدام مفتاح بمدخل طلب مختلف تعيد 409.
  • إعادة المحاولات محدودة وتنطبق فقط على الأعطال العابرة الآمنة؛ ولا تُعاد الأساليب غير الآمنة التكرارية (non-idempotent) بشكل أعمى.
  • تفتح قاطع الدائرة بعد أعطال متكررة في المنبع ويعيد 503 قابلًا لإعادة المحاولة أثناء التبريد.

حماية SSRF وأمان الشبكة

  • يجب أن تكون المنابع HTTPS عامة. وتُرفض إجابات DNS الخاصة والحلقية والرابط المحلي وغير الآمنة.
  • يجب أن يبقى المسار على المضيف الأصلي. ويُرفض اجتياز ...
  • لا تُتبع عمليات إعادة التوجيه.
  • يُثبّت عنوان DNS العام المحدد عبر اتصال TLS لمنع إعادة الربط.
  • تُرفق أسرار المورّد من جهة الخادم ولا تُعاد أبدًا إلى المتصفح.
  • معاينات الاستجابة محدودة وتنقّح ملفات تعريف الارتباط والتفويض ورؤوس مفتاح API.

سجلات الطلبات والقياس

  • عرض المستهلك: سجل طلبات مساحة العمل النشطة مع البحث وتصفية الحالة والتصدير إلى CSV.
  • عرض المورّد: سجلات على مستوى الطلب عبر المنتجات المملوكة، مع المستهلك وendpoint والزمن والحالة ومعاينات منقّحة.
  • أحداث الاستخدام: رمز الحالة، والزمن، والاشتراك، والمنتج، وendpoint، والطابع الزمني.
  • العدادات الشهرية: نموذج قراءة الحصة والتحليلات.
  • يمكن تهيئة الاحتفاظ باستخدام prune_telemetry.

بيئة البوابة

كل المهل والحدود وميزانيات إعادة المحاولة وحدود الدائرة ومدة idempotency ونطاقات CIDR للوكيل الموثوق وحدود معاينة الوسائط ولاحقة مضيف المنتج تُدار عبر البيئة. راجع التهيئة للجدول الكامل.

المنصةقراءة 14 دقيقة

الفوترة والدفعات

للفوترة مهمتان: تمكين المستهلكين من الدفع مقابل خطط API، وتمكين مشغّل المنصة من تحصيل مقابل سعة مساحة العمل. وكلتاهما تستخدم المزوّدين والفواتير وتسوية webhook نفسها.

هل تربط مزوّدًا لأول مرة؟ اقرأ بوابات الدفع خطوة بخطوة أولًا. يغطي هذا الدليل لوحة تحكم المزوّد وعناوين URL لـ webhook ومعرّف webhook الخاص بـ PayPal وعمليات الدفع التجريبية. يشرح هذا الدليل ما يحدث بعد توصيل المزوّد.

مستويا الفوترة

فكّر فيهما كصندوقَي تسجيل نقدي منفصلين:

المستوىمن يدفعمن يستلمما الذي يفتحه
خطط API للمورّدمستهلك APIمورّد API، ناقص رسوم السوقالطلبات إلى ذلك المنتج، وفق حصته وحد معدله.
خطط المنصةمالك مساحة العملمشغّل المنصةعدد مساحات العمل وحدود إدراج API على المنصة نفسها.

كلتاهما تستخدم الدفع المستضاف وwebhooks الموقعة والفواتير والتسوية. تتدفق إيرادات API الخاصة بالمورّد إلى تسوية الدفعات؛ أما إيرادات اشتراكات المنصة فلا.

خطط المورّد

  • فاصل شهري أو سنوي، وعملة، وسعر، ووصف.
  • الحصة الشهرية، وحد المعدل لكل دقيقة، والتجاوز لكل 1,000 طلب، وأيام التجربة.
  • حتى ثمانية أسطر ميزات عامة وخطة عامة موصى بها واحدة.
  • استحقاق endpoint من نوع all أو selected.
  • تُقفل الشروط التجارية بعد أول اشتراك؛ استخدم خطة بديلة لإجراء التغييرات.

الدفع والتسوية

  1. يختار المستهلك خطة ويقبل شروط API.
  2. يُنشأ اشتراك معلّق وفاتورة الفترة الأولى.
  3. يفتح المزوّد المهيأ الدفع المستضاف.
  4. يرسل المزوّد webhook موقّعًا بعد الدفع.
  5. يتحقق FastRestful من التوقيع، ويسجل حدث المزوّد، ويتحقق من المبلغ/العملة، ويعلّم الفاتورة مدفوعة.
  6. لا يفعّل الاستحقاق إلا بعد التسوية. ولا تمنح عمليات إعادة توجيه المتصفح وصولًا أبدًا.
webhooks المزوّد
POST /api/v1/billing/stripe-webhook/
POST /api/v1/billing/paypal-webhook/
POST /api/v1/billing/flutterwave-webhook/
POST /api/v1/billing/paystack-webhook/
POST /api/v1/billing/razorpay-webhook/

دعم المزوّد

لكل مزوّد أدناه دليل إعداد خطوة بخطوة في بوابات الدفع خطوة بخطوة.

المزوّدالدفعالدفعاتبيانات الاعتماد
Stripeنعم، PaymentIntent مضمّن أو مستضافربط التحويلاتSTRIPE_SECRET_KEY، STRIPE_WEBHOOK_SECRET
PayPalاشتراكات الفوترةالدفعاتمعرّف العميل/السر، ومعرّف webhook
Flutterwaveدفع مستضافتسوية يدويةمفتاح عام/سري/سر webhook
Paystackدفع مستضافتسوية يدويةمفتاح عام/سري/سر webhook
Razorpayدفع مستضافتسوية يدويةمعرّف المفتاح/السر/سر webhook

تتجاوز Admin → بوابات الدفع بيانات اعتماد البيئة حقلًا بحقل. ويؤدي تعطيل سجل بوابة إلى إيقاف ذلك المزوّد في كل مكان، حتى لو بقيت مفاتيح البيئة.

المبالغ المستردة

  • يسترد المورّدون الذين لديهم إذن الفوترة الفواتير المدفوعة عبر البوابة الأصلية.
  • تُسوّى عمليات استرداد Stripe تراكميًا من أحداث webhook؛ وتؤكد البوابات المستضافة بشكل متزامن.
  • مفاتيح idempotency وطلبات الاسترداد المعلقة تجعل إعادة المحاولات آمنة.
  • الاسترداد الكامل يعلّم الفاتورة كمستردة.
  • تضيف عمليات الاسترداد بعد الدفعة قيود استرداد إيرادات المورّد وعكس الرسوم النسبي إلى دفتر الأستاذ.
  • لا يمكن للمستهلكين استرداد الأموال بأنفسهم؛ ويجب استرداد المدفوعات اليدوية عبر مزوّدها.

الدفعات

حالة الدفعة
pending ──► in_transit ──► paid
   │              │
   ├──► failed ◄──┘
   └──► reversed

# Only paid invoices settle. Refunds reduce the next transfer.
# Gross collected revenue is stored separately from net transfer.
# Provider event IDs are unique and retries are idempotent.
  • هيّئ وجهة مورّد باستخدام PATCH /api/v1/orgs/{id}/payout-provider/ (acct_… لـ Stripe أو البريد الإلكتروني لـ PayPal).
  • ابدأ تحويلًا باستخدام POST /api/v1/payouts/{id}/transfer/.
  • سوِّ باستخدام POST /api/v1/payouts/{id}/reconcile/؛ تتطلب الحالات الصارمة معرّف تحويل أو سبب فشل.
  • تُسوّي webhooks Stripe transfer.created|paid|failed|reversed.

اشتراكات المنصة

يجب تفعيل وضع تعدد المورّدين. يكون دفع اشتراك المنصة غير متاح ما دام وضع تعدد المورّدين معطلًا في إعدادات الموقع. فعّله قبل بيع خطط مساحات العمل.
  • تُدار خطط المنصة في Admin → خطط المنصة؛ بحد أقصى خمس خطط.
  • يمكن لكل خطة تحديد حدود مساحات العمل المملوكة وإدراج API والمزايا وتوصية.
  • تبقى الخطط المدفوعة غير منشورة حتى تهيئة مبلغ عرض ومعرّف سعر متكرر مطابق لدى المزوّد.
  • تُنشأ جلسات الدفع وبوابة الفوترة من الخادم بوجهات FRONTEND_URL ثابتة.
  • تسوية الاشتراك للقراءة فقط في لوحة الإدارة كي لا تنحرف تغييرات الموظفين عن المزوّد.

أوامر التسوية

shell
python3.11 manage.py generate_invoices --period 2026-10
python3.11 manage.py generate_payouts --period 2026-10

# Both commands are idempotent and safe to rerun.

تعمل مهمة Celery الشهرية في اليوم الأول الساعة 00:05 UTC. وبدون وسيط، استدعِ الأوامر يدويًا.

بيئة المزوّد

راجع التهيئة → المدفوعات والدفعات لكل متغير. على الأقل: سر/webhook Stripe، أو عميل/webhook PayPal، أو ثلاثي البوابة المستضافة العام/السري/webhook. وتحتاج واجهة البطاقة الأمامية أيضًا إلى NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY.

المنصةقراءة 24 دقيقة

بوابات الدفع خطوة بخطوة

اربط مزوّد دفع حقيقيًا دون تخمين. لكل قسم مزوّد نصفان: ما تنقر عليه في لوحة تحكم المزوّد، ثم ما تدخله في FastRestful. ويتضمن PayPal جولة كاملة في webhooks، بما في ذلك مكان العثور على معرّف webhook الذي يتطلبه FastRestful.

قبل أن تبدأ

تحتاج إلىالسبب
عنوان URL عام عبر HTTPSيجب أن يتمكن كل مزوّد من الوصول إلى endpoint webhook لديك. لن يعمل localhost في لوحة تحكم مزوّد حقيقية.
حساب اختبار أولًااستخدم وضع sandbox/الاختبار حتى تُسوّى دفعة اختبارية. لا تصحح الأخطاء بأموال حقيقية أبدًا.
وصول إداريستهيّئ المزوّدين في Admin → بوابات الدفع أو في backend/.env.
خطة للبيعتُنشأ خطط API للمورّد في استوديو المورّد. وتُنشأ خطط المنصة في Admin → خطط المنصة.
مزوّد واحد في كل مرة. اضبط Stripe، ونفّذ دفعة تجريبية، وتأكد من سداد الفاتورة قبل إضافة PayPal أو بوابة مستضافة. أخطاء المزوّد أسهل بكثير في الاكتشاف عندما يتغير شيء واحد فقط.
تعمل الخطط المجانية دون مزوّد. لا يمكن فتح إتمام الشراء المدفوع حتى يتم تفعيل بوابة واحدة على الأقل. إذا قال الدفع “No payment provider is configured”، فأكمل قسم مزوّد واحد أدناه أولًا.
تتغير لوحات تحكم المزوّدين. استخدم هذه الخطوات كخريطة، لا كلقطة شاشة. إذا اختلف اسم عنصر في القائمة، فابحث عن المفهوم نفسه: مفاتيح API أو webhooks أو المنتجات أو الأسعار أو الدفعات.

كيف يتحرك المال في FastRestful

  1. ينشئ FastRestful فاتورة.

    يوجد الاشتراك وفاتورة الفترة الأولى قبل فتح الدفع. ولا شيء معلّم كمدفوع بعد.

  2. للخطط المدفوعة، يفتح المزوّد الدفع.

    يدفع العميل على صفحة المزوّد المستضافة. ويخزّن FastRestful مرجع الدفع فقط.

  3. يرسل المزوّد webhook موقّعًا.

    يتحقق FastRestful من التوقيع، ويسجل الحدث مرة واحدة، ويفحص المبلغ والعملة.

  4. تُسوّى الفاتورة.

    عندها فقط يُفعّل الاشتراك ويبدأ الاستحقاق. ولا تمنح إعادة توجيه المتصفح وصولًا أبدًا.

webhooks هي مصدر الحقيقة. إذا دفع العميل لكن لم يصل webhook أبدًا، تبقى الفاتورة مفتوحة. لوحة تحكم المزوّد هي المكان المناسب لفحص عملية التسليم وإعادة إرسالها.

أين تذهب بيانات الاعتماد

يمكنك وضع بيانات الاعتماد في backend/.env أو في Admin → بوابات الدفع. سجلات الإدارة أسهل في التدوير وتتجاوز قيم البيئة حقلًا بحقل. ويؤدي تعطيل سجل إداري إلى إيقاف المزوّد في كل مكان، حتى لو بقيت مفاتيح البيئة.

المزوّدحقل عامحقل سريحقل webhook
Stripe—المفتاح السري (sk_…)سر التوقيع (whsec_…)
PayPalمعرّف العميلسر العميلمعرّف webhook (ليس سرًا وليس عنوان URL)
Flutterwaveالمفتاح العامالمفتاح السري (FLWSECK-…)تجزئة السر التي تنشئها
Paystackالمفتاح العام (pk_…)المفتاح السري (sk_…)اتركه فارغًا لاستخدام المفتاح السري
Razorpayمعرّف المفتاح (rzp_…)سر المفتاحسر توقيع webhook
أسماء حقول الإدارة عامة. في نموذج بوابة الدفع، المفتاح العام يعني المعرّف العام/معرّف العميل لدى المزوّد، المفتاح السري يعني سر API الخاص به، و سر webhook يعني قيمة توقيع webhook. وبالنسبة إلى PayPal، فهي Client ID وClient secret وWebhook ID على الترتيب.

اختبار webhooks على حاسوبك المحمول

لا يمكن للمزوّدين الوصول إلى http://127.0.0.1:5056. استخدم أحد هذه الأساليب للاختبار المحلي.

Stripe CLI

  1. ثبّت Stripe CLI وسجّل الدخول.

    اتبع دليل التثبيت الخاص بـ Stripe CLI، ثم نفّذ stripe login ووافق على مطالبة المتصفح.

  2. مرّر الأحداث إلى واجهتك الخلفية المحلية.
    shell
    stripe listen --forward-to localhost:5056/api/v1/billing/stripe-webhook/
  3. انسخ سر التوقيع المطبوع.

    تطبع CLI whsec_…. ضعه في STRIPE_WEBHOOK_SECRET أو في سجل Stripe الإداري. أبقِ CLI قيد التشغيل.

  4. أطلق حدث اختبار.
    shell
    stripe trigger checkout.session.completed
    stripe trigger invoice.paid

PayPal وFlutterwave وPaystack وRazorpay

تحتاج هذه المزوّدين إلى عنوان URL عام عبر HTTPS. استخدم نفقًا مثل ngrok أو Cloudflare Tunnel، ثم سجّل عنوان URL للنفق في لوحة تحكم المزوّد:

shell
# Example with ngrok
ngrok http 5056

# Use the generated https URL, for example:
# https://abc123.ngrok-free.app/api/v1/billing/paypal-webhook/

هل ستغيّر عنوان URL للنفق لاحقًا؟ حدّث لوحة تحكم المزوّد ووجهة webhook في FastRestful معًا. عنوان URL القديم هو السبب الأكثر شيوعًا لعبارة «نجح الدفع لكن الفاتورة لم تُغلق أبدًا».

يوفر PayPal أيضًا محاكي webhook في لوحة تحكم المطوّر. وجّهه إلى عنوان URL للنفق واستخدم معرّف webhook من تطبيق sandbox نفسه كي يتمكن FastRestful من التحقق من الحدث المحاكى.

اختيار مزوّد

المزوّدالدفعالدفعاتالأنسب
Stripeدفع مستضاف أو واجهة بطاقة مضمّنةربط التحويلاتالبطاقات والمحافظ العالمية والدفعات الآلية للمورّدين.
PayPalطلبات PayPal Checkout؛ وPayPal Billing لخطط المنصةPayPal Payoutsالمشترون الذين يفضلون أرصدة PayPal والبطاقات واشتراكات PayPal.
Flutterwaveدفع مستضافتسوية يدويةالأسواق الأفريقية بطرق دفع محلية.
Paystackدفع مستضافتسوية يدويةنيجيريا وغانا وكينيا وجنوب أفريقيا.
Razorpayروابط الدفعتسوية يدويةالهند، مع تسعير أولوية بـ INR.
خطط المورّد مقابل خطط المنصة. تُفوتَر اشتراكات خطط API الخاصة بالمورّد عبر فواتير FastRestful: تفتح الفترة الأولى دفعًا مستضافًا، وتُنشأ الفواتير اللاحقة بواسطة مهمة التسوية. تستخدم اشتراكات المنصة الفوترة المتكررة لدى المزوّد: Stripe Prices أو خطط PayPal Billing. يتطلب دفع اشتراك المنصة أيضًا تفعيل وضع تعدد المورّدين في إعدادات الموقع. ويُضبط كل منهما في مكان مختلف.

Stripe خطوة بخطوة

1. أنشئ حساب Stripe وفعّله

  1. أنشئ حساب Stripe وأكمل ملف الأعمال.
  2. أبقِ وضع الاختبار مفعّلًا أثناء التكامل. المفتاح في الشريط العلوي من Stripe Dashboard.
  3. يمكنك تحصيل مدفوعات اختبارية قبل أن ينهي Stripe تفعيل الحساب.

2. انسخ مفاتيح API

  1. افتح Developers → API keys.

    في Stripe Dashboard، افتح Developers ثم API keys.

  2. انسخ المفتاح السري.

    استخدم المفتاح السري للاختبار أولًا (sk_test_…). ضعه في STRIPE_SECRET_KEY أو في سجل Stripe الإداري. لا تضع المفتاح السري أبدًا في كود الواجهة الأمامية.

  3. انسخ المفتاح القابل للنشر.

    ضع مفتاح النشر التجريبي (pk_test_…) في NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY إذا أردت واجهة البطاقة المضمّنة. أعد بناء الواجهة الأمامية بعد تغييره.

3. أضف endpoint webhook الخاص بـ Stripe

  1. افتح Developers → Webhooks → Add endpoint.
  2. عيّن عنوان URL للـ endpoint.
    عنوان URL للإنتاج أو التجهيز
    https://api.example.com/api/v1/billing/stripe-webhook/
  3. حدّد الأحداث التي يطابقها FastRestful.
    • checkout.session.completed
    • invoice.paid وinvoice.payment_succeeded
    • invoice.payment_failed
    • customer.subscription.created، customer.subscription.updated، customer.subscription.deleted
    • charge.refunded
    • transfer.created، transfer.paid، transfer.failed، transfer.reversed (الدفعات)
  4. انسخ سر التوقيع.

    يعرض Stripe قيمة تبدأ بـ whsec_…. هذه هي STRIPE_WEBHOOK_SECRET. وهي ليست المفتاح السري لواجهة API.

يوقّع Stripe كل عملية تسليم. يرفض FastRestful التوقيعات القديمة ويفشل بشكل مغلق عند غياب STRIPE_WEBHOOK_SECRET، لذا فإن سر التوقيع الصحيح إلزامي.

4. أضف Stripe في FastRestful

افتح Admin → Payment gateways وحرّر صف Stripe (مستحسن)، أو استخدم متغيرات البيئة.

حقل FastRestfulقيمة Stripe
الوضعاختبر حتى ينجح sandbox، ثم انتقل إلى Live.
المفتاح السريsk_test_… أو sk_live_…
سر webhookwhsec_…

إذا استخدمت متغيرات البيئة بدلًا من ذلك، فعيّن STRIPE_SECRET_KEY وSTRIPE_WEBHOOK_SECRET، ثم أعد تشغيل الخادم الخلفي والعاملين.

5. خطط المنصة وأسعار Stripe

مطلوب فقط إذا كنت تبيع اشتراكات المنصة. تستخدم خطط API الخاصة بالمورّد سعر المنتج نفسه ولا تحتاج إلى Stripe Price.

  1. أنشئ منتجًا (Product) في Stripe.

    افتح Product catalog → Add product. سمّه باسم خطة منصتك.

  2. أضف سعرًا متكررًا (Price).

    استخدم المبلغ والعملة وفترة الفوترة نفسها التي تعرضها خطة منصتك. يجب أن تكون الأسعار الشهرية والسنوية أسعارًا منفصلة.

  3. انسخ معرّف كل Price.

    تبدأ معرّفات Price بـ price_….

  4. الصقها في خطة المنصة.

    افتح Admin → Platform plans واملأ Stripe monthly price ID وStripe annual price ID.

يتحقق FastRestful من Price مقابل مبلغ الخطة وعملتها وفترتها عند الدفع. يؤدي عدم التطابق إلى إرجاع 409 مع توضيح بدلًا من تحصيل مبلغ خاطئ.

6. Stripe Connect لدفعات المورّدين

  1. فعّل Connect في Stripe وأنشئ حسابًا متصلًا لكل مورّد تدفع له.
  2. انسخ معرّف الحساب المتصل (acct_…).
  3. خزّنه كوجهة المورّد عبر PATCH /api/v1/orgs/{id}/payout-provider/ أو من إعدادات دفعات المورّد.
  4. اختياريًا، عيّن PAYOUT_PROVIDER=stripe للسماح بدفعات Stripe فقط.
  5. أبقِ أحداث transfer.* محددة على webhook الخاص بـ Stripe.

7. اختبر Stripe

  1. استخدم بطاقة الاختبار 4242 4242 4242 4242، وأي تاريخ انتهاء مستقبلي، وأي CVC.
  2. أكمل عملية دفع وتأكد من أن الفاتورة أصبحت مدفوعة.
  3. تأكد من أن الاشتراك أصبح نشطًا وأن مفتاح المستهلك يعمل.
  4. افتح Admin → Payment events وتأكد من معالجة الحدث مرة واحدة.
  5. أطلق استردادًا وتأكد من صحة حالة استرداد الفاتورة.

PayPal، خطوة بخطوة

PayPal هو المزوّد الذي يتطلب أكبر عدد من الخطوات على جانب المنصة. يستخدم FastRestful منتجين مختلفين من PayPal: Checkout orders لعمليات شراء خطط API الخاصة بالمورّدين، وBilling subscriptions لخطط المنصة. وكلاهما يستخدم بيانات اعتماد التطبيق نفسه وwebhook نفسه.

1. أنشئ تطبيق PayPal وانسخ بيانات الاعتماد

  1. افتح PayPal Developer Dashboard.

    انتقل إلى developer.paypal.com وسجّل الدخول بحساب PayPal للأعمال.

  2. اختر Sandbox أو Live.

    استخدم مفتاح التبديل Sandbox/Live في الأعلى. لكل من Sandbox وlive تطبيقات وبيانات اعتماد ومعرّفات webhook منفصلة.

  3. افتح Apps & Credentials → Create App.

    أعطه اسمًا مثل FastRestful وحدّد حساب الأعمال الذي يجب أن يستقبل المدفوعات.

  4. انسخ Client ID وSecret.

    يُوضعان في PAYPAL_CLIENT_ID وPAYPAL_CLIENT_SECRET (أو في سجل PayPal الإداري). إذا كان السر مخفيًا، فاستخدم إجراء إعادة الإنشاء في التطبيق وانسخ القيمة الجديدة.

2. أضف webhook الخاص بـ PayPal (مطلوب)

هذه هي الخطوة التي يفوّتها معظم الناس. بدون معرّف webhook، يرفض FastRestful كل حدث PayPal وتبقى الطلبات المدفوعة غير مدفوعة.

  1. افتح تطبيقك في Apps & Credentials.
  2. مرّر وصولًا إلى Webhooks وانقر على Add Webhook.

    قد تكون التسمية الدقيقة Webhooks أو Add Webhook حسب إصدار لوحة PayPal.

  3. أدخل عنوان URL الخاص بـ webhook.
    عنوان URL الخاص بـ webhook PayPal
    https://api.example.com/api/v1/billing/paypal-webhook/

    يجب أن يكون عنوان URL عامًا عبر HTTPS. إعادة توجيه المتصفح ليست دليلًا على الدفع؛ يرسل PayPal أحداثًا موقّعة إلى هذا العنوان، وهذه الأحداث هي التي تسوّي الفاتورة.

  4. حدّد أنواع الأحداث.
    مجموعة الأحداثالتحديدلماذا يحتاجها FastRestful
    Checkout ordersCHECKOUT.ORDER.APPROVED، PAYMENT.CAPTURE.COMPLETEDيلتقط مدفوعات خطط API الخاصة بالمورّدين ويسوّيها.
    الاشتراكاتBILLING.SUBSCRIPTION.ACTIVATED، BILLING.SUBSCRIPTION.CANCELLED، BILLING.SUBSCRIPTION.SUSPENDED، BILLING.SUBSCRIPTION.EXPIREDيفعّل اشتراكات المنصة ويحدّثها. ACTIVATED هو الحدث الذي يمنح الاستحقاق.
    مدفوعات الاشتراكPAYMENT.SALE.COMPLETEDيسجّل التجديدات ويعيد تفعيل اشتراكات المنصة المتأخرة.
    الدفعاتPAYMENT.PAYOUTS-ITEM.SUCCEEDED، PAYMENT.PAYOUTS-ITEM.FAILED، PAYMENT.PAYOUTS-ITEM.BLOCKED، PAYMENT.PAYOUTS-ITEM.RETURNED، PAYMENT.PAYOUTS-ITEM.CANCELEDيطابق تحويلات دفعات المورّدين.
  5. احفظ webhook وانسخ Webhook ID.

    افتح webhook المحفوظ إذا لزم الأمر. يعرض PayPal معرّف webhook (سلسلة قصيرة من الحروف والأرقام). هذا هو PAYPAL_WEBHOOK_ID. وهو ليس عنوان URL الخاص بـ webhook وليس سر العميل.

لماذا يختلف PayPal. لا يجزّئ FastRestful حمولة PayPal باستخدام سر مشترك. بل يرسل ترويسات webhook وجسم الحدث إلى /v1/notifications/verify-webhook-signature endpoint الخاص بـ PayPal مع معرّف webhook المخزّن. إذا كان المعرّف مفقودًا، أو من البيئة الأخرى، أو من تطبيق آخر، تفشل عملية التحقق ويعيد FastRestful 400 Bad signature. هذا سلوك مقصود للإغلاق عند الفشل.

3. أضف PayPal في FastRestful

حقل FastRestfulقيمة PayPal
معرّف العميلApp Client ID
سر العميلApp Secret
Webhook IDمعرّف webhook الذي نسخته في الخطوة السابقة
الوضعTest لـ sandbox، وLive للإنتاج

افتح Admin → Payment gateways وحرّر صف PayPal. في هذا النموذج، Public key هو Client ID، وSecret key هو Client secret، وWebhook secret هو Webhook ID.

إذا كنت تفضّل متغيرات البيئة:

backend/.env
PAYPAL_CLIENT_ID=...
PAYPAL_CLIENT_SECRET=...
PAYPAL_WEBHOOK_ID=...
PAYPAL_ENV=sandbox          # use live in production
# PAYPAL_API_BASE=          # only for a proxy or custom host

أعد تشغيل الخادم الخلفي والعاملين بعد تغيير قيم البيئة. إذا استخدمت السجل الإداري، فاحفظه وفعّله؛ لا حاجة لإعادة التشغيل.

4. خطط PayPal Billing لاشتراكات المنصة

تخطَّ هذا ما لم تكن تبيع اشتراكات المنصة عبر PayPal. تستخدم خطط API الخاصة بالمورّدين أوامر Checkout لمرة واحدة ولا تحتاج إلى خطة PayPal Billing.

  1. أنشئ منتجًا في PayPal.

    في لوحة PayPal، افتح منطقة Billing/Subscriptions وأنشئ منتجًا يمثّل منصتك.

  2. أنشئ خطة شهرية و/أو سنوية.

    عيّن المبلغ والعملة والفترة نفسها المطابقة للخطة في FastRestful. أنشئ خطة منفصلة لكل فترة.

  3. انسخ معرّف كل خطة.

    تبدأ معرّفات خطط PayPal بـ P-….

  4. الصقها في خطة المنصة.

    افتح Admin → Platform plans واملأ PayPal monthly plan ID وPayPal annual plan ID.

  5. تأكد من أن webhook يتضمن أحداث الاشتراك.

    يُنشأ الاشتراك في حالة PENDING. ولا يصبح نشطًا إلا بعد وصول BILLING.SUBSCRIPTION.ACTIVATED.

5. PayPal Payouts للمورّدين

  1. تأكد من أن حساب PayPal للأعمال معتمد لـ Payouts.
  2. خزّن بريد مستلم PayPal الخاص بالمورّد كوجهة دفع له عبر PATCH /api/v1/orgs/{id}/payout-provider/.
  3. اختياريًا، عيّن PAYOUT_PROVIDER=paypal، أو PAYOUT_PROVIDER=stripe,paypal للسماح بكل منهما.
  4. أبقِ أحداث PAYMENT.PAYOUTS-ITEM.* محددة على webhook.

6. اختبر PayPal sandbox

  1. استخدم بيانات اعتماد sandbox.

    عيّن PAYPAL_ENV=sandbox، واستخدم Client ID وsecret الخاصين بتطبيق sandbox، ومعرّف webhook الخاص بـ sandbox.

  2. أنشئ حساب مشترٍ في sandbox.

    يوفر PayPal Developer Dashboard حسابات شخصية تجريبية. سجّل الدخول إلى sandbox.paypal.com بذلك المشتري عند فتح صفحة الدفع.

  3. أكمل عملية دفع تجريبية.

    وافق على الطلب وانتظر إعادة التوجيه إلى FastRestful.

  4. تحقق من استلام webhook.

    افتح Admin → Payment events. يجب أن ترى CHECKOUT.ORDER.APPROVED، ثم PAYMENT.CAPTURE.COMPLETED، ويجب أن تصبح الفاتورة مدفوعة.

  5. أعد إرسال عملية تسليم إذا لزم الأمر.

    في لوحة PayPal، افتح عمليات تسليم الأحداث الخاصة بـ webhook وأعد إرسال الحدث الفاشل. يزيل FastRestful التكرار حسب معرّف الحدث.

استكشاف أخطاء webhook PayPal وإصلاحها

استجابة FastRestfulالمعنىالحل
400 PayPal webhook is not configured.Client ID أو client secret مفقود، أو السجل الإداري معطّل.املأ client ID وsecret وفعّل السجل. أعد التشغيل إذا كنت تستخدم متغيرات البيئة.
400 Bad signature.معرّف webhook مفقود، أو ينتمي إلى تطبيق/بيئة أخرى، أو تمت إزالة ترويسات التوقيع.انسخ معرّف webhook من التطبيق نفسه في sandbox/live. لا تستخدم عنوان URL أو client secret. تحقق من أن الوكيل الخاص بك يمرّر ترويسات Paypal-*.
404 Unknown invoice for PayPal capture.وصل الالتقاط قبل وجود مرجع الفاتورة المحلي أو جاء الحدث من تثبيت آخر.أعد إرسال الحدث من PayPal بعد التأكد من أن عملية الدفع أنشأها هذا التثبيت.
{"status":"ignored"}الحدث ليس من الأحداث التي يعالجها FastRestful، أو مرجع الاشتراك/الطلب غير معروف.تحقق من تحديد أنواع الأحداث أعلاه. تأكد من أن عملية الدفع أنشأتها بيئة FastRestful هذه.
{"status":"duplicate"}تم تسليم معرّف الحدث نفسه مرتين.لا إجراء. هذا هو عمل حارس idempotency.

Flutterwave، خطوة بخطوة

  1. أنشئ حساب Flutterwave وتحقق منه.

    أكمل ملف الأعمال وKYC قبل استخدام وضع live.

  2. انسخ مفاتيح API.

    افتح Settings → API Keys. انسخ المفتاح العام والمفتاح السري. مفاتيح الاختبار ومفاتيح live منفصلة.

  3. أضف عنوان URL الخاص بـ webhook.

    افتح Settings → Webhooks وعيّن:

    عنوان URL الخاص بـ webhook Flutterwave
    https://api.example.com/api/v1/billing/flutterwave-webhook/
  4. أنشئ secret hash.

    أدخل سلسلة عشوائية طويلة كـ secret hash الخاص بـ webhook. ضع القيمة نفسها في FLUTTERWAVE_WEBHOOK_SECRET أو السجل الإداري. هذه قيمة تختارها أنت، وليست مفتاحًا يولّده Flutterwave.

  5. أدخل المفاتيح في FastRestful.

    حرّر صف Flutterwave في Admin → Payment gateways، أو عيّن FLUTTERWAVE_PUBLIC_KEY وFLUTTERWAVE_SECRET_KEY وFLUTTERWAVE_WEBHOOK_SECRET.

  6. اختبر عملية دفع.

    يعالج FastRestful charge.completed بالحالة successful. يتم الإقرار بالأحداث الأخرى وتجاهلها.

Paystack، خطوة بخطوة

  1. أنشئ حساب Paystack وفعّله.

    أكمل خطوات تفعيل الأعمال قبل استخدام مفاتيح live.

  2. انسخ مفاتيح API.

    افتح Settings → API Keys & Webhooks. انسخ المفتاحين العام والسري لوضع الاختبار أو live.

  3. أضف عنوان URL الخاص بـ webhook.
    عنوان URL الخاص بـ webhook Paystack
    https://api.example.com/api/v1/billing/paystack-webhook/
  4. اترك سر webhook فارغًا.

    يوقّع Paystack كل webhook بمفتاحك السري باستخدام HMAC-SHA512. يعود FastRestful إلى PAYSTACK_SECRET_KEY عندما يكون PAYSTACK_WEBHOOK_SECRET فارغًا. لا تعيّن تجاوزًا إلا إذا منحك دعم Paystack مفتاح توقيع منفصلًا.

  5. أدخل المفاتيح في FastRestful.

    حرّر صف Paystack في Admin → Payment gateways، أو عيّن PAYSTACK_PUBLIC_KEY وPAYSTACK_SECRET_KEY.

  6. اختبر عملية دفع.

    يعالج FastRestful charge.success ويقارن المبلغ بأصغر وحدة عملة (مثل kobo لـ NGN).

Razorpay، خطوة بخطوة

  1. أنشئ حساب Razorpay وتحقق منه.

    أكمل KYC وفعّل مدفوعات live.

  2. أنشئ مفاتيح API.

    افتح Account & Settings → API Keys وأنشئ مفتاحًا. انسخ Key ID وKey Secret.

  3. أضف webhook.

    افتح Account & Settings → Webhooks → Add New Webhook وعيّن:

    عنوان URL الخاص بـ webhook Razorpay
    https://api.example.com/api/v1/billing/razorpay-webhook/

    حدّد payment_link.paid. ينشئ FastRestful رابط دفع Razorpay لعملية الدفع ويطابق ذلك الحدث. عيّن سر webhook قويًا؛ يوقّع Razorpay باستخدام HMAC-SHA256، ويجب تخزين القيمة نفسها في FastRestful.

  4. أدخل المفاتيح في FastRestful.

    حرّر صف Razorpay في Admin → Payment gateways، أو عيّن RAZORPAY_KEY_ID وRAZORPAY_KEY_SECRET وRAZORPAY_WEBHOOK_SECRET.

  5. اختبر عملية دفع.

    افتح Payment Link، وادفع بطريقة اختبار، وتأكد من دفع الفاتورة وتسجيل الحدث مرة واحدة.

اختبار القبول في 10 دقائق

نفّذ هذا لكل مزوّد قبل الانتقال إلى live:

  • يظهر المزوّد كمُهيأ ومُفعّل في Admin → Payment gateways.
  • تفتح عملية دفع تجريبية صفحة المزوّد وتعود إلى عنوان URL الصحيح للواجهة الأمامية.
  • يصل webhook الموقّع ويظهر مرة واحدة في Admin → Payment events.
  • لا تصبح الفاتورة مدفوعة إلا بعد webhook، وليس عند إعادة التوجيه.
  • يصبح الاشتراك نشطًا ويعمل مفتاح المستهلك.
  • يعود الاسترداد إلى وسيلة الدفع الأصلية ويحدّث دفتر الحسابات.
  • إذا كانت الدفعات مفعّلة، يصل تحويل تجريبي إلى وجهة المورّد ويُطابَق.
  • يتم الإقرار بتسليم webhook مكرر دون تسوية مزدوجة.

أخطاء webhook الشائعة

الخطأما يحدثالحل
استخدام http://localhost كعنوان URL لـ webhookلا يستطيع المزوّد الوصول إلى جهازك.استخدم عنوان URL عامًا عبر HTTPS أو نفقًا للاختبار المحلي.
خلط بيانات اعتماد الاختبار وliveتُفتح عملية الدفع، لكن يفشل التحقق من webhook أو يُحصَّل من الحساب الخاطئ.أبقِ المجموعة كاملة في الوضع نفسه: المفاتيح، ومعرّف/سر webhook، وبيئة المزوّد.
لصق عنوان URL الخاص بـ webhook PayPal كـ PAYPAL_WEBHOOK_IDكل حدث PayPal يعيد Bad signature.انسخ معرّف webhook من صفحة تفاصيل Webhooks في التطبيق.
استخدام مفتاح Stripe السري كسر webhookتفشل عمليات تسليم Stripe في التحقق.استخدم سر توقيع الـ endpoint (whsec_…).
نسيان الاشتراك في حدثلا يرسله المزوّد أبدًا، فتبقى الفاتورة مفتوحة.حدّد قائمة الأحداث لذلك المزوّد تمامًا كما هو موضّح أعلاه.
تغيير عنوان URL للنفقتذهب عمليات التسليم إلى مضيف قديم وتفشل.حدّث لوحة المزوّد وFastRestful معًا.
مبلغ أو عملة خاطئةيرفض FastRestful التسوية لحماية دفتر الحسابات.اجعل سعر الخطة وسعر المزوّد متطابقين تمامًا.
الوكيل يزيل ترويسات التوقيعيفشل التحقق حتى مع أسرار صحيحة.مرّر ترويسات المزوّد دون تغيير عبر Nginx أو Cloudflare أو موازن الحمل.

قائمة التحقق قبل الإطلاق

  1. انتقل إلى بيانات اعتماد live.

    استبدل مفاتيح الاختبار ومعرّفات webhook والأسرار بقيم live. عيّن PAYPAL_ENV=live لـ PayPal.

  2. سجّل عناوين URL الخاصة بـ webhook في الإنتاج.

    استخدم اسم مضيف API الحقيقي، وليس نفقًا، وتأكد من أن HTTPS يعمل من الإنترنت العام.

  3. عيّن مفتاح النشر الخاص بالواجهة الأمامية.

    استخدم مفتاح Stripe القابل للنشر الخاص بـ live وأعد بناء الواجهة الأمامية.

  4. طابق الأسعار ومعرّفات الخطط.

    تأكد من أن معرّفات Stripe Price ومعرّفات خطط PayPal Billing تشير إلى كائنات live بالمبلغ والعملة والفترة نفسها.

  5. خذ دفعة حقيقية صغيرة واستردها.

    تحقق من webhook والفاتورة والاستحقاق والاسترداد وقيود دفتر الحسابات. هذه هي الطريقة الوحيدة لإثبات مسار live.

  6. راقب أحداث اليوم الأول.

    تحقق من Admin → Payment events بحثًا عن أعطال، وتأكد من أن لوحة المزوّد تعرض عمليات تسليم ناجحة.

Experienceقراءة 8 دقائق

مكتبة الوسائط & CDN

مسار تخزين واحد لأصول الوسائط وشعارات المنتجات وصور المورّدين وصور المستخدمين الرمزية وصور CMS. نظام ملفات محلي في التطوير؛ S3 + CloudFront في الإنتاج.

الأنواع المدعومة والحدود

النوعالإضافاتالحد
صورةjpg، jpeg، png، webp، gif8 MB
فيديوmp4، webm64 MB
صوتmp3، wav، ogg16 MB
مستندpdf، txt، csv16 MB
أرشيفzip32 MB

يتحقق النظام من الامتداد ونوع المحتوى المعلن وتوقيع magic-byte والحجم. تتم إزالة تكرار البايتات المتطابقة داخل مساحة العمل نفسها عبر checksum SHA-256. ويغذّي GET /api/v1/media/supported-types/ تلميحات القبول في الواجهة.

أوضاع التخزين

MEDIA_STORAGEالسلوك
localتخزين Django على نظام الملفات ضمن MEDIA_ROOT؛ ويُقدَّم عبر /media/.
s3S3 عبر django-storages. أسماء كائنات UUID غير قابلة للتغيير وتُكتب بترويسة تخزين مؤقت غير قابلة للتغيير لمدة سنة.

يتطلب وضع S3 وجود boto3 وdjango-storages في بيئة الإنتاج. يفشل manage.py check إذا كانت الحاوية مفقودة ويحذّر عندما لا يُهيأ نطاق CDN ولا ACL للقراءة العامة.

إعداد CloudFront

  1. أنشئ حاوية خاصة مع تفعيل Block all public access.
  2. أنشئ توزيع CloudFront مع أصل الحاوية وOrigin Access Control (OAC).
  3. امنح التوزيع s3:GetObject على arn:aws:s3:::<bucket>/* عبر سياسة الحاوية المُولّدة.
  4. وجّه MEDIA_CDN_DOMAIN إلى التوزيع أو إلى CNAME بشهادة ACM.
  5. اختياريًا، عيّن MEDIA_CDN_DISTRIBUTION_ID لتفعيل إجراءات التطهير.
لأن أسماء الكائنات غير قابلة للتغيير، تحصل عمليات الرفع المستبدلة على مفتاح جديد. التخزين المؤقت طويل الأمد في CDN آمن ونادرًا ما تكون التطهيرات ضرورية. اضبط MEDIA_S3_ACL=public-read فقط عند التقديم مباشرة من S3 دون CloudFront.

سير عمل المكتبة

  • Console: يرفع الموظفون أصول المكتبة ويديرونها؛ ويرى المستأجرون رفّ مساحة عمل للقراءة فقط على /dashboard/media أو /vendor/media.
  • Collections: مجلدات/فئات خاصة بمساحة العمل مع البحث والتصفية والنقل المجمّع.
  • Rename presets: kebab أو snake أو Title Case أو UPPER أو الإبقاء، مع بادئات ولاحقات وتسلسلات مبطّنة.
  • Focal points: focal_x/focal_y لكل أصل (0–100) تستخدمها كتل صور CMS.
  • Range selection: حدّد نطاقًا بالنقر مع Shift، ونزّل، وانسخ URL، وافتح الأصل السابق/التالي في اللوحة الجانبية.
  • Usage badges: اعرف أين يُشار إلى الأصل قبل حذفه.

دلالات المنتقي

اختيار أصل من المكتبة ينسخ بايتاته إلى الحقل الهدف. استبدال أصل المكتبة أو حذفه لا يكسر الصورة المختارة أبدًا، ويحتفظ كل نموذج بدورة حياة تخزينه. تُرفض الأصول العابرة لمساحات العمل.

الأهداف الموصولة: شعار المنتج، وملف/غلاف المورّد، وصورة المستخدم الرمزية، وهوية المسؤول، وصور الفئات، وصور CMS، ووسائط كتل المحتوى.

Media API

endpointالغرض
GET/POST /api/v1/media/الإدراج مع النوع/البحث/الترتيب ورفع multipart.
PATCH/DELETE /api/v1/media/{id}/البيانات الوصفية والنص البديل والوسوم والحذف.
POST /api/v1/media/bulk-delete/حذف مجمّع بالمعرّفات.
GET /api/v1/media/supported-types/سجل الأنواع والحدود.
GET /api/v1/media/storage-info/تشخيصات الخادم الخلفي والحاوية وCDN وACL وعنوان URL النموذجي للموظفين فقط.

البيئة

راجع Configuration لمصفوفة تخزين الوسائط والمواصفات، بما في ذلك عنوان URL للـ endpoint ونطاق CDN ومعرّف التوزيع وسلوك ACL.

Experienceقراءة 12 دقيقة

استوديو النشرة البريدية

تسويق بريدي للموظفين فقط مع الجماهير وقوالب قائمة على الكتل والحملات واختبارات موضوع A/B والشرائح والأتمتة وتحليلات لكل رابط وبريد نظامي معاملاتي.

استوديو النشرة البريدية في FastRestful مع النمو وقابلية التسليم والحملات والمشتركين ونشاط البريد الإلكتروني
استوديو الرسائل الإخبارية سطح تشغيلي منفصل داخل مستوى التحكم، وليس علامة تبويب إعدادات مدفونة.

بداية سريعة

  1. افتح /admin/newsletter/ → Settings وهيئ المزوّد والمرسل وعنوان URL العام للخادم الخلفي والعنوان البريدي ونص إلغاء الاشتراك.
  2. Lists & contacts → أنشئ قائمة؛ وأضف جهات الاتصال أو استوردها بصيغة email, name, tags.
  3. Templates → انسخ قالب بداية مدمجًا أو ابدأ فارغًا، وصمّم بمحرر الكتل، ثم احفظ واعرض المعاينة.
  4. Campaigns → اختر قالبًا وقوائم وشريحة اختيارية وموضوعًا/مواضيع، وأرسل اختبارًا إلى نفسك.
  5. Automations → أضف خطوات بريد وانتظار؛ ويؤدي الانضمام إلى قائمة أو إضافة وسم إلى بدء التسجيل.
  6. System emails → اربط القوالب بمحفّزات المعاملات.
إعداد المزوّد: للحصول على خطوات لوحة التحكم الدقيقة لـ SES وMailgun وSendGrid وPostmark وBrevo وMailjet وSparkPost وResend أو SMTP المخصص، راجع External integrations → Email.
عمل مجدول
python3.11 manage.py newsletter_beat
# or schedule the Celery tasks:
# newsletter.send_due_campaigns
# newsletter.process_automations

مزوّدو البريد الإلكتروني

المزوّدملاحظات بيانات الاعتماد
SMTP (مخصص)المضيف والمنفذ واسم المستخدم وكلمة المرور وTLS/SSL؛ ترث الحقول الفارغة EMAIL_*.
Amazon SESبيانات اعتماد SMTP والمنطقة.
Mailgunمفتاح API ونطاق الإرسال؛ منطقة EU مدعومة.
SendGridمفتاح API من نوع Bearer.
Postmarkرمز الخادم.
Brevoمفتاح API.
Mailjetمفتاح API وسر.
SparkPostمفتاح API من نوع Bearer.
Resendمفتاح API من نوع Bearer.

تُشفَّر الأسرار عند التخزين. يرسل زر الاختبار عبر المزوّد المحدد قبل اعتماد حملة.

القوالب والمصمّم

  • الكتل: الترويسة، والواجهة الرئيسية، والنص، والصورة، والزر، والفاصل، والمسافة، والصورة + النص، والميزات، والاقتباس، وروابط التواصل، وHTML الخام، والتذييل.
  • كتل متقدمة: الأعمدة، والشهادة، والجدول، والفيديو، وبطاقة المنتج، ولافتة CTA، وملاحظة التذييل.
  • متغيرات لتخطيطات الواجهة الرئيسية، وحجم النص/محاذاته، وإطارات الصور/تعليقاتها، ونمط الزر/حجمه/محاذاته، ونمط الفاصل/عرضه، ونصف قطر السمة، وعرض المحتوى.
  • السحب والإفلات مع إعادة الترتيب بلوحة المفاتيح، ومعاينة مباشرة مؤجلة، وبديل نصي عادي، ونص تمهيدي، وعناوين URL معقّمة.
  • العناصر النائبة: {{first_name}}، {{action_url}}، {{message}}، {{site_name}}، {{unsubscribe_url}}، {{preferences_url}}.
  • 18 قالبًا مدمجًا تشمل الإطلاقات والملخصات والندوات ودراسات الحالة واستعادة العملاء وNPS والعروض وسجلات التغييرات والمقالات الافتتاحية وإبرازات المجتمع والتهيئة وإعلانات الخدمة.

الحملات

  • الجمهور هو اتحاد القوائم المحددة ∩ شريحة اختيارية، مع إزالة التكرار؛ وجهات الاتصال المشتركة فقط، مع استبعاد العناوين المرتجعة/المشتكية.
  • تقسم اختبارات موضوع A/B نسبة من المستلمين، وتنتظر نافذة زمنية، ثم ترسل النسخة الفائزة إلى الباقي. يتوفر «تحديد الفائز الآن» يدويًا.
  • ينشئ «إعادة الإرسال إلى من لم يفتح» مسودة تستهدف فقط جهات الاتصال التي لم تفتح الحملة الأصلية.
  • الجدولة، والإيقاف المؤقت/الاستئناف/الإلغاء، وإرسال اختبار، وتقويم الحملات.
  • التقارير: التسليم، والفتحات، والنقرات، وإلغاءات الاشتراك، ومقارنة A/B، وجدول النقرات لكل رابط، والخط الزمني للتفاعل، وأحدث المستلمين.
  • تُطبَّق قيم UTM الافتراضية على روابط الحملة؛ ولا تُقبل إلا أهداف http(s).

الشرائح والأتمتة

تجمع الشرائح القوائم والوسوم (الكل/أي) وحالة جهة الاتصال ونوافذ التفاعل (فتح، نقر، لم يفتح خلال N يومًا) وحداثة الانضمام. تُحسب الأعداد مباشرة وتُعاد استخدامها في الحملات.

تُشغَّل الأتمتة عند الانضمام إلى قائمة أو إضافة وسم أو يدويًا أو عبر API. ترسل الخطوات بريدًا أو تنتظر N ساعة. تتقدم عمليات التشغيل بشكل idempotent وتسجّل الأعطال. تتم إزالة تكرار التسجيل لكل جهة اتصال.

بريد النظام

إذا كان قالب استوديو نشط مرتبطًا بمحفّز، فإنه يعرض HTML + نصًا؛ وإلا يُرسل النص العادي القديم. تشمل المفاتيح المرتبطة: الترحيب، وإعادة تعيين كلمة المرور، ورمز تسجيل الدخول، وتنبيه الأمان، وإشعار المنصة، وفتح الفاتورة، وفشل الدفع، والموافقة على المورّد، وتنبيه الحصة، ودعوة المؤسسة، وملخص النشاط.

التسجيل العام والتفضيلات

  • POST /api/v1/newsletter/subscribe/ مع تأكيد double opt-in اختياري.
  • GET /confirm/<token>/، وGET /unsubscribe/<token>/، وRFC 8058 one-click POST.
  • مركز التفضيلات على /api/v1/newsletter/preferences/<token>/ لتبديل القوائم أو إلغاء الاشتراك عالميًا.
  • يعيد بكسل الفتح وإعادة توجيه النقر كتابة الروابط عند تفعيل التتبع.
  • يتضمن البريد الصادر الترويستين List-Unsubscribe وList-Unsubscribe-Post.

قابلية التسليم والعمليات

  • مخططات الارتداد والشكاوى وإلغاء الاشتراك والنمو؛ أبقِ معدلات الارتداد والشكاوى قريبة من الصفر.
  • خريطة حرارية لأوقات الإرسال حسب يوم الأسبوع المحلي × الساعة، مع توصيات بأفضل النوافذ.
  • تقديرات الجمهور وعناوين نموذجية قبل الإرسال.
  • صفحة جهات الاتصال مع الحالة والوسوم والحقول المخصصة والعضويات والقمع وعمليات التسليم والأحداث وتشغيلات الأتمتة.
  • تصدير CSV لجهات الاتصال ومستلمي الحملات والروابط.
  • شغّل newsletter_beat كل بضع دقائق للجداول وقرارات A/B وتأخيرات الأتمتة.
Experienceقراءة 8 دقائق

الإعلانات & اللافتات

لافتات عامة يصممها المسؤول للأشرطة العلوية ومواضع التذييل والإعلانات داخل الصفحة — مع الاستهداف والجدولة وقواعد الإغلاق والتجارب البصرية وتحليلات الظهور/النقر.

المواضع

المفتاحأين تظهر
topbarشريط بعرض كامل فوق الترويسة العامة.
footerلافتة بعرض كامل فوق شبكة التذييل.
footer_leftموضع إعلان التذييل الأيسر.
footer_rightموضع إعلان التذييل الأيمن.
centerلافتة داخل الصفحة بين الترويسة ومحتوى الصفحة.

تُقدَّم لافتة واحدة لكل موضع، تُختار حسب الأولوية ثم الحداثة. ويمكن للافتة استهداف مواضع متعددة.

الاستهداف والجدولة

  • Paths: أنماط تضمين واستبعاد مثل /pricing أو /docs/* أو *.
  • الجمهور: الجميع، أو الزوار غير المسجلين، أو المستخدمون المسجلون.
  • اللغة والجهاز: قوائم سماح مفصولة بفواصل؛ يعود الجهاز اللوحي إلى mobile عندما يكون mobile مسموحًا.
  • الجدولة: طوابع زمنية للبداية/النهاية ومفتاح تفعيل.
  • الأولوية: تفوز الأرقام الأعلى عند تطابق لافتات متعددة.

التصميم والعناصر المدمجة

  • التخطيطات: شريط، بطاقة، منقسم، بسيط.
  • الشارة، والعنوان، والنص الأساسي، وتسمية CTA/URL/النمط/تبويب جديد، والصورة، والجانب، والألوان، والتدرجات، والمحاذاة، والمعاينة المباشرة.
  • أيقونة/إيموجي اختيارية، وأنماط زخرفية (نقاط، شبكة، خطوط، توهج)، وحركات دخول تراعي تقليل الحركة.
  • 32 لافتة مدمجة تشمل الإطلاقات والثقة/الحالة والعروض والأحداث ودورة الحياة والمقالات والمجتمع والحملات الموسمية.
  • HTML مخصص مع العناصر النائبة {{click_url}} و{{dismiss_url}} و{{impression_url}} كي يظل التتبع يعمل.
  • تكرار الإغلاق: كل تحميل صفحة، أو مرة لكل جلسة، أو مرة يوميًا، أو مرة واحدة فقط.

التسليم والتتبع

endpoints عامة
GET  /api/v1/announcements/?path=/pricing&locale=en&placement=topbar
POST /api/v1/announcements/<id>/impression/
POST /api/v1/announcements/<id>/dismiss/
GET  /api/v1/announcements/<id>/click/

تتضمن الحمولات HTML المُقدَّم من الخادم بأنماط مضمّنة إضافة إلى impression_url وdismiss_url وfrequency. وتسجّل الأحداث الموضع والمسار واللغة والجهاز والمُحيل وuser agent وIP.

التجارب والتقارير

  • تتقاسم اللافتات ذات الأولوية نفسها نسبة الحركة حسب الوزن (1–1000).
  • عيّن اسم تجربة وتسمية متغير على عدة لافتات؛ ويُختار متغير واحد لكل طلب بناءً على الوزن.
  • تعرض تقارير التجارب مرات الظهور والنقرات ونسبة CTR والمتغير المتقدم.
  • ترسم التقارير النشاط اليومي خلال 30/90 يومًا وتفصّل الموضع وأفضل الصفحات والأجهزة والأحداث الأخيرة.
  • تعرض قوائم المسؤول العدادات وإجراءات التفعيل/الإيقاف المؤقت وسجلات الأحداث للقراءة فقط.

العمليات

أحداث اللافتات للإضافة فقط. تُخزَّن حالة الإغلاق في متصفح الزائر وتُحتسب على جانب الخادم. يتجاوز السكربت العام user agents البوتات؛ استخدم user agent عاديًا لمتصفح حقيقي في اختبار جودة اللافتات العامة.

Experienceقراءة 7 دقائق

الروابط القصيرة

روابط قصيرة جاهزة للحملات، وإعادات توجيه، ورموز QR، وقيم UTM افتراضية، وبدائل احتياطية، وتحليلات نقرات، وفحوص وجهات معطلة — متاحة في لوحة المستهلك واستوديو المورّد معًا.

  • أنشئ روابط قصيرة باستخدام slug مخصص ووجهة ووسوم ونوع إعادة توجيه وانتهاء وحالة تفعيل.
  • إعادات توجيه 301 أو 302؛ ويمكن للروابط المنتهية أو المعطّلة أن تعود إلى وجهة آمنة أو صفحة 410 تحمل الهوية.
  • تُضاف قيم UTM الافتراضية (utm_source، utm_medium، utm_campaign) عند إعادة التوجيه؛ وتكون لمعاملات الحملة الواردة الأولوية.
  • توليد QR بصيغة SVG مع لون مخصص وبيانات وصفية للحملة.
  • تحليلات النقرات مع البلد والجهاز والمُحيل وسياق الحملة.
  • فحوص صحة الوجهات المعطلة مع تفاصيل الخطأ وإعادة فحص بنقرة واحدة.
  • استيراد/تصدير CSV وإجراءات التحديد المجمّع.

افتح Links في لوحة المستهلك (/dashboard/links) أو استوديو المورّد (/vendor/links). يتضمن المحرر العنوان والوجهة وslug والوسوم ونوع إعادة التوجيه والانتهاء ومفتاح التفعيل ونطاق الموقع الكامل الخاص بالموظفين فقط. ويعرض الجدول إجراءات النسخ وQR وإعادة الفحص والتحرير والحذف والصحة والحالة.

المتغيرالغرض
SHORTLINK_BASE_URLأصل الرابط القصير العام، مثل https://go.example.com.
NEWSLETTER_TRACKING_BASE_URLالأصل الاحتياطي عندما تكون قاعدة الرابط القصير فارغة.
FRONTEND_URLالأصل الاحتياطي الأخير.
جدولة فحوص الصحة
python3.11 manage.py checklinks --limit 200 --timeout 6
endpointالغرض
GET/POST /api/v1/short-links/إدراج روابط مساحة العمل وإنشاؤها.
PATCH/DELETE /api/v1/short-links/{id}/التحرير أو الحذف.
GET /api/v1/short-links/{id}/qr/QR بصيغة SVG مع لون اختياري.
POST /api/v1/short-links/{id}/check/إعادة فحص صحة الوجهة.
GET /api/v1/short-links/export/تصدير CSV.
POST /api/v1/short-links/import/استيراد CSV.

تُحل إعادات التوجيه العامة حسب slug، وتسجّل النقرة، ثم تعيد التوجيه. وتتضمن قوائم المسؤول أعمدة النقر/الصحة، وإجراءات إعادة الفحص/التفعيل/التعطيل، وإجراء سريع «تقصير رابط»، وسجل نقرات للقراءة فقط.

Experienceقراءة 12 دقيقة

الموقع وCMS & اللغات

يملك مستوى التحكم في Django الواجهة العامة: الهوية، وافتراضيات البحث/المشاركة، والتنقل، والصفحات، ومقالات المدونة، والمستندات القانونية، وأكواد CSS/JS المخصصة، ووضع الصيانة، وطبقات اللغة.

واجهات المشغّل

مسار المسؤوليملك
/admin/platform/sitesettings/سياسة السوق، وأصول الهوية، والبيانات الوصفية العامة، ونص الترويسة/التذييل، والإعلان، وجهة اتصال الدعم، وسياسة المصادقة الثنائية، ووضع الصيانة.
/admin/platform/sitenavigationitem/روابط الترويسة/التذييل المرتبة، والموضع، والظهور، وسلوك التبويب الجديد.
/admin/platform/contentpage/الصفحات، ومقالات المدونة، والمسودات القانونية، والأقسام المنظمة، ووسائط الغلاف، وSEO، وحالة النشر.
/admin/platform/siteasset/مقتطفات CSS/JS المخصصة، وتحديد النطاق بالمسار، والمعاينة، وسجل المراجعات.
/admin/platform/sitelocale/اللغات المضمّنة، وطبقات المسؤول، وتغطية الترجمة، والاستيراد/التصدير.

إعدادات الموقع

  • الشعار، وأيقونة الموقع، وصورة المشاركة الاجتماعية مع منتقي الوسائط والتنظيف بعد الاعتماد.
  • عنوان meta العام، والوصف، والصورة الاحتياطية للمشاركة.
  • وضع السوق، ونسبة الرسوم الافتراضية، وعلم الصيانة.
  • تسمية CTA في الترويسة + الوجهة (يجب توفيرهما معًا).
  • تفعيل لافتة الإعلان/نصها/رابطها.
  • عنوان التذييل، والملخص، وحقوق النشر، وبريد الدعم.
  • تحدي مدمج أو Google reCAPTCHA للنماذج العامة.
  • سياسة مصادقة ثنائية إلزامية لجميع الحسابات.
  • ألوان السمة والخطوط ومعاينة مباشرة للواجهة العامة.

المحتوى المنظم

تُجمَّع الصفحات والمقالات من أقسام مرتبة، وليس من HTML خام. تشمل أنواع الأقسام المتاحة: النثر، والجدول، والكود، والصورة، والفيديو، والمنقسم، والاقتباس، وعلامات التبويب، والكود متعدد اللغات، ونموذج endpoint، والشهادات، وقائمة الميزات، والأسئلة الشائعة، والخطوات، والمقاييس، وشبكة البطاقات، والفاصل، والواجهة الرئيسية، وشريط الشعارات، والخط الزمني، وقائمة الروابط، والتنبيه، ومجموعة API، ومجموعة الفئات، وأبرز APIs، والمقالات الأخيرة.

  • يدعم النثر فقرات مفصولة بسطر فارغ؛ وعناصر القائمة عنصر واحد لكل سطر.
  • تتطلب الإجراءات تسمية ووجهة معًا؛ وتقبل الروابط مسارات الموقع، أو HTTPS، أو mailto، أو tel.
  • لا تظهر المسودات علنًا أبدًا؛ وتظهر الصفحات المنشورة في محتوى الموقع والبيانات الوصفية ومسارات sitemap.
  • يتجاوز SEO على مستوى الصفحة الافتراضيات العامة لكل حقل.
  • تنضم الصفحات القانونية إلى مجموعة التذييل القانونية الافتراضية بعد النشر فقط.

CSS & JS المخصصان

يحقن Admin → Custom assets CSS أو JavaScript في الموقع العام دون نشر. ولكل مقتطف نوع وموضع (head أو footer) ونطاق (الموقع كاملًا أو مسارات محددة أو صفحة واحدة). وتدعم المسارات التطابقات التامة وبدائل /prefix/*.

  • الحمولة العامة: يعيد GET /api/v1/platform/assets/ المقتطفات النشطة إضافة إلى csp_nonce المهيأ.
  • المعاينة: لكل مقتطف معاينة iframe داخل لوحة المسؤول مع حقن مفروض عبر ?fr_preview_asset=<id>.
  • المراجعات: ينشئ كل حفظ لقطة غير قابلة للتغيير مع المؤلف والملاحظة؛ ويمكن استعادة أي مراجعة كإدخال جديد.
  • CSP: عيّن nonce نفسه في Site settings وفي سياسة edge لديك؛ وتستلمه الوسوم تلقائيًا.

اللغات وطبقات الترجمة

الإنجليزية هي حزمة المصدر الأساسية. ويُشحن الفرنسي كاملًا. وكل لغة أخرى طبقة مسؤول متفرقة تُدمج فوق الإنجليزية وقت التشغيل.

  • افتح Site locales → Manage translations لفحص التغطية، أو تحرير الفرنسية المضمّنة، أو إضافة لغة.
  • تظهر الفرنسية المضمّنة بنسبة 100% دون صف في قاعدة البيانات. ويؤدي حفظ حقل إلى إنشاء طبقة مسؤول دون تغيير البديل المشحون.
  • صدّر JSON أو TypeScript، وترجم دون اتصال، ثم استورد مجددًا. تُتجاهل المفاتيح غير المعروفة ويُبلَّغ عنها.
  • تعيد واجهة API العامة للغات الطبقات النشطة؛ وتدمجها الواجهة الأمامية فوق الإنجليزية والفرنسية المضمّنتين.
  • بعد تحرير lib/i18n/*.json، شغّل npm run export:i18n وأعد تشغيل API لتحديث ذاكرة العملية المؤقتة.

وضع الصيانة

توقف الصيانة كل مسار في الواجهة الأمامية وكل استدعاء لـ API/بوابة العملاء. وتبقى لوحة الموظفين وفحوص الصحة وعمليات ردّ مزوّد الهوية وwebhooks الدفع والدفعات الموقعة متاحة. ويُكشف التوفر العام بشكل مجهول مع علم الصيانة والإشعار وفترة إعادة المحاولة.

العقود العامة

endpointيكشف
GET /api/v1/platform/branding/الشعار، وأيقونة الموقع، ووقت التحديث.
GET /api/v1/platform/site-metadata/العنوان، والوصف، وصورة التواصل، وأيقونة الموقع، ووقت التحديث.
GET /api/v1/platform/site-content/التنقل النشط، ونص الواجهة، والصفحات/المقالات المنشورة.
GET /api/v1/platform/site-pages/بيانات المسارات المنشورة لـ SEO وsitemap.
GET /api/v1/platform/availability/علم الصيانة، والإشعار، وفترة إعادة المحاولة.
GET /api/v1/platform/assets/أكواد CSS/JS المخصصة النشطة وCSP nonce.
GET /api/v1/platform/locales/طبقات اللغة النشطة.
Advancedقراءة 14 دقيقة

التكاملات الخارجية، خطوة بخطوة

البريد الإلكتروني، وتخزين الكائنات، وتسجيل الدخول الموحد، والبنية التحتية، وwebhooks الصادرة. يوضح كل قسم ما يجب فعله على موقع المزوّد أولًا، ثم القيم التي تنسخها بالضبط إلى FastRestful.

المدفوعات في دليلها الخاص. Stripe وPayPal وFlutterwave وPaystack وRazorpay وwebhooks والدفعات مشمولة في بوابات الدفع خطوة بخطوة.

أي قيمة تفوز؟

  • توفر متغيرات البيئة افتراضيات النشر.
  • تتجاوز السجلات التي يديرها المسؤول قيم البيئة المطابقة حقلًا بحقل.
  • يؤدي تعطيل سجل إداري إلى إيقاف ذلك المزوّد في كل مكان، حتى إذا بقيت مفاتيح البيئة معيّنة.
  • تُدمج قيم مزوّد الواجهة الأمامية وقت البناء. أعد البناء بعد تغيير NEXT_PUBLIC_*.
  • شغّل إجراء الاختبار الخاص بالمزوّد قبل إرسال حركة live.

مزوّدو البريد الإلكتروني والرسائل الإخبارية

يمكن لـ FastRestful إرسال بريد الحملات والأتمتة وبريد النظام عبر مزوّدك الخاص. هيّئه في Admin → Newsletter → Email settings، أو ورّث SMTP من متغيرات البيئة EMAIL_*. تُشفَّر مفاتيح API والأسرار عند التخزين.

الإعداد في ست خطوات

  1. أنشئ حسابًا لدى مزوّد واحد.

    استخدم مزوّد بريد معاملاتي مثل Amazon SES أو Mailgun أو SendGrid أو Postmark أو Brevo أو Mailjet أو SparkPost أو Resend، أو أي مضيف SMTP.

  2. تحقق من نطاق الإرسال أو عنوان المرسل.

    لن يسلّم معظم المزوّدين حتى يتم التحقق من النطاق أو البريد. أضف سجلات DNS التي يمنحك إياها المزوّد.

  3. أنشئ مفتاح API أو بيانات اعتماد SMTP.

    استخدم أصغر صلاحية تتيح إرسال البريد. ولـ SMTP، انسخ المضيف والمنفذ واسم المستخدم وكلمة المرور.

  4. أدخل القيم في FastRestful.

    افتح Admin → Newsletter → Email settings. اختر المزوّد، والصق بيانات الاعتماد، وعيّن اسم المرسل وبريد المرسل وعنوان الرد والعنوان البريدي ونص إلغاء الاشتراك.

  5. عيّن عنوان URL العام للخادم الخلفي.

    يُستخدم هذا في بكسلات التتبع وروابط التأكيد وروابط إلغاء الاشتراك. ويجب أن يكون الأصل العام الذي يصل إلى Django، وليس خادم تطوير الواجهة الأمامية.

  6. أرسل بريدًا تجريبيًا إلى نفسك.

    استخدم إجراء الاختبار المدمج. افحص مصدر الرسالة الكامل للتحقق من المرسل والروابط المتوقعة قبل إرسال حملة.

ورقة مرجعية سريعة للمزوّدين

المزوّدما يجب فعله على موقع المزوّدما يجب لصقه في FastRestful
SMTP (مخصص)احصل على المضيف والمنفذ واسم المستخدم وكلمة المرور من مضيف البريد أو لوحة الاستضافة.المضيف، والمنفذ، واسم المستخدم، وكلمة المرور، وTLS/SSL.
Amazon SESتحقق من النطاق أو المرسل، واطلب الوصول إلى الإنتاج، ثم أنشئ بيانات اعتماد SMTP في وحدة تحكم SES.مضيف SMTP مثل email-smtp.us-east-1.amazonaws.com، والمنفذ 587، واسم مستخدم SMTP وكلمة المرور. أبقِ TLS مفعّلًا.
Mailgunأضف نطاق الإرسال وتحقق منه، ثم أنشئ مفتاح API. لاحظ ما إذا كان النطاق في منطقة US أو EU.مفتاح API، ونطاق الإرسال، ومنطقة EU اختيارية، وendpoint API اختياري.
SendGridتحقق من مرسل أو نطاق، ثم أنشئ مفتاح API بصلاحية Mail Send.مفتاح API من نوع Bearer.
Postmarkأنشئ خادمًا وتحقق من توقيع مرسل أو نطاق.رمز الخادم.
Brevoتحقّق من المرسل أو النطاق وأنشئ مفتاح API v3.مفتاح API.
Mailjetتحقّق من المرسل أو النطاق وأنشئ مفتاح API وسرًّا.مفتاح API وسر.
SparkPostتحقّق من نطاق الإرسال وأنشئ مفتاح API بصلاحية الإرسال.مفتاح API من نوع Bearer.
Resendتحقّق من نطاق الإرسال وأنشئ مفتاح API.مفتاح API من نوع Bearer.

قابلية التسليم مهمة DNS. فعّل مصادقة SPF وDKIM وDMARC قبل زيادة الحجم. ابدأ بإرساليات صغيرة، وراقب الارتدادات والشكاوى، وأبقِ رابط إلغاء الاشتراك فعّالًا. ويمكن أن تستخدم الحملات والأتمتة والبريد النظامي قوالب مختلفة، لكنها تشترك في المزوّد نفسه.

تخزين الكائنات وCDN

التخزين على نظام الملفات المحلي مناسب للتطوير. وينبغي أن يستخدم الإنتاج تخزينًا متوافقًا مع S3 مع CDN، لتبقى الملفات المرفوعة بعد عمليات النشر وتُحمَّل الأصول بسرعة.

1. أنشئ حاوية S3 والأذونات

  1. أنشئ حاوية خاصة.

    في وحدة تحكم AWS، أنشئ حاوية في المنطقة التي تريدها. أبقِ خيار حظر كل الوصول العام مفعّلًا. سيقرأ CloudFront منها عبر OAC.

  2. أنشئ مستخدم IAM أو دورًا.

    سلسلة بيانات الاعتماد القياسية مدعومة: متغيرات البيئة، أو ملف تعريف المثيل، أو IRSA على Kubernetes. لا تُضمّن المفاتيح مباشرة في المستودع.

  3. امنح الأذونات التي يحتاجها FastRestful فقط.
    الحد الأدنى لسياسة IAM
    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Action": ["s3:ListBucket"],
          "Resource": "arn:aws:s3:::my-media-bucket"
        },
        {
          "Effect": "Allow",
          "Action": ["s3:GetObject", "s3:PutObject", "s3:DeleteObject"],
          "Resource": "arn:aws:s3:::my-media-bucket/*"
        }
      ]
    }
  4. ثبّت مكتبات التخزين.

    نفّذ pip install boto3 django-storages في بيئة الواجهة الخلفية وأضفها إلى متطلبات النشر.

  5. عيّن قيم البيئة.
    backend/.env
    MEDIA_STORAGE=s3
    MEDIA_S3_BUCKET=my-media-bucket
    MEDIA_S3_REGION=us-east-1
    # MEDIA_S3_ENDPOINT_URL=   # only for S3-compatible providers
    # MEDIA_S3_ACL=            # omit when using CloudFront OAC
  6. أعد التشغيل وارفع أصلًا تجريبيًا.

    افتح مكتبة الوسائط وارفع صورة. ينبغي أن تظهر في الحاوية وتُحمَّل من CDN أو عنوان S3 المهيأ.

2. ضع CloudFront أمام الحاوية

  1. أنشئ توزيع CloudFront.

    اختر الحاوية كمصدر وأنشئ Origin Access Control (OAC).

  2. حدّث سياسة الحاوية.

    اسمح لتوزيع CloudFront بقراءة الكائنات. ويمكن لوحدة تحكم CloudFront توليد السياسة لك.

  3. عيّن قيم FastRestful.
    backend/.env
    MEDIA_CDN_DOMAIN=cdn.example.com
    MEDIA_CDN_DISTRIBUTION_ID=E1234567890ABC
    # MEDIA_S3_ACL=public-read   # only if serving S3 directly, not recommended
  4. اسمح بإبطال الذاكرة المؤقتة.

    أضف cloudfront:CreateInvalidation إلى سياسة IAM إذا أردت أن يعمل زر التطهير في مكتبة الوسائط.

  5. اختبر برفع ملف جديد.

    ارفع ملفًا جديدًا، وافتحه عبر نطاق CDN، ثم استبدله واستخدم إجراء التطهير.

3. مزوّدون متوافقون مع S3

تعمل Cloudflare R2 وMinIO وDigitalOcean Spaces وخدمات مشابهة عبر S3 API. عيّن MEDIA_S3_ENDPOINT_URL إلى endpoint S3 الخاص بالمزوّد، وأبقِ الحاوية خاصة إذا كان المزوّد يدعم CDN أو عناوين URL موقّعة. تحقّق من الرفع والتنزيل والحذف قبل الاعتماد عليه في الإنتاج.

4. تخزين مواصفات OpenAPI

بشكل افتراضي، تُخزَّن عقود OpenAPI المستوردة في قاعدة البيانات. لتخزينها في S3، عيّن:

backend/.env
SPEC_STORAGE=s3
SPEC_S3_BUCKET=my-spec-bucket
SPEC_S3_PREFIX=specs/
SPEC_S3_REGION=us-east-1
# SPEC_S3_ENDPOINT_URL=

راجع مكتبة الوسائط & CDN لحدود الرفع وأنواع الملفات المدعومة وسلوك CDN.

تسجيل الدخول الموحّد

يحافظ كل من OIDC وSAML على الوجهات النسبية الآمنة ورموز دعوات المؤسسة. ويمكن إبقاء تسجيل الدخول بكلمة المرور مفعّلًا كخيار احتياطي.

OIDC خطوة بخطوة

  1. أنشئ تطبيق OIDC في مزوّد الهوية لديك.

    استخدم Okta أو Auth0 أو Microsoft Entra ID أو Google Workspace أو Keycloak أو Authentik أو أي مزوّد OIDC متوافق.

  2. سجّل عنوان URL للاستدعاء الراجع.
    URI إعادة التوجيه
    https://api.example.com/api/v1/auth/sso/callback/

    استخدم اسم المضيف الدقيق الذي يصل إليه المستخدمون. وأي اختلاف في الشرطة المائلة الأخيرة سيُفشل الاستدعاء الراجع.

  3. اسمح بتدفق رمز التفويض والنطاقات.

    اطلب openid وemail وprofile.

  4. انسخ المُصدر ومعرّف العميل وسر العميل.
    backend/.env
    SSO_ISSUER=https://login.example.com/realms/acme
    SSO_CLIENT_ID=fastrestful
    SSO_CLIENT_SECRET=...
  5. أعد تشغيل الواجهة الخلفية.

    يُخفى زر SSO حتى يُهيّأ المزوّد.

  6. اختبر بهوية حقيقية.

    سجّل الدخول عبر الزر وتأكد من أن الاستدعاء الراجع يعود إلى مسار الواجهة الأمامية المتوقع.

SAML 2.0 خطوة بخطوة

  1. ثبّت التبعية الاختيارية.

    نفّذ pip install lxml قبل تفعيل SAML.

  2. انسخ بيانات SP الوصفية.

    أعطِ مزوّد الهوية لديك عنوان URL هذا، أو ارفع ملف XML الذي يعيده:

    بيانات SP الوصفية
    https://api.example.com/api/v1/auth/saml/metadata/
  3. عيّن عنوان ACS ومعرّف الكيان في IdP.

    خدمة استهلاك التأكيدات هي:

    عنوان ACS
    https://api.example.com/api/v1/auth/saml/callback/

    معرّف الكيان الافتراضي هو fastrestful. ويمكنك تغييره باستخدام SSO_SAML_ENTITY_ID.

  4. انسخ عنوان SSO الخاص بـ IdP وشهادة التوقيع.
    backend/.env
    SSO_SAML_ENABLED=1
    SSO_SAML_ENTITY_ID=fastrestful
    SSO_SAML_SSO_URL=https://idp.example.com/sso
    SSO_SAML_IDP_CERT=-----BEGIN CERTIFICATE-----...
    # SSO_SAML_AUDIENCE=fastrestful
  5. أعد التشغيل واختبر.

    ابدأ تسجيل الدخول من الواجهة الأمامية وتأكد من أن تأكيد IdP يعود إلى الصفحة المتوقعة.

مزوّدو البنية التحتية

الخدمةما يجب فعلهإعداد FastRestful
PostgreSQLوفّر قاعدة بيانات مُدارة أو خادمك الخاص. فعّل النسخ الاحتياطي الآلي وراقب حدود الاتصالات.DATABASE_URL. مطلوب في الإنتاج.
Redisوفّر نسخة Redis مُدارة. فعّل الاستمرارية إذا كنت تعتمد على إعادات محاولات Celery.REDIS_URL. مطلوب في الإنتاج.
Celeryشغّل عملية worker وbeat ضمن systemd أو Supervisor أو مدير العمليات في منصتك.CELERY_BROKER_URL (القيمة الافتراضية REDIS_URL).
Nginxأنهِ TLS، ووكّل الطلبات إلى Gunicorn، وقدّم /static/ و/media/، ومرّر ترويسات المضيف وعنوان IP للعميل.راجع النشر → Nginx.
Cloudflare / CDNوكّل DNS، وفعّل TLS، وارفع حدود الرفع لتطابق إعدادات الوسائط. وأبقِ مسارات webhook بعيدة عن التخزين المؤقت العدواني.قواعد DNS والتخزين المؤقت.
شغّل المجدول. يقود Celery beat التسوية الشهرية وتصعيد الإشراف والبريد الإلكتروني وفحوص التوفر. من دون وسيط، شغّل أوامر التسوية يدويًا. راجع العمليات.

أدوات API وwebhooks الصادرة

OpenAPI وSwagger وPostman

  • استيراد OpenAPI: استورد OpenAPI 3.x أو Swagger 2.0 إلى إصدار مسودة. ويوفّق مسار الإصدار بين endpoints ويُعلّم التغييرات الكاسرة.
  • مخطط المنصة: صدّره من /api/schema/ باستخدام python3.11 manage.py spectacular --file schema.yml --validate.
  • واجهة Swagger: تقدّمها الواجهة الخلفية على /api/docs/.
  • Postman / حزم البدء: تعرض endpoints المنتجات حزمًا قابلة للتنزيل للمستهلكين.

webhooks الصادرة خطوة بخطوة

  1. أنشئ endpoint في FastRestful.

    افتح قسم webhook endpoints في مستوى التحكم وأضف عنوان URL للمستقبِل. ويجب أن يكون HTTPS.

  2. اختر الأحداث وسر التوقيع.

    خزّن سرًّا قويًا. يوقّع FastRestful جسم الطلب الخام باستخدام HMAC-SHA256.

  3. أرسل تسليمًا تجريبيًا.

    تأكد من أن مستقبِلك يعيد استجابة 2xx.

  4. تحقّق من التوقيع على خادمك.

    قارن HMAC-SHA256 الذي تحسبه أنت لجسم الطلب الخام مع ترويسة X-FastRestful-Signature. والقيمة هي sha256=<hex>. واسم الحدث موجود في X-FastRestful-Event.

  5. راقب سجل التسليم.

    إعادات المحاولة آمنة وسجل التسليم دليل للقراءة فقط. وتعامل مع أسماء الأحداث المكررة بشكل idempotent.

webhooks الدفع منفصلة. تسوّي webhooks المزوّد المعاملات المالية وتُسجّل في لوحة تحكم كل مزوّد. أما webhooks المورّد الصادرة فمخصّصة لتكاملاتك الخاصة. لا توجّه مزوّد دفع إلى endpoint webhook خاص بمورّد.

قائمة قبول التكامل

  • يظهر المزوّد مهيأً ومفعّلًا في صفحة الإدارة أو الإعدادات.
  • تصل رسالة اختبار حقيقية أو عملية رفع إلى المزوّد ويُحمَّل عنوان URL المُعاد.
  • تصل رسالة البريد التجريبية؛ وتنجح SPF وDKIM وDMARC.
  • تُخزَّن الوسائط المرفوعة في الحاوية وتُقدَّم عبر CDN.
  • يعود استدعاء OIDC أو SAML الراجع إلى مسار الواجهة الأمامية المتوقع.
  • تتحقق توقيعات webhooks الصادرة على المستقبِل.
  • لا تؤدي إعادات المحاولة إلى تكرار الآثار الجانبية.
  • لا تُخلط بيانات اعتماد الاختبار والإنتاج.
متقدمقراءة 9 دقائق

النسخ الاحتياطية والترقيات

مسار قابل للتكرار للنسخ الاحتياطي والاستعادة والترقية لنشر FastRestful المستضاف ذاتيًا. تأتي النسخ الاحتياطية أولًا؛ وتعتمد طريقة الترقية على كيفية شرائك للمنتج ونشره.

تثبيت مرخّص من Dakidarts؟ استخدم الترخيص والتحديثات الرسمية للحصول على إصدارات رسمية موقعة وتراجع بنقرة واحدة. لا يزال هذا الدليل مسؤولًا عن خطة النسخ الاحتياطي والاستعادة، ومسار ترقية المصدر اليدوي.

ما يجب نسخه احتياطيًا

البياناتالسببالطريقة
PostgreSQLالمستأجرون، والمنتجات، والإصدارات، والاشتراكات، والفواتير، والتدقيق، والمحتوى، وبيانات المفاتيح الوصفية.تفريغ منطقي ليلي مع نسخ احتياطي مستمر من المزوّد.
وسائط S3أصول المكتبة والشعارات والصور الرمزية وصور CMS.الإصدارات والنسخ المتماثل عبر المناطق حيث يلزم.
كتل المواصفاتعقود OpenAPI عند SPEC_STORAGE=s3.مشمولة في نسخ S3 الاحتياطي.
أسرار البيئةDJANGO_SECRET_KEY، FIELD_ENCRYPTION_KEY، وبيانات اعتماد المزوّد.مدير أسرار مع تحكم في الوصول وسجل تدوير.
إعداد بناء الواجهة الأماميةقيم NEXT_PUBLIC_* وإعدادات الاستضافة.البنية التحتية كشيفرة أو ملاحظات النشر.
تحذير مفتاح التشفير. فقدان FIELD_ENCRYPTION_KEY يجعل مفاتيح API المشفرة وأسرار المزوّد غير قابلة للاسترداد. انسخه احتياطيًا بشكل منفصل عن قاعدة البيانات، مع تحكم صارم في الوصول.

نسخ PostgreSQL الاحتياطي

shell
pg_dump --format=custom "$DATABASE_URL" > fastrestful-$(date +%F-%H%M).dump
pg_dump --format=plain "$DATABASE_URL" | gzip > fastrestful-$(date +%F-%H%M).sql.gz

# Verify the dump is readable
pg_restore --list fastrestful-$(date +%F-%H%M).dump > /dev/null

الاستعادة إلى قاعدة بيانات نظيفة

shell
createdb fastrestful_restore
pg_restore --clean --if-exists --no-owner \
  --dbname=fastrestful_restore fastrestful-2026-10-21.dump

# Point a staging deployment at the restored database and run:
python3.11 manage.py migrate --check
python3.11 manage.py check

اختبر الاستعادة كل ثلاثة أشهر. فالنسخة الاحتياطية التي لم تُستعد قط افتراض، لا خطة تعافٍ.

طريقتان للترقية

المساراستخدمها عندماابدأ من هنا
مركز التحديث الرسمياشتريت FastRestful من Dakidarts وتشغّل نشرًا من المصدر أو على VM.الترخيص والتحديثات الرسمية
ترقية يدوية من المصدرتدير fork مخصصًا، أو تبني صورك الخاصة، أو لا تستخدم LicenseHub.التسلسل أدناه.

تسلسل الترقية اليدوية

استخدم هذا فقط لنشر مخصص لا يديره مركز التحديث الرسمي.

  1. اقرأ ملاحظات الإصدار وتحقق من تغييرات الترحيل أو البيئة.
  2. انسخ PostgreSQL والوسائط والأسرار احتياطيًا.
  3. ضع المنصة في وضع الصيانة إذا تطلّب الترحيل إيقاف الكتابة مؤقتًا.
  4. اسحب الشيفرة وثبّت تبعيات الواجهة الخلفية والأمامية.
  5. نفّذ الترحيلات واجمع الملفات الثابتة وابنِ الواجهة الأمامية.
  6. أعد تشغيل API والعاملين؛ وتحقق من الجاهزية ومن طلب فحص سريع.
  7. اخرج من وضع الصيانة وراقب معدل الأخطاء وعمق الطابور وإيصالات webhook.
بعد أي من مساري الترقية، أعد تشغيل Gunicorn وعامل Celery وbeat وعملية بناء الواجهة الأمامية إذا كانت تعمل على المضيف نفسه. ثم تحقق من /api/health/readyوأرسل طلب فحص واحد وافتح الإدارة → أحداث الدفع لتأكيد عدم فشل أي عمليات تسليم من المزوّد أثناء إعادة التشغيل.
shell
git pull --ff-only
pip install -r backend/requirements.txt
npm ci

python3.11 backend/manage.py migrate --noinput
python3.11 backend/manage.py collectstatic --noinput
npm run build

sudo systemctl restart fastrestful
sudo systemctl restart fastrestful-worker fastrestful-beat
curl -f https://api.example.com/api/health/ready

التراجع

  • يكون التراجع عن الشيفرة مباشرًا فقط عندما لا يتطلب الإصدار السابق ترحيلًا غير قابل للعكس في قاعدة البيانات.
  • احتفظ بلقطة من قاعدة البيانات قبل كل ترحيل. واستعد اللقطة وإصدار الشيفرة المطابق معًا.
  • لا تعدّل أبدًا ترحيلًا مطبّقًا في الإنتاج؛ بل أضف ترحيلًا تصحيحيًا جديدًا.
  • بعد التراجع، أعد تنفيذ طلب الفحص السريع وافحص المهام في الطابور بحثًا عن افتراضات المخطط.

أمان الترحيل

فحص مسبق
python3.11 manage.py showmigrations
python3.11 manage.py makemigrations --check --dry-run
python3.11 manage.py migrate --plan
  • التغييرات الإضافية أولًا، ثم التعبئة الرجعية، ثم إزالة الحقول القديمة في إصدار لاحق.
  • تجنّب أقفال الجداول الطويلة على جداول القياس المكثفة وسجلات الطلبات والتدقيق.
  • شغّل وضع الصيانة للترحيلات التي تغيّر أعمدة حالة الأموال أو حالة الإصدار.
  • أبقِ Celery متوقفًا مؤقتًا حتى تكتمل الترحيلات.

إصدارات الواجهة الأمامية

بناء الواجهة الأمامية ثابت ومكتفٍ بذاته. أبقِ أصل API وعنوان URL للموقع العام متوافقين مع النشر. وإذا نشرت بناءً جديدًا يتوقع حقول API جديدة، فأصدر الواجهة الخلفية أولًا أو أبقِ العقد متوافقًا مع الإصدارات السابقة.

متقدمقراءة 9 دقائق

المراقبة التشغيلية

الصحة والسجلات والمقاييس والطوابير لمنصة تترك فيها الطلبات والأموال والإشراف أدلة.

الصحة والجاهزية

الفحصما تجيب عنه
GET /api/health/liveهل العملية حية؟
GET /api/health/readyهل تستطيع العملية الوصول إلى قاعدة البيانات والذاكرة المؤقتة المشتركة؟
GET /api/schema/هل عقد API قابل للتقديم؟
عرض مسار الواجهة الأماميةهل يمكن للغلاف العام تحميل الهوية والمحتوى؟

استخدم الجاهزية لتحديد عضوية موازن التحميل. ويعيد انقطاع الذاكرة المؤقتة 503 مع التبعية المتعثرة بدلًا من التقديم بحالة محلية فقط.

سياق الطلب

  • تحمل كل استجابة API بيانات وصفية للطلب في سجلات التطبيق. وحافظ على معرّف الطلب عبر الوكيل العكسي.
  • تتضمن سجلات طلبات البوابة الاشتراك والمنتج وendpoint والحالة وزمن الاستجابة ومعاينات محجوبة.
  • تخزّن أحداث المزوّد معرّفات الأحداث وتجزئات الحمولة، لا الأسرار الخام.
  • تربط أحداث التدقيق الفاعل والإجراء والمؤسسة والهدف والبيانات الوصفية.

الإشارات الواجب مراقبتها

المجالالإشارةحد الإجراء
APIمعدل 5xx وزمن استجابة p95فعّل التنبيه عند استمرار 5xx أو تدهور زمن الاستجابة.
البوابةمعدل أخطاء المنبع وعدد مرات فتح الدائرةتحقق من صحة المورّد قبل رفع الحصص.
قاعدة البياناتالاتصالات والاستعلامات البطيئة والقرصوسّع أو أضف فهارس قبل التشبع.
Redisالذاكرة وعمليات الإخلاء وأخطاء الاتصالقد تؤدي عمليات الإخلاء إلى إخفاق سلوك الحصة/حد المعدل.
Celeryعمق الطابور وإخفاقات المهام ونبض beatنبّه إذا توقفت التسوية أو طابور البريد.
الأموالwebhooks الفاشلة والاستردادات المعلقة واستثناءات الدفعاتطابق السجلات قبل إعادة المحاولة عشوائيًا.
البريد الإلكترونيمعدل الارتداد والشكاوى وإلغاء الاشتراكاحجب وتحقق عند تجاوز المعدل الطبيعي.

قواعد التسجيل

  • لا تسجّل أبدًا مفاتيح API الخام أو أسرار المزوّد أو حمولات الدفع الكاملة.
  • أبقِ معاينات الطلب/الاستجابة محدودة ومحجوبة.
  • سجّل معرّفات أحداث المزوّد ونتائج التسوية، لا بيانات البطاقات.
  • استخدم حقولًا منظمة حيث أمكن: معرّف الطلب، المؤسسة، المنتج، endpoint، الحالة.
  • افصل أدلة التدقيق عن سجلات التطبيق العادية.

الطوابير والعمل المجدول

shell
celery -A config inspect ping
celery -A config inspect active
celery -A config inspect reserved
celery -A config inspect scheduled

راقب طابوري الافتراضي والفوترة بشكل مستقل. فالتسوية تُنفّذ شهريًا؛ ويعمل الإشراف والإشعارات كل 15 دقيقة؛ وتُجرى فحوص التوفر يوميًا.

الحد الأدنى من التنبيهات

  • فشل الجاهزية لأكثر من دقيقتين.
  • معدل 5xx في API أعلى من هدف الخدمة.
  • فتح دائرة البوابة أو ارتفاع حاد في معدل أخطاء المنبع.
  • إخفاقات webhook أو أحداث مزوّد غير معالجة.
  • غياب نبض Celery beat؛ ونمو عمق الطابور.
  • تشبع قرص قاعدة البيانات والاتصالات.
  • فشل النسخ الاحتياطي أو تقادم آخر نسخة ناجحة.
  • انخفاض غير متوقع في تسجيل الموظفين للتحقق بخطوتين.

أوامر التشخيص

shell
python3.11 manage.py check --deploy
python3.11 manage.py showmigrations
python3.11 manage.py prune_telemetry --request-log-days 90 --usage-event-days 365
python3.11 manage.py check_api_availability
python3.11 manage.py checklinks --limit 200 --timeout 6
متقدمقراءة 8 دقائق

التوسع

أين يتوسع FastRestful بسلاسة، وأين يحتاج إلى بنية تحتية، وأي حالة يجب أن تبقى مشتركة.

وسّع الطبقات بشكل منفصل

البنية
edge / CDN
  ├── frontend static assets
  └── API reverse proxy
        ├── Django / Gunicorn replicas
        ├── Celery workers (default queue)
        ├── Celery workers (billing queue)
        ├── Celery beat (one instance)
        ├── PostgreSQL primary + read capacity
        └── Redis (shared cache + broker)

طبقة الويب

  • شغّل عدة نسخ Gunicorn/Django عديمة الحالة خلف موازن تحميل.
  • تعيش الجلسات في قاعدة البيانات؛ وتستخدم الذاكرة المؤقتة وحدود المعدل Redis. ولا تعتمد على الذاكرة المحلية في الإنتاج.
  • اضبط حجم العاملين وفق أبطأ طلب بوابة (المهلة الافتراضية 15 ثانية).
  • أنهِ TLS عند الحافة وحافظ على المضيف الأصلي لتوجيه المنتجات.

قاعدة البيانات

  • استخدم PostgreSQL مع تجميع الاتصالات مع نمو عدد العاملين.
  • الجداول المكثفة: أحداث الاستخدام وسجلات الطلبات وأحداث التدقيق وتسجيلات webhook.
  • قلّم بيانات القياس عن بُعد وفق جدول وأرشف أدلة التدقيق وفق السياسة.
  • أبقِ الكتابات المتعلقة بحالة الأموال ضمن معاملات؛ ولا تقسّم جداول الفواتير أو دفتر الأستاذ دون خطة ترحيل.

Redis

  • الذاكرة المؤقتة المشتركة مطلوبة لحدود معدل البوابة وidempotency.
  • يعيد انقطاع Redis استجابة 503 قابلة لإعادة المحاولة قبل حجز الحصة؛ ولا ترتد البوابة إلى حالة لكل عملية.
  • راقب عمليات الإخلاء. فقدان سجلات idempotency قد يسمح باستدعاءات منبع مكررة بعد تغييرات TTL.
  • استخدم قاعدة بيانات Redis أو نسخة منفصلة لوسيط Celery إذا زاد ضغط الذاكرة المؤقتة.

سعة البوابة

  • تُفرض الحصة وحدود المعدل لكل اشتراك وendpoint، لا لكل عملية.
  • يهيمن زمن استجابة المنبع على وقت الطلب؛ فأبقِ المهلات وإعادات المحاولة متحفظة.
  • ينمو تخزين idempotency مع حجم الطلبات؛ فاضبط حجم Redis وفق TTL المهيأ.
  • استخدم توجيه مضيف المنتج مع TLS بنطاق شامل لتجنّب عنق زجاجة مركزي في المسار عند الحافة.

العاملون والعمل المجدول

  • شغّل نسخة beat واحدة؛ فمجدولات beat المتعددة يمكن أن تكرر العمل المؤقت.
  • وسّع طابوري الفوترة والافتراضي بشكل منفصل.
  • أبقِ التسوية idempotent؛ فإعادة التشغيل آمنة بحكم التصميم.
  • اضبط ضغط طابوري البريد والإشراف بزيادة تزامن العاملين بدلًا من تعطيل إعادات المحاولة.

الوسائط وCDN

  • انقل الملفات المرفوعة إلى S3 قبل أن تصبح دورة حياة القرص المحلي مشكلة.
  • قدّم عبر CloudFront بأسماء كائنات ثابتة وتخزين مؤقت طويل الأمد.
  • أبقِ الوصول إلى الأصل خاصًا؛ وتجنّب سياسات الحاويات العامة.
  • استخدم التطهير لكل أصل فقط عندما يُعاد استخدام مفتاح كائن عمدًا.

قائمة التحقق من السعة

  • تنبيهات الجاهزية و5xx موصولة بنظام الاستدعاء.
  • لدى PostgreSQL فسحة للاتصالات والقرص وعمليات IOPS.
  • لدى Redis فسحة للذاكرة المؤقتة وسجلات idempotency معًا.
  • عمق طابور Celery ونبض beat مراقبان.
  • تخزين الكائنات وCDN خارج خادم الويب.
  • يُهيأ الاحتفاظ ببيانات القياس عن بُعد قبل النمو لا بعده.
متقدمقراءة 10 دقائق

نموذج البيانات & الأذونات

الكيانات التي تحدد FastRestful، وحدود المستأجرين حولها، والثوابت التي تحافظ على اتساق الأموال والإصدارات.

المستأجرون

Organization هو حد المستأجر. وينضم المستخدم عبر Membership بدور محدد. وتنتقل المؤسسة النشطة صراحةً وتُحل من جهة الخادم قبل الوصول إلى الكائن.

الدورالغرض
المالكتحكم كامل بمساحة العمل والفوترة والفريق وعمليات المورّد. وآخر مالك محمي.
Adminالفريق والتطبيقات والمفاتيح والاشتراكات والنشر والفوترة والدعم.
Developerالتطبيقات والمفاتيح واختبار endpoint والنشر حيث يُسمح.
الفوترةالفواتير والكوبونات والاستردادات والدفعات وطرق الدفع.
Viewerاطلاع للقراءة فقط على مساحة العمل.

الكيانات الأساسية

المجالالكيانات
الهويةUser, Organization, Membership, OrganizationInvite, VendorProfile, TwoFactorDevice, LoginCode
الكتالوجCategory, ApiProduct, ApiVersion, Endpoint, ApiAvailabilityCheck
الوصولApplication, ApiKey, Plan, Subscription, Coupon
القياسUsageEvent, MonthlyCounter
الأموالInvoice, Payout, LedgerEntry, PaymentEvent, PayoutProviderEvent, RefundRequest
المنصةSiteSettings, PlatformPlan, PlatformSubscription, SiteNavigationItem, ContentPage, SiteLocale, SiteAsset
التفاعلEmailList, Contact, Campaign, EmailTemplate, Automation, Banner, ShortLink
الثقةAbuseReport, ModerationAppeal, ModerationPolicy, SafetyEnforcement, ProfileBlock, DirectMessage
العملياتRequestLog, WebhookEndpoint, WebhookDelivery, Ticket, TicketMessage, AuditEvent, ExportJob

الثوابت

  • يمتلك المنتج إصدارًا حيًّا واحدًا في كل وقت.
  • لا يمكن تعديل عقد الإصدار الحي وكتالوج endpoints الخاص به.
  • للاشتراك شروط تجارية غير قابلة للتغيير؛ وتؤدي التغييرات إلى إنشاء خطة جديدة.
  • ينتمي مفتاح API إلى تطبيق واحد فقط ولا يمكنه عبور التطبيقات.
  • يُسجّل معرّف حدث المزوّد مرة واحدة؛ ولا تسوّي عمليات الإعادة مرتين.
  • تتبع الدفعات آلة حالات أحادية الاتجاه.
  • قيود دفتر الأستاذ للإضافة فقط.
  • لا يمكن إزالة آخر مالك نشط لمساحة العمل أو خفض دوره.

فحوص الأذونات

العمليةالصلاحية المطلوبة
تغييرات الفريق ومساحة العملمالك أو مسؤول
نشر/ترقية المنتجمالك أو مسؤول أو مطوّر في المؤسسة المالكة
الفاتورة والاسترداد والدفعة والكوبونمالك أو مسؤول أو فوترة
إعدادات المنصةمستخدم خارق / أذونات موظفين صريحة
مراجعة ملف المورّدموظف لديه إذن نموذج المورّد
قرار الإشرافموظف لديه إذن نموذج السلامة

الحذف والاحتفاظ

  • لا تُحذف التذاكر أبدًا؛ وتبقى دليلًا على الدعم.
  • يبقى سجل الإصدار الحي متاحًا للتدقيق حتى بعد الإيقاف.
  • أحداث التدقيق وإيصالات المزوّد للإضافة فقط.
  • تُقلّم سجلات الطلبات وأحداث الاستخدام وفق مدة الاحتفاظ المهيأة.
  • تستخدم عمليات حذف الوسائط دورة حياة الأصل وينبغي أن تحترم المراجع قيد الاستخدام.

توسيع النموذج

  1. ابدأ من سير عمل حقيقي، لا من حقل افتراضي.
  2. أبقِ بيانات المنصة فقط خارج المُسلسِلات المجهولة.
  3. تحقق على مستوى النموذج/API؛ وأضف قيود قاعدة البيانات للأموال وانتقالات الحالة.
  4. أضف اختبارات عقود للأذونات وحدود المستأجرين وidempotency.
  5. وثّق واجهة المشغّل قبل شحن النموذج.
متقدمقراءة 8 دقائق

الإضافات

وسّع التجربة العامة وسير العمل التشغيلي دون تفرّع النواة: أصول مخصصة، وأقسام CMS، وطبقات لغة، وwebhooks، وأنماط إدارة.

CSS وJavaScript المخصصة

تحقن صفحة الإدارة → الأصول المخصصة مقتطفًا في الموقع العام. ولكل مقتطف نوع وموضع ونطاق وحالة تفعيل.

الحقلالخيارات
النوعCSS أو JavaScript
الموضعالترويسة أو التذييل
النطاقالموقع بأكمله أو مسارات محددة أو صفحة واحدة
أنماط المساراتمسارات دقيقة وأحرف بدل /prefix/*
  • ينشئ كل حفظ مراجعة غير قابلة للتغيير مع المؤلف والملاحظة؛ ويمكن استعادة أي مراجعة كإدخال جديد.
  • عاين الموقع الحي في iframe إداري مع حقن المقتطف قسريًا.
  • استخدم nonce الخاص بـ CSP المهيأ في إعدادات الموقع وسياسة الحافة معًا؛ وتتلقاه الوسوم المحقونة تلقائيًا.
  • تعامل مع المقتطفات كشيفرة مشغّل موثوقة. فهي قادرة على إعادة تنسيق الموقع العام أو تزويده بأدوات قياس.

أقسام CMS المنظمة

تُبنى الصفحات والمقالات من أقسام مرتبة. ويتضمن المحرر النثر والجدول والشيفرة والصورة والفيديو والتقسيم والاقتباس وعلامات التبويب ومجموعات الشيفرة وعينات endpoint والشهادات والميزات والأسئلة الشائعة والخطوات والمقاييس والبطاقات والفواصل والقسم الرئيسي وشريط الشعارات والخط الزمني وقائمة الروابط والملاحظات ومجموعات API ومجموعات الفئات وأفضل APIs والمقالات الحديثة.

  • استخدم أقسامًا منظمة بدلًا من لصق HTML عشوائي.
  • عيّن تسمية الإجراء والوجهة معًا.
  • استخدم مسارات الموقع أو HTTPS أو mailto أو وجهات tel.
  • أبقِ نص alt للصورة ذا معنى؛ ويمكن أن يخدم نص المتن كتسمية توضيحية.
  • لا تنضم الصفحات المنشورة إلى التنقل وبيانات خريطة الموقع إلا عندما تكون حية.

طبقات اللغة

الإنجليزية هي الحزمة الأساسية؛ وتأتي الفرنسية مكتملة. أضف لغة أخرى في الإدارة، واستورد حزمة JSON أو TypeScript، وتجاوز فقط المفاتيح التي تحتاجها.

  • تبقى القيم المضمّنة بديلًا عندما يكون مفتاح الطبقة فارغًا.
  • تُتجاهل المفاتيح غير المعروفة ويُبلّغ عنها أثناء الاستيراد.
  • صدّر JSON أو TypeScript للترجمة دون اتصال.
  • نفّذ npm run export:i18n بعد تعديل حزمة الواجهة الأمامية وأعد تشغيل API.

webhooks الصادرة

تسلّم webhooks المورّد أحداثًا موقّعة إلى endpoints HTTPS مع سجل تسليم آمن لإعادات المحاولة. أبقِ سر التوقيع في مساحة عمل المورّد وتحقق من التوقيع قبل التصرف بناءً على حمولة.

  • استخدم عنوان endpoint ثابتًا وأعد 2xx بسرعة.
  • تعامل مع الأحداث كضمان مرة واحدة على الأقل واجعل المعالجات idempotent.
  • استخدم سجل التسليم لفحص حالة الاستجابة والمعاينات.
  • لا تُعد استخدام مسارات webhook الخاصة بمزوّد الدفع لأحداث المورّد.

نمط توسيع الإدارة

  1. سجّل النموذج بسلوك صريح للقائمة والتصفية والبحث والأذونات.
  2. أضف نموذج إدارة مركّزًا بدلًا من كشف الحقول الداخلية الخام.
  3. استخدم أحداث التدقيق للإجراءات التي تغيّر الحالة.
  4. أضف صفحة معاينة أو تقرير فقط عندما تجيب عن سؤال مشغّل حقيقي.
  5. اختبر حدود الأذونات وفصل المُسلسِلات العامة/الخاصة.

نمط توسيع API

  • أبقِ نطاق المستأجر قبل كل استعلام.
  • استخدم مُسلسِلات صريحة للطلب/الاستجابة.
  • أعد رموز أخطاء ثابتة لسلوك العميل.
  • اجعل إعادات المحاولة آمنة باستخدام idempotency حيث تتعلق الأموال أو الحالة.
  • أضف تعليقات OpenAPI ليبقى المخطط قابلًا للاستخدام.
مرجعقراءة 10 دقائق

الإدارة

مستوى تحكم الموظفين واجهة إدارة Django تراعي الأذونات لعمليات المنصة. وهي لا تستخدم مقاييس تجريبية ولا تتجاوز أذونات النماذج.

نظرة عامة على عمليات مستوى تحكم فريق المنصة مع حركة المرور والكتالوج والإيرادات وقوائم القرارات
نظرة الموظفين العامة لقطة حية تراعي الأذونات لسجلات المنصة الحالية.

حد الوصول

  • وصول الموظفين يتطلب is_staff. ودور admin في مساحة العمل لا يمنح صفة موظف المنصة.
  • يمكن فرض التحقق بخطوتين على كل حساب من إعدادات الموقع.
  • تُحترم أذونات نماذج Django وسلوك ModelAdmin المسجّل.
  • قد تكون قراءات الإدارة أوسع من الكتابات؛ ومع ذلك تظل ملكية الكائن وحالة المزوّد تحكمان الإجراءات المهمة.
  • ينبغي أن ينشئ كل إجراء حساس حدث تدقيق يتضمن الفاعل والهدف والبيانات الوصفية.

نظرة عامة على العمليات

يعرض /admin/ لقطة حية للقراءة فقط مبنية من السجلات الحالية: حركة المرور، وAPIs العامة، والمستهلكون النشطون، ومساحات العمل النشطة، ورسائل التواصل، واعتماد التحقق بخطوتين، وإشعارات المنصة، وطوابير الاهتمام، وحالة الدفع، وتدفق التدقيق، وتجربة الموقع، وتغطية اللغات.

  • إجراءات سريعة: إنشاء API، مراجعة المورّدين، إعدادات الموقع، خطط المنصة، استوديو المحتوى، النشرة البريدية، اللافتات، الروابط.
  • طوابير القرار: المورّدون، الإشراف، الاستئنافات، قيود السلامة، الدعم، webhooks الفاشلة، الدفعات، الفواتير، صندوق رسائل التواصل.
  • لوحة الدفع: الإيرادات حسب المزوّد، والاشتراكات النشطة، وMRR، وعمليات الدفع المعلقة، وإيصالات webhook، والاستردادات، وروابط البوابة.

أقسام مستوى التحكم

القسمالنماذج / سير العمل
كتالوج APIالمنتجات والفئات والإصدارات وendpoints والمراجعات وفحوص التوفر وإعدادات البوابة.
المورّدونمراجعة ملف المورّد واعتماده وتعليقه وإعادة تقديمه.
المالية والدفعاتبوابات الدفع والفواتير والدفعات ودفتر الأستاذ والكوبونات وأحداث الدفع والاستردادات وأحداث المزوّد.
تذاكر الدعمالطوابير والأولوية والحالة وسياق الطلب والردود.
الثقة & السلامةتقارير إساءة الاستخدام والاستئنافات وسياسة الإشراف وحظر الملفات وسجل الإنفاذ.
الموثوقية والاستخدامسجلات الطلبات وسجلات idempotency وأحداث الاستخدام والعدادات الشهرية وأحداث التدقيق.
مساحات العمل والوصولالمؤسسات والعضويات والدعوات والتطبيقات ومفاتيح API والخطط والاشتراكات وخطط المنصة.
التكاملاتendpoints webhook وسجل التسليم.
النشرة البريدية & البريدالقوالب والقوائم وجهات الاتصال والشرائح والحملات والأتمتة والبريد المتتبع والأحداث والإعدادات.
تجربة الموقعالوسائط والمجموعات وإعدادات الموقع والتنقل وصفحات المحتوى والأصول المخصصة واللغات.
الهوية & الأمانالمستخدمون ورموز الدخول والمجموعات والرموز المحظورة/المعلّقة.
الرسائل & المجتمعإشعارات المنصة ورسائل التواصل والرسائل المباشرة والتفضيلات والمتابعات وإشعارات المستخدم ورسائل التذاكر.

الإشراف والسلامة

  • تحمل التقارير نوع/تسمية الهدف والفئة والأدلة والأولوية وموعد SLA النهائي والإسناد وملخصات الحل الخاصة/العامة.
  • يهيّئ الموظفون نوافذ SLA حسب الأولوية وحدود التصعيد ونوافذ الاستئناف في سياسة الإشراف.
  • يمكن استئناف التقارير المغلقة المؤهلة مرة واحدة داخل النافذة؛ ويبقى القرار العام الأصلي مرفقًا.
  • تعيد الاستئنافات المقبولة فتح الحالة بـ SLA جديد مشتق من السياسة.
  • يمكن أن يصدر حل تقرير مؤيّد إنفاذًا أمنيًا قابلًا للتدقيق: تحذير، أو تقييد مجتمعي، أو تقييد نشر، أو تقييد على المنصة.
  • تعرض سجلات الإنفاذ النقاط والسبب العام وتواريخ السريان والحالة، ولا يقرأها إلا المستخدم المتأثر أو أعضاء المورّد النشطون.

الدعم والفريق

  • تربط التذاكر المستهلك والمنتج والاشتراك وسياق سجل الطلب الاختياري.
  • تقدّم الرسائل الطابع الزمني لنشاط التذكرة لتبقى الطوابير مرتبة حسب آخر رد.
  • دعوات الفريق وتغييرات الأدوار والتعطيل والإزالة مقصورة على المالك/المسؤول؛ ولا يمكن إزالة آخر مالك نشط.
  • الدعوات مجزأة وأحادية الاستخدام ومرتبطة بالبريد الإلكتروني وتنتهي صلاحيتها.

خطط المنصة والمطابقة

  • خمس خطط منصة كحد أقصى؛ وتبقى الرموز ثابتة بعد الإنشاء.
  • سعر العرض، ومعرّفات المزوّد السنوية/الشهرية، وحد مساحات العمل، وحد إدراج API، والمزايا، والتوصية.
  • لا تُنشر الخطط المدفوعة حتى يتوفر زوج من المبلغ ومعرّف سعر متكرر لدى المزوّد.
  • تعرض مطابقة اشتراك المنصة للقراءة فقط الحالة والاستحقاق دون السماح بانحراف الموظفين عن المزوّد.

إشعارات المنصة

تتوزع الإشعارات التي يكتبها الموظفون إلى صفوف صندوق وارد لكل مستخدم. ويمكن أن يكون الجمهور كل الحسابات أو الموظفين فقط؛ والمستويات هي معلومات وإشعار وحرج. وتظهر أعداد التسليم في لقطة العمليات.

التدقيق وعمليات التصدير

  • أحداث تدقيق للإضافة فقط تتضمن الفاعل والإجراء والمؤسسة والهدف والبيانات الوصفية.
  • تدعم مهام التصدير مراجعة الأمان وسير عمل الاحتفاظ.
  • تعرض قوائم الإدارة طرق عرض مفلترة وبحثًا وCSV حيث يلزم.
  • لا تضع أبدًا أسرارًا خامة أو مفاتيح API أو حمولات المزوّد في بيانات التدقيق الوصفية.

إدارة اللغات

لغات الموقع → إدارة الترجمات تعرض اللغات المضمّنة والمدارة والتغطية والمفاتيح الناقصة. ويمكن تعديل الفرنسية المضمّنة عبر طبقة إدارية. ويدعم الاستيراد/التصدير JSON وقيم TypeScript الحرفية؛ وتُتجاهل المفاتيح غير المعروفة ويُبلّغ عنها.

مرجعقراءة 10 دقائق

مرجع API

واجهة FastRestful API مبنية على Django REST Framework وجذورها عند /api/v1/. وتقدّم الواجهة الخلفية OpenAPI وهو العقد المرجعي.

عناوين URL الأساسية والوثائق

الواجهةURL
جذر APIhttps://api.example.com/api/v1/
مخطط OpenAPI/api/schema/
Swagger UI/api/docs/
الصحة/api/health/live، /api/health/ready
مضيف المنتجhttps://{product-slug}.api.example.com
اسم مسار المنتج البديل/api/v1/{product-slug}/...

المصادقة

الحصول على الرموز
curl --request POST \
  --url 'https://api.example.com/api/v1/auth/token/' \
  --header 'Content-Type: application/json' \
  --data '{"username":"you@example.com","password":"..."}'

# Response
{"access":"...", "refresh":"...", "user": {...}}
استدعاء مصادق عليه
curl --request GET \
  --url 'https://api.example.com/api/v1/dashboard/consumer/' \
  --header 'Authorization: Bearer <access>' \
  --header 'X-Organization: <organization-uuid>'

مساحات الأسماء

البادئةالغرض
/auth/الرمز والتحديث والتسجيل وme وتسجيل الخروج وإعادة تعيين كلمة المرور والملف الشخصي و2FA وSSO وSAML والدعوات.
/orgs/، /memberships/، /organization-invites/مساحات العمل والأدوار والدعوات والفريق.
/products/، /versions/، /endpoints/، /plans/، /categories/الكتالوج ودورة حياة API.
/applications/، /keys/، /subscriptions/وصول المستهلك واستحقاقاته.
/dashboard/نماذج قراءة ملخصات المستهلك والمورّد.
/gateway/execute/مغلّف البوابة الآمن القديم (يُفضّل المسارات المباشرة).
/request-logs/، /usage-events/، /usage-counters/القياس والمراقبة التشغيلية.
/invoices/، /payouts/، /ledger/، /coupons/، /billing/الأموال والاستردادات وwebhooks المزوّد.
/support/ (التذاكر، رسائل التذاكر)طابور الدعم والردود.
/media/، /media-collections/مكتبة الوسائط وأداة الاختيار.
/newsletter/التسجيل العام والتتبع والتفضيلات.
/short-links/الروابط القصيرة وQR والنقرات والصحة والاستيراد/التصدير.
/announcements/تسليم اللافتات العامة والأحداث.
/platform/الإعدادات والهوية والبيانات الوصفية ومحتوى الموقع والخطط والاشتراكات واللغات والأصول والتوفر.
/moderation-appeals/، /safety-enforcements/سجل حالات السلامة والقيود.
/messages/، /blocks/، /reports/، /reviews/المجتمع والثقة.
/audit-events/، /export-jobs/سجل التدقيق وعمليات التصدير.
/webhook-endpoints/، /webhook-deliveries/إدارة webhooks الموقّعة.

خريطة endpoints الأساسية

الطريقة + المسارالغرض
POST /auth/token/، POST /auth/token/refresh/تسجيل الدخول بكلمة المرور وتحديث الرمز الدوّار.
POST /auth/register/أنشئ مستخدمًا وأول مساحة عمل اختيارية.
GET /auth/me/مستخدم الجلسة والمؤسسات وقدرة النشر.
GET /orgs/، GET /memberships/مساحات العمل وعضوية الأدوار.
GET /products/، GET /products/{slug}/كتالوج المنتجات العام والمرئي للمستأجر.
POST /products/{slug}/import-spec/استورد عقد OpenAPI أو Swagger إلى إصدار مسودة.
GET /versions/{id}/diff/?against=قارن عقدي إصدارين.
POST /versions/{id}/promote/رقِّ إصدارًا متحققًا منه وأحِل الإصدار الحي السابق للتقاعد.
GET /products/{slug}/publication-readiness/أعد بوابات النشر الأربع.
GET /applications/، GET /keys/تطبيقات المستهلك وبيانات اعتماد محددة النطاق.
POST /keys/{id}/rotate/، POST /keys/{id}/revoke/استبدل مفتاحًا أو أبطله بأمان.
GET /subscriptions/، POST /{id}/cancel/الخطط النشطة والإلغاء.
POST /subscriptions/{id}/change-plan/انتقل إلى خطة أخرى مؤهلة.
POST /gateway/execute/مغلّف البوابة الآمن القديم.
GET /dashboard/consumer/، GET /dashboard/vendor/نماذج قراءة ملخصات المستهلك والمورّد.
GET /request-logs/سجل طلبات محجوب ومحدد النطاق بالمستأجر.
GET /usage-events/، GET /usage-counters/تفاصيل القياس والعدادات الشهرية.
GET /invoices/، POST /invoices/{id}/pay/سجل الفوترة والدفع لدى المزوّد.
POST /invoices/{id}/refund/استرداد كلي أو جزئي عبر البوابة الأصلية.
GET /payouts/، POST /payouts/{id}/transfer/تسوية المورّد والتحويل عبر المزوّد.
POST /payouts/{id}/reconcile/طبّق نتيجة المزوّد الصارمة على دفعة.
GET/POST /media/، GET /media/supported-types/مكتبة الوسائط والتحقق من الرفع.
POST /newsletter/subscribe/اشتراك عام في القائمة، مع تأكيد مزدوج اختياري.
GET /short-links/، GET /short-links/{id}/qr/إدارة الروابط وإعادة التوجيه وأصول QR.
GET /announcements/?path=أفضل لافتة عامة لكل موضع.
GET /platform/branding/، GET /platform/site-content/الغلاف العام والبيانات الوصفية والتنقل والمحتوى المنشور.
GET /platform/plans/، GET /platform/subscription/خطط المنصة والاستحقاق الحالي.
GET /platform/locales/، GET /platform/assets/طبقات اللغة النشطة والأصول المخصصة.
GET /tickets/، GET/POST /ticket-messages/طابور الدعم والردود وسياق الطلب.
GET /reports/، GET /moderation-appeals/سجل حالات السلامة وأهلية الاستئناف.
GET /webhook-endpoints/، GET /webhook-deliveries/تهيئة webhooks الصادرة وأدلة التسليم.
GET /audit-events/، GET /export-jobs/سجل التدقيق وحالة التصدير.

ترقيم الصفحات والتصفية

تستخدم endpoints القوائم عقد ترقيم صفحات: page وpage_size وsearch وordering ومرشحات الموارد. وتستخدم الاستجابات {count, next, previous, results}. ويقبل الترتيب اسم حقل، مع بادئة اختيارية -.

مثال
GET /api/v1/products/?page=2&page_size=25&search=delivery&ordering=-rating_average
GET /api/v1/invoices/?status=paid&ordering=-created_at
GET /api/v1/request-logs/?status_class=server&ordering=-created_at

بنية الخطأ

تستخدم أخطاء التحقق كائن DRF الذي تُستخدم فيه أسماء الحقول مفاتيح. وتستخدم أخطاء البوابة والمنصة كائن JSON يتضمن رمزًا قابلًا للقراءة آليًا ورسالة بشرية وبيانات إعادة محاولة اختيارية.

خطأ نموذجي
{
  "detail": "Monthly quota exceeded.",
  "code": "quota_exceeded",
  "retry_after": 300
}

بنية استدعاء البوابة

طلب مباشر
GET https://signal-stack.api.example.com/v2/deliveries?limit=10
X-API-Key: fr_live_…
Idempotency-Key: request-8241

{
  "status": 200,
  "latency_ms": 84,
  "content_type": "application/json",
  "data_preview": "...",
  "headers": {...}
}

webhooks

هناك نوعان من webhook في FastRestful. أبقِهما منفصلين:

النوعالاتجاهالغرض
webhooks المورّد الصادرةمن FastRestful إلى خادمكأبلغ أنظمتك بأحداث المنصة. موقّعة بـ X-FastRestful-Signature: sha256=<hex> وX-FastRestful-Event.
webhooks مزوّد الدفعمن المزوّد إلى FastRestfulسوِّ الفواتير والاشتراكات والاستردادات والدفعات. وتختلف مخططات التوقيع حسب المزوّد.
مسارات مزوّد الدفع
POST /api/v1/billing/stripe-webhook/
POST /api/v1/billing/paypal-webhook/
POST /api/v1/billing/flutterwave-webhook/
POST /api/v1/billing/paystack-webhook/
POST /api/v1/billing/razorpay-webhook/
  • يجب أن تستخدم endpoints webhook الخاصة بالمورّد HTTPS وأن تخزّن سر توقيع.
  • التسليمات موقّعة وتُعاد محاولتها بأمان وتُسجّل مع الحالة ومعاينة الاستجابة.
  • تُسجّل webhooks مزوّد الدفع في لوحة تحكم كل مزوّد، لا في قسم webhook المورّد.
  • معرّفات أحداث المزوّد فريدة؛ وتُقبل الأحداث الموقّعة المكررة دون تسوية مزدوجة.
  • التهيئة وقوائم أحداث webhook في بوابات الدفع خطوة بخطوة.

سير عمل OpenAPI

shell
cd backend
python3.11 manage.py spectacular --file schema.yml --validate

استخدم المخطط المولّد لأدوات SDK أو Postman أو اختبارات العقود. وعقود OpenAPI على مستوى المنتج منفصلة: تُستورد في إصدارات API وتُرقّى عبر مسار الإصدار.

عند التعثر

إذا أعاد endpoint رمزًا غير متوقع، فتحقق أولًا من معرّف الطلب وطريقة المصادقة وترويسة مساحة العمل وحالة الاشتراك. ويغطي دليل استكشاف الأخطاء أنماط الفشل الشائعة بالترتيب.