first commit: منصة Tripz — خطط كاملة + سكافولد باك إند NestJS/Docker
- 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>
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
# 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)
|
||||
ملف إعداد لكل دولة يجمع كل ما يختلف بين الأسواق:
|
||||
```yaml
|
||||
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](08-data-model.md) للتفصيل.
|
||||
|
||||
← السابق: [05-pricing-billing](05-pricing-billing.md) · التالي: [07-integrations](07-integrations.md)
|
||||
Reference in New Issue
Block a user