Files
tripz-llc/docs/22-full-product-roadmap.md

26 KiB
Raw Permalink Blame History

22 — الخريطة الشاملة: من باك إند مكتمل إلى منصّة كاملة مماثلة لسيرو

بعد اكتمال المجموعات A–K (باك إند النواة) واختبار E2E بـ43 محكّاً على السيرفر، هذه خريطة بقية المنتج: كل ما في سيرو + طبقة الـSaaS متعددة المستأجرين + تطبيق فلاتر مُعاد بناؤه. مبنية على دراسة كود سيرو الفعلي لا التخمين. كل مجموعة تُنفَّذ بعد إقرارك، مجموعة مجموعة (أسلوبنا المتّفق).

آخر تحديث: 2026-07-19 — تصحيح حالات M3/O2/O5/P على واقع الكود (كانت الوثيقة متأخرة عن الكوميتات)، + ربط كتالوج الميزات 27.


0. ما درسته في سيرو (سطح الميزات الكامل)

المكوّن ما هو التقنية
siro_rider · siro_driver تطبيقا الراكب والسائق Flutter/GetX
siro_admin تطبيق أدمن المستأجر Flutter (متعدد المنصات)
siro_service تطبيق خدمة العملاء Flutter
transit_dashboard لوحة المواصلات ويب (Vite/JS)
backend/pricing-engine تسعير ديناميكي/ذكاء أسعار المنافسين (انحدار · تجميع · surge · مناطق) Node/TS
backend/marketing_engine بوتات تسويق آلية + مولّد تعليقات Gemini + مهام مجدولة + تقارير PHP + Python
android_bot · socialBot بوتات Kotlin/Android
backend/Admin/geofence السياج الجغرافي PHP
backend/transit + وضع الباص نظام المواصلات (خطوط باص) PHP + Flutter
driver_assurance تأمين السائق PHP
متحكّم موقع السائق (location_controller.dart) تسجيل كل 3ث · رفع دفعات كل دقيقتين · واعٍ للبطارية (توفير عند 20%) · سوكت للبثّ + دفعات للحفظ · وضع باص منفصل · عتبة محفظة −200 Flutter

1. قراراتك المفتوحة — توصياتي

1.1 لوحة الأدمن/السوبر-أدمن/خدمة العملاء: ويب أم تطبيق؟

توصيتي: ويب للثلاثة (الأدمن · السوبر-أدمن · خدمة العملاء)، والموبايل (راكب/سائق) يبقى فلاتر.

  • لماذا ويب: لا احتكاك متجر (تحديث فوري) · يعمل على سطح المكتب حيث يعمل المشغّلون فعلاً · بناء وصيانة أسهل من فلاتر · معيار الصناعة (لوحات أوبر/بولت ويب). سيرو استعمل فلاتر للأدمن لأنه أراد تطبيقاً واحداً، لكن للوحة تحكّم SaaS الويب أنسب.
  • لماذا الموبايل يبقى فلاتر: GPS في الخلفية · overlay · إشعارات · كاميرا/حيوية وجه — كلها تحتاج أصيلاً (native).
  • يطابق قرار بنية المستودع السابق: dashboards/admin-web · dashboards/superadmin-web.

1.2 مواصفات السيرفر (بحث الحمل: 1.15M رحلة/يوم على صندوق مشترك واحد)

الدور المواصفات الحمل
سيرفر مستأجر مشترك (launch/brand) 8 vCPU · 32GB · NVMe عدة مستأجرين صغار على نفس الصندوق (عزل بالبادئة)
سيرفر مستأجر سيادي (sovereign) 8 vCPU · 16–32GB · NVMe مخصّص مستأجر واحد كبير حتى ~1M/يوم
السيرفر الاحتياطي مماثل أو أصغر نسخة Postgres متدفّقة (streaming replica) + Redis AOF
Control Plane (سوبر-أدمن + فوترة) 4 vCPU · 8GB يدير كل المستأجرين، منفصل
  • العنق دائماً Postgres (بركة الاتصالات) لا الـCPU/RAM. Redis 4–8GB يكفي (نصوص صغيرة).
  • الاحتياطي: تكرار فيزيائي متدفّق لـPostgres (hot standby) + docker compose جاهز للإقلاع. RPO ≈ ثوانٍ، RTO ≈ دقائق.
  • التوسّع: نسخ API أفقية خلف Nginx (الـredis-io-adapter مبني أصلاً) قبل تقسيم القاعدة.

1.3 كتالوج الميزات: أساسية مقابل مدفوعة (يوسّع المجموعة K)

فئة ميزات
نواة (كل الباقات) رحلات · مطابقة · محفظة · تقييم · إشعارات · دردشة · مكالمات · وثائق · مركبات
علامة+ محرّك تعرفة كامل · country pack · أنواع رحلات مخصّصة · dispatch
أسطول+ API/Webhooks · تقارير متقدمة · بوابة شركات
مدفوعة منفصلة (add-ons) 🤖 التسعير الديناميكي · 📊 استخبار السوق · 📣 محرّك التسويق/البوتات · 🚌 المواصلات · 🛡️ تأمين السائق · المفاوض الذكي · شرائح السائقين
سيادة كل الميزات + عزل داخل الدولة

1.4 توفير المستأجر من السوبر-أدمن (الخيارات التي تزوّدها)

عند إنشاء مستأجر، السوبر-أدمن يحدّد: الاسم · اللوغو · الدولة (country pack) · وسائل الدفع · الباقة · الميزات المفعّلة · الحدود العددية. أغلبها مبني في K (tenants.features/settings)؛ الناقص: رفع اللوغو + توليد الحزمة (§2 المجموعة N).


1.5 طبقات التطبيق (lite / pro / max) — قرار المالك 2026-07-18 🔒

المطلوب: تُولَّد تطبيقات بـ«نسخ» متفاوتة الميزات، ولا يستطيع من يفكّك نسخة أدنى رؤية ميزات النسخ الأعلى.

القرار: نسخة = بناء مُولَّد، لا fork للكود. مستودع واحد؛ الطبقة تُشتق من باقة المستأجر عبر مانيفست N3.

ثلاث نسخ منسوخة يدوياً = كل إصلاح باغ ×٣ وتباعد خلال شهرين. الطبقة صفة للمستأجر لا قائمةَ متجرٍ إضافية (كل مستأجر له bundle ID خاصه أصلاً). وlite/pro/max ليست مفهوماً جديداً — هي presets فوق كتالوج §1.3.

1) أعلام const لكل ميزة — لا Map وقت التشغيل. بناء AOT يعمل tree-shaking: كود محروس بعلم const قيمته false يُحذف من الـbinary فيزيائياً. هذا ما يحقّق مناعة التفكيك. علم مستقل لكل ميزة (FF_NEGOTIATOR…)؛ لو قرأناها من Map وقت التشغيل بقي الكود كاملاً في الملف وضاع الغرض.

2) الطبقة الأصيلة موحّدة عبر كل الطبقات (شرط Shorebird). Shorebird يرقّع Dart فقط. بتوحيد Kotlin/الصلاحيات/NDK تصير ترقية مستأجر من lite إلى pro patch فورياً بلا مراجعة متجر؛ ولو اختلف الأصيل صار كل ترقية إصداراً جديداً وانتظار مراجعة — أي نخسر أهم ميزة تشغيلية عندنا.

3) طبقتا إعداد، لكلٍّ دورة حياة:

الطبقة متى تُحسم تحوي التغيير يسري بـ
BuildConfig مولَّد (const) وقت البناء (N3) هوية المستأجر · BASE_URL · ألوان · أصول · أعلام الميزات إصدار/patch
مانيفست ريموت (GET /tenant/config) كل إقلاع تشغيل/إطفاء ضمن المبنيّ · وسائل الدفع · ترتيبات · وضع صيانة فوراً

القاعدة الحاكمة: الفعّال = المبني في الـbinary ∩ المانيفست ∩ استحقاقات السيرفر.

4) الحدّ الأمني يبقى السيرفر. التجريد من الـbinary دفاعٌ إضافي وحجمٌ أصغر وUX بلا أزرار مقفلة — لا بديل عن FeatureGuard (docs/19 — K5). أثقل ملكية فكرية (تسعير · مطابقة · surge) سيرفرية أصلاً ولا تظهر في التطبيق.

5) تطبيقاتنا المنشورة (rider/driver بمعرّفات tripz-mobile-store-identity) تبقى بناء max كاملاً — لا نفتّت قوائم منشورة.

البنية المقابلة في فلاتر (Q5): feature-first — كل ميزة موديول مستقل يسجّل نفسه في DI والراوتر فقط إذا علمه مفعّل، فيكون الإقفال من نقطة واحدة لا if مبعثرة في الشاشات.


2. المجموعات القادمة (تكملةً لـA–K)

المجموعة L — إكمال نموذج التسعير (B9/B10/B11 + الديناميكي)

# البند
L1 B9: نقاط CRUD لتحرير التعرفة من لوحة الأدمن (jsonb موجود؛ نحتاج واجهة + تحقّق)
L2 B10: كتالوج أنواع رحلات عالمي جاهز (بدل 6 مبثوثة) — المستأجر يختار منه
L3 B11: بُعد تسعير بالوزن (شحن/توصيل) بجانب المسافة/الزمن
L4 التسعير الديناميكي (من pricing-engine): surge حسب الطلب/العرض في المنطقة + مناطق تسعير. add-on مدفوع. 🔵 جهة الاستقبال جاهزة: tariff.engine يطبّق surge.multiplier × مضاعف geofence. الناقص: البوت الذي يكتب المضاعف (جرد كرونات سيرو الكامل في 27 §4).

المجموعة M — ميزات التشغيل المتقدّمة (F سابقاً)

# البند
M1 المفاوض الذكي: الراكب يعرض سعراً، السائق يقبل/يفاوض (نمط inDrive).
M2 شرائح السائقين (tiers): برونزي/فضي/ذهبي حسب الأداء → أولوية عروض/عمولة أقل.
M3 السياج الجغرافي (من Admin/geofence): مناطق مسموح/ممنوع · تسعير حسب المنطقة · حظر دخول. 🔵 مبني بالكود (a15e65c + fef1235، 2026-07-18): modules/geofence — Redis pub-sub، geofence_promo push عند دخول المنطقة، مضاعف تسعير في tariff.engine. الناقص: واجهة أدمن لرسم المناطق (R4 في 27) + إثبات سيرفر.
M4 تأمين السائق (driver_assurance).

المجموعة N — طبقة الـSaaS: السوبر-أدمن وتوليد التطبيق ⭐ (الهدف الأساسي) — 🔵 قيد التنفيذ

# البند الحالة
N1 لوحة سوبر-أدمن (ويب): إنشاء مستأجر · اسم/لوغو/دولة/دفع/باقة/ميزات · مراقبة. ✅ الباك إند (provision · summary · app-manifest · payment-methods · branding · overview · status خلف PlatformGuard) + dashboards/superadmin-web/index.html (نظرة شاملة + تعليق/تفعيل). التصميم مؤجَّل عمداً لآخر المشوار.
N1a تعليق المستأجر يسري فعلياً (2026-07-18). ✅ كان tenant.status يُكتب ويُعرض بلا أي فرض — أي أن «تعطيل المستأجر» زخرفة والمستأجر غير الدافع يظل يشتغل. الفرض الآن في JwtStrategy (نقطة واحدة، نفس حجّة ربط الجهاز D2) + AuthService.resolveTenant (يخنق sendOtp وverifyOtp معاً). القراءة مكيَّشة (Redis أولاً) والإبطال يجعل التعليق فورياً؛ وتعذّر القراءة يمرّر لا يقطع المنصة كلها (G).
N1b النظرة الشاملة: GET /admin/overview?days= — رحلات · GMV · إيراد المنصة (العمولة) لكل مستأجر. ✅ استعلام واحد مجمَّع لكل المستأجرين (لا N+1). revenue = مجموع العمولة وهو الرقم الذي يهمّ عند التسعير، لا الـGMV.
N1c خدمة اللوحات الثلاث على الإنترنت. ✅ تُخدم من نفس أصل الـAPI عبر useStaticAssets: /panel/superadmin · /panel/admin · /panel/service — بلا CORS وبلا دومين/شهادة ثانية، وترث TLS القائم (docs/20). المجلد مربوط bind من compose فتعديل HTML يظهر بتحديث الصفحة بلا إعادة بناء.
N1d تعيين أول أدمن للمستأجر. ✅ POST /platform/users/role صار يُنشئ المستخدم إن لم يوجد. كان يشترط دخولاً سابقاً، وهذه بيضة ودجاجة: مستأجر مزوَّد حديثاً بلا مستخدمين، فلا سبيل لصنع أول أدمن — أي أن لوحته لا يمكن الدخول إليها إطلاقاً. زر «تعيين أدمن» في لوحة السوبر-أدمن.
N2 رفع اللوغو + توليد الأيقونات/splash. ✅ الرفع مع تحقّق (image-meta.ts: PNG/JPEG · حدّ أدنى 512×512 · مربّع ±5٪ · سقف 5MB) — لوغو صغير أو مستطيل كان يُنتج أيقونة ممطوطة في كل تطبيقات المستأجر ولا يُكتشف إلا بعد بناءٍ ونشر. لم نُدخل sharp: التوليد نفسه شغل flutter_launcher_icons في N3، والباك إند لا يحتاج إلا التحقّق (قراءة ترويسة بلا اعتمادية). زر رفع في اللوحة.
N3 سكربت توليد التطبيق الواحد: bundle ID · أيقونات/splash من اللوغو · FCM · إضافات Kotlin/C++ الأصيلة (overlay · method channels · NDK) · بناء · Shorebird. 🔵 scripts/generate-tenant-app.sh — يجلب المانيفست ويضبط الهيكل؛ خطوات فلاتر موسومة [Q] تُوصَل عند بناء المجموعة Q (المشروع غير موجود بعد). ✅ يولّد الآن lib/core/build_config.dart بأعلام const (§1.5) · يضبط applicationId وPRODUCT_BUNDLE_IDENTIFIER وandroid:label · يجلب اللوغو ويكتب إعدادات flutter_launcher_icons/flutter_native_splash · و--build اختياري يشغّل Shorebird.
N4 لوحة أدمن المستأجر (ويب): سائقون (اعتماد) · رحلات · مراجعة وثائق · سحوبات (تحويل/فشل). ✅ dashboards/admin-web/index.html + نقاط سرد إدارية (/drivers/admin/list · /trips/admin/list · /payouts/admin/list خلف RolesGuard admin/dispatcher). التعرفة والتقارير تُضاف مع L.
N5 لوحة خدمة العملاء (ويب): بحث مستخدم برقمه (فهرس أعمى) · رحلاته · تفاصيل رحلة بالمعرّف. ✅ dashboards/service-web/index.html + GET /admin/users/search · /trips/admin/list?rider=. الشكاوى تحتاج وحدة complaints (لا توجد بعد — بند لاحق).

| N6 | كتالوج تسعير الميزات (قرار المالك 2026-07-19، أُعيد تأكيده مع قائمة الميزات الكاملة — 27-feature-catalog): جدول feature_catalog — المفتاح · الاسم العربي · الفئة (نواة/باقة/add-on) · سعر شهري · رسم إعداد · الوصف — والسوبر-أدمن يحرّر الأسعار من اللوحة. يوسّع K2: الكتالوج نفسه يغذّي الاستحقاقات الافتراضية والتسعير معاً. الإضافات المسعّرة أولاً: استخبار السوق · البوتات/التسويق · التسعير الديناميكي · المواصلات · المفاوض · شرائح السائقين · تأمين السائق. | ⬜ | | N7 | مولّد عرض السعر (الفوترة التعاقدية): في لوحة السوبر-أدمن — اختيار باقة + إضافات ⇒ عرض سعر مجمّع (إعداد مرة واحدة + شهري) يُطبع/يُرسل للعميل عند التعاقد. عند الاعتماد: تُكتب tenants.features آلياً من البنود المختارة (تكامل K3 — لا إدخال يدوي مزدوج ينسى ميزة) + سجل اشتراك شهري يظهر في overview (N1b). | ⬜ |

مصادقة اللوحتين: هاتف + OTP → JWT بدور admin/dispatcher (نفس تدفّق الموبايل). كل الحماية على السيرفر (RolesGuard) — الواجهة عرض فقط. الوصول للوحة معيَّن بـ?tenant=<slug>. اختبار الحراسة: E2E يثبت أن السائق/الراكب (غير أدمن) يُرفضان من كل النقاط الإدارية (403).

اختبار: backend/scripts/provision-test.mjs (يتطلّب PLATFORM_SECRET) — يثبت الحارس، التزويد، تصفية الدفع، الاستحقاقات، والمانيفست.

المجموعة O — التحليلات والمواصلات والتسويق

# البند
O1 تحليل بيانات المواقع: driver_tracks (مبني في H) → خرائط حرارية · تنبّؤ الطلب · سلوك السائق (H6/H7 المؤجَّلتان).
O2 نظام المواصلات (transit + وضع الباص): خطوط · محطات · بثّ موقع الباص منفصل. add-on. 🔵 microservice مبني (backend-transit/ منفصل بقاعدته — f30209b + 4aeab52) + لوحة مشرف. الناقص: التكامل مع تطبيقي الراكب/السائق + كرونات transit الثلاثة (27 §4).
O3 محرّك التسويق (marketing_engine): بوتات آلية · مولّد تعليقات Gemini · مهام مجدولة · تقارير. add-on.
O4 البوتات (socialBot · android_bot): نسخ + تهيئة كـadd-ons مدفوعة خلف الاستحقاقات.
O5 مراجعة المهام المجدولة (cron) وترتيبها — قرار المالك 2026-07-18. ✅ الجرد اكتمل (27 §4 — 24 كروناً بجدولتها من مستودع سيرو نفسه، ومنها فجوة cron_ride_timeout = R1). التوحيد على BullMQ نفسه ⬜. تُجرد كل المهام الدورية (تسويات · تقارير · تجميع التقييمات · تنظيف · استخبار السوق والأخبار) في مكان واحد بجدولة موحّدة عبر BullMQ (بادئة tripz_). المطلوب: مهمة واحدة لا تعمل مرتين عند تشغيل أكثر من نسخة، وسجلّ تنفيذ يُظهر آخر نجاح/فشل — لا مهام صامتة.

المجموعة P — إكمال المدفوعات (بوابات حقيقية) 💰

تُقرأ 24-tenant-wallet-revenue أولاً — فلسفة المال (إيراد مقابل أمانة) تحكم كل بند هنا.

# البند الحالة
P0 محفظتا المستأجر: tenant_wallet (إيراد) وtenant_pending (أمانات) كدفترين مضافَين فقط. الفصل بمحفظتين لا بحقل حالة — استعلامٌ ينسى الشرط يجعل المالك يسحب من مال الركّاب. ✅ مبني بالكود (b1a060c — modules/tenant-wallet)
P1 بوابات فعلية: PayMob (مصر) · CliQ (الأردن) · MTN/SyriaTel/شام كاش (سوريا) — جدول لكل وسيلة + محوّل موحّد. 🔵 PayMob + cash + invoice عبر payment-gateway.registry (d4ac38c، مع إغلاق ثغرة webhook). CliQ · MTN/SyriaTel · شام كاش ⬜
P2 تسوية بالرسائل (كليك/شام كاش بلا API): تطبيق أندرويد يرفع الرسالة خاماً → webhook → استخراج بـGemini → مطابقة فاتورة. تفرّد على مرجع العملية، وطابور مراجعة لما لا يُطابَق. ✅ مبني بالكود (da035e4 — sms-settlement.service + raw_sms + integrations/gemini)
P3 رسم العملية إيراداً: 35 ل.س · 5 ج.م · 20 قرشاً — من إعداد المستأجر لا من الكود (سيرو كتب الرقم مرتين فتناقضا وسرّب مالاً). ✅ (b1a060c — transaction-fee.ts + spec)
P4 تقارير المستأجر: الدخل حسب الوسيلة/اليوم · شحن السائقين مقابل الأمانات · العمولات · المعلّق غير المسوّى. ⬜
P5 تصحيح revenue في /admin/overview: يحسب عمولة الرحلات فقط؛ الإيراد الحقيقي = عمولة الرحلات + شحن السائقين + رسوم العمليات، والأمانات تُستثنى. ✅ (b1a060c)

ملحق P (2026-07-18، غير مخطط أصلاً): وحدة billing كاملة لاشتراكات المستأجرين أنفسهم (SaaS): tenant-subscription + superadmin-payment + webhook PayMob + اعتماد حوالة بنكية (d239f51). هذا نصف N6/N7 العملي — الناقص كتالوج الأسعار والحاسبة.

المجموعة Q — تطبيق فلاتر (إعادة بناء كاملة) 📱

إعادة استعمال الأصيل الثابت (Kotlin/iOS من التطبيق القديم Ride/Tripz)، وإعادة بناء Dart من الصفر بـCubit+Bloc (لا GetX). راجع tripz-mobile-store-identity لمعرّفات المتاجر التي يجب الحفاظ عليها.

📜 القانون المُلزِم: 23-flutter-conventions — يُقرأ كاملاً قبل أي كود Dart. الحالة (2026-07-18): هيكل التطبيقين متطابق حرفياً (core/ + features/auth + features/home)؛ Dart القديم (GetX) أُزيل من السائق مع الإبقاء على الأصيل والإضافات وشهادات التوقيع وShorebird وFirebase. طبقة الشبكة تُرسل x-device-id وتجدّد التوكن عند 401 مرة واحدة. الحزم موحّدة بين التطبيقين والـAPI صار https حصراً (usesCleartextTraffic=false في الاثنين).

# البند
Q1 الأساس: splash · onboarding · login (هاتف+OTP، بلا كلمة مرور) · الخريطة (flutter_map + بلاطات انطلق).
Q2 الراكب: صفحة الطلب · اختيار الوجهة/التوقفات · widgets الرحلة · تتبّع السائق حياً · الدفع · التقييم (شاشة إجبارية عند وجود رحلة معلّقة).
Q3 السائق: overlay العرض · قبول · widgets الرحلة · متحكّم الموقع (تسجيل 3ث/رفع دفعات/واعٍ للبطارية — نمط سيرو) · حيوية الوجه · الرصيد/الشحن.
Q4 الخرائط المتقدّمة: خريطة حرارية · خريطة تنبّؤية (من O1).
Q5 البنية التحتية للتطبيق: طبقة الشبكة (توقيع HMAC · x-device-id) · country pack ديناميكي · flavors · طبقتا الإعداد وأعلام const حسب §1.5 · موديولات feature-first تُسجَّل حسب العلم.
Q6 نظام التصميم الثابت — 26-flutter-design-system (قرار المالك 2026-07-19): tokens · ثيم ليلي/نهاري من بذرة المستأجر · خطوط ثابتة (Inter + IBM Plex Sans Arabic مضمّنة محلياً) · اتجاه وخط يتبعان اللغة · TripzScaffold + عدة مكونات core/ui/ · ARB للترجمة. يُبنى قبل شاشات Q1–Q3 — ترتيب البناء في 26 §11.

3. ترتيب التنفيذ المقترح

  1. L (التسعير) — يكمل النواة المالية، باك إند صرف، سريع.
  2. N ⭐ (السوبر-أدمن + توليد التطبيق) — الهدف الأساسي؛ يجعل المنتج قابلاً للبيع لمستأجر جديد.
  3. Q (فلاتر) — بالتوازي مع N، لأنه أطول جزء.
  4. M (ميزات متقدّمة) · P (بوابات) · O (تحليلات/بوتات) — add-ons تُباع تِباعاً.

4. ما لا أعرفه بعد (أحتاج دراسة أعمق قبل تنفيذ كل مجموعة)

  • تفاصيل pricing-engine (خوارزميات surge الفعلية) — قبل L4.
  • بروتوكول intaleq_maps وبلاطات انطلق للـflutter_map — قبل Q1.
  • تفاصيل إضافات Kotlin/C++ (overlay/NDK) وربطها بـbundle ID — قبل N3.
  • API بوابات الدفع الفعلية (PayMob/CliQ/MTN) — قبل P1.

← ذو صلة: 17-backend-backlog · 05-pricing-billing · 06-tenant-model · 19-entitlements-licensing · 20-tls