- docs/00-15: دراسة، بنية، محرك تعرفة، تسعير، نموذج استئجار، تكاملات، بيانات، realtime، خطة، devops، لاندنج، مخاطر، اصطلاحات سيرفر، تدفق نشر - backend/: NestJS 11 على Docker (health + tenants + عزل tenant_id + بادئة tripz_ + Redis DB 3) - apps/rider, apps/driver, dashboards/admin-web, dashboards/superadmin-web (هياكل) - sync-to-server.sh + .gitignore Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
3.2 KiB
3.2 KiB
06 — نموذج الاستئجار متعدد المستأجرين
وضعان
1. القياسي (Shared) — الافتراضي
- نشرة واحدة مشتركة، قاعدة واحدة، عمود
tenant_idفي كل جدول. - نطاق إلزامي على مستوى الـ Repository (نفس نمط انطلق الحالي).
- الأرخص تشغيلاً والأسرع تحديثاً. يخدم باقات انطلاقة/علامة/أسطول+.
2. السيادة (Sovereign / Enterprise)
- نسخة معزولة كاملة (Docker Compose / K8s namespace) داخل بلد المستأجر أو على خوادمه.
- نفس الكود، متغيرات بيئة مختلفة — لا فرع كود منفصل.
- المنتج المضاد لثغرة Onde السيادية. يخدم باقة سيادة.
فرض العزل (الأهم أمنياً)
- كل استعلام يُنطَّق بـ
tenant_id— لا استثناء. - يُفرض عبر أحد نمطين (يُحسم في P0):
- Repository scoped: مستودع مخصّص يحقن الشرط تلقائياً.
- TypeORM subscriber/query filter: فلتر عام يُضاف لكل استعلام.
TenantGuardيستخرجtenant_idمن الـ subdomain/header/JWT ويحقنه في سياق الطلب (AsyncLocalStorage).- اختبار اختراق العزل ضمن CI: طلب من مستأجر A لا يرى بيانات B أبداً.
حزمة الدولة (Country Pack)
ملف إعداد لكل دولة يجمع كل ما يختلف بين الأسواق:
country: JO
currency: JOD
rounding: { increment: 0.05 }
locale: ar
direction: rtl
phone: { length: 9, prefix: "+962" }
otp: { length: 4, ttl_sec: 300 }
payments: [cash, cliq, zaincash]
sms_provider: local_jo
maps_scope: "amman,zarqa,irbid"
default_tariff_mode: time_or_distance # العداد المنظّم
regulator: ltrc # هيئة تنظيم النقل البري
legal_docs: { terms: jo/terms.md, privacy: jo/privacy.md }
المستأجر الجديد = country pack + هوية بصرية. لا كود جديد.
التطبيقات: كود واحد، نكهة لكل مستأجر
كود موحّد (راكب+سائق)
→ flavor لكل مستأجر (bundle id, أيقونة, ألوان, مفاتيح FCM)
→ إعداد تشغيلي من GET /tenant/config عند الإقلاع
→ fastlane + CI ينشران كل النكهات بأمر واحد
- ديناميكي (من API، بلا إصدار متجر): النصوص، الميزات، طرق الدفع، التعرفة، الألوان.
- بالبناء فقط (flavor): اسم الحزمة، الأيقونة، مفاتيح FCM.
- الهدف الصلب: مستأجر جديد في يوم عمل واحد. إن احتاج أكثر — النموذج لا يتوسع.
جدول tenants (مبسّط)
tenants: id, name, slug, country_pack, plan, mode (shared|sovereign),
branding (jsonb), features (jsonb), status, created_at
راجع 08-data-model للتفصيل.
← السابق: 05-pricing-billing · التالي: 07-integrations