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,64 @@
|
||||
# 03 — خطة تطبيقات الموبايل (Flutter)
|
||||
|
||||
## الحزمة التقنية
|
||||
- **Flutter** (أحدث مستقر) + **Dart 3**.
|
||||
- إدارة الحالة: **flutter_bloc** — **Cubit** افتراضياً، **Bloc كامل** لآلتَي حالة فقط.
|
||||
- التوجيه: **go_router** · الحقن: **get_it** (+ injectable اختياري).
|
||||
- الشبكة: **dio** + interceptors (tenant header, auth, retry).
|
||||
- الخرائط: عميل انطلق (بلاطات vector عبر `maplibre_gl` أو ما يعادله فوق Martin).
|
||||
- الترجمة: **flutter_localizations** + ARB، RTL أول درجة.
|
||||
|
||||
## لماذا Cubit افتراضياً؟
|
||||
الانتقال من GetX Controller شبه مباشر: `Controller` → `Cubit`، `update()` → `emit(state)`. نكسب قابلية الاختبار (`bloc_test`) والقبول الصناعي لمنتج يُرخّص ويُدقّق، دون كلفة أحداث Bloc الكاملة في الشاشات الاعتيادية.
|
||||
|
||||
## أين نستخدم Bloc الكامل (حصراً)
|
||||
| آلة الحالة | لماذا Bloc |
|
||||
|-----------|-----------|
|
||||
| **دورة حياة الرحلة (راكب)** | سلسلة انتقالات مسماة تأتيها أحداث من 3 جهات (المستخدم، socket، مؤقتات) — الأحداث الصريحة تمنع أخطاء التزامن وتعطي سجل انتقالات للتشخيص |
|
||||
| **تدفق العروض/الطلبات (سائق)** | نفس السبب: عروض تصل وتنتهي صلاحيتها بتزامن حسّاس |
|
||||
|
||||
## بنية الحزمة (packages / flavors)
|
||||
كود موحّد + نكهة لكل مستأجر:
|
||||
```
|
||||
mobile/
|
||||
├── packages/
|
||||
│ └── tripz_core/ # مشترك: نماذج، شبكة، تعرفة، خرائط، ثيم، l10n
|
||||
├── apps/
|
||||
│ ├── rider/ # تطبيق الراكب
|
||||
│ └── driver/ # تطبيق السائق
|
||||
└── flavors/ # إعداد لكل مستأجر (bundle id, ألوان, أيقونة, مفاتيح)
|
||||
```
|
||||
- **ما يتغير بالبناء فقط:** bundle id، الأيقونة، اسم التطبيق، مفاتيح FCM → في الـ flavor.
|
||||
- **ما يمكن جعله ديناميكياً:** النصوص، الميزات المفعّلة، طرق الدفع، التعرفة، الألوان → يُجلب من `GET /tenant/config` عند الإقلاع.
|
||||
- **درء رفض آبل (بند 4.3):** كل نكهة بأصول ومحتوى متجر مميّز؛ خيار «التطبيق الجامع» (راكب واحد يضم مشغّلين) للباقة المجانية.
|
||||
|
||||
## طبقات كل تطبيق
|
||||
```
|
||||
lib/
|
||||
├── main_<flavor>.dart # نقطة دخول لكل نكهة
|
||||
├── app.dart # MaterialApp.router + ثيم + l10n
|
||||
├── core/ # DI, router, dio client, config bootstrap
|
||||
├── data/ # repositories, data sources, models (DTO↔domain)
|
||||
├── domain/ # entities, use cases (نقية)
|
||||
└── features/
|
||||
├── auth/ # cubit + screens
|
||||
├── home/ # الخريطة + طلب رحلة
|
||||
├── trip/ # ★ TripBloc (Bloc كامل) + شاشات دورة الرحلة
|
||||
├── offers/ (سائق) # ★ OffersBloc (Bloc كامل)
|
||||
├── earnings/ (سائق) # cubit
|
||||
├── wallet/ # cubit (P3)
|
||||
├── chat/ rating/ profile/ settings/ # cubits
|
||||
```
|
||||
|
||||
## الشاشات الأساسية (P1)
|
||||
**الراكب:** onboarding/OTP → الخريطة والطلب → اختيار الوجهة والسعر المقفول → انتظار الإسناد → تتبع حي → دردشة → إنهاء ودفع كاش → تقييم · العناوين المفضلة · السجل.
|
||||
**السائق:** OTP → تسجيل بالوثائق → الحالة (متصل/مشغول) → استقبال العرض → التوجّه/الوصول → بدء/إنهاء الرحلة → الأرباح.
|
||||
|
||||
## قواعد الهندسة
|
||||
- **لا منطق عمل في الـ Widgets** — في الـ Cubit/Bloc والـ use cases.
|
||||
- **الثيم والنصوص من config** حيث أمكن — لا قيم مبعثرة.
|
||||
- **RTL افتراضي**، اختبار كل شاشة بالعربية أولاً.
|
||||
- **اختبار:** `bloc_test` لكل Cubit/Bloc حرج + golden tests للشاشات الرئيسية.
|
||||
- تجريد الخرائط في `tripz_core/maps` لتبديل المزوّد لأي مستأجر خارج تغطية انطلق.
|
||||
|
||||
← السابق: [02-backend-plan](02-backend-plan.md) · التالي: [04-tariff-engine](04-tariff-engine.md)
|
||||
Reference in New Issue
Block a user