إليك التقرير الفني الشامل لمشروع **Intaleq Passenger App**، مكتوباً بصيغة توثيق تقني (Technical Documentation) موجهة لفريق التطوير، بناءً على تحليل الكود المصدري. --- # 📘 Intaleq Passenger App - Technical Documentation Report **Prepared by:** CTO Office **Target Audience:** Mobile Engineering Team **Version:** 1.0 --- ## 1. 🚀 بداية التشغيل (Initialization & Startup) تعتمد مرحلة الإقلاع على تهيئة الخدمات الأساسية قبل عرض واجهة المستخدم لضمان استقرار التطبيق. ### أ. نقطة الدخول (`main.dart`) - **المسار:** `lib/main.dart` - **الوظيفة:** - يستخدم `runZonedGuarded` لالتقاط الأخطاء العامة (Global Error Handling) وإرسالها للسيرفر عبر `CRUD.addError`. - **تهيئة الخدمات:** يتم تهيئة `GetStorage` (للتخزين المحلي)، `WakelockPlus` (لمنع انطفاء الشاشة)، و `Firebase` (للإشعارات) قبل استدعاء `runApp`. - **إعدادات التوجيه:** يتم تحديد الاتجاه العمودي فقط (`portraitUp`) للجهاز. - **حقن التبعيات (DI):** يتم استدعاء `AppBindings` كـ `initialBinding` لتهيئة المتحكمات الأساسية. ### ب. إدارة التبعيات (`AppBindings`) - **المسار:** `lib/app_bindings.dart` - **الآلية:** - يتم حقن `LocaleController` و `DeepLinkController` بشكل دائم (`permanent: true`) لضمان تواجدهم طوال دورة حياة التطبيق. - يتم استخدام `Get.lazyPut` مع `fenix: true` للمتحكمات الأخرى (مثل `LoginController`) ليتم إنشاؤها عند الحاجة وإعادة إنشائها إذا تم التخلص منها. ### ج. شاشة البداية (`Splash Screen`) - **المسار:** `lib/splash_screen_page.dart` و `lib/controller/home/splash_screen_controlle.dart` - **المنطق:** - يتم عرض انيميشن باستخدام `AnimatedTextKit` و `FadeTransition`. - **العمليات الخلفية:** يقوم `SplashScreenController` بتنفيذ `_initializeBackgroundServices` لتهيئة خدمات التشفير (`EncryptionHelper`) والإشعارات. - **التوجيه الذكي:** تتحقق الدالة `_performNavigationLogic` من وجود بيانات المستخدم في `BoxName`. إذا كان المستخدم مسجلاً ومفعلاً (`isVerified == '1'`)، يتم توجيهه تلقائياً للصفحة الرئيسية، وإلا يتم توجيهه لصفحة الدخول أو الترحيب (`OnBoarding`). --- ## 2. 🔐 دورة المصادقة (Authentication Cycle) يعتمد النظام على مصادقة هجينة (Token-based + Social Auth) مع تخزين آمن. ### أ. التسجيل والدخول (`Sign Up & Login`) - **المسار:** `lib/controller/auth/login_controller.dart` و `register_controller.dart` - **الآلية:** - **Social Login:** يتم استخدام `GoogleSignInHelper` أو `AuthController` (Apple). عند النجاح، يتم إرسال التوكن للسيرفر للتحقق. - **Credentials:** في حالة الدخول التقليدي، يتم استدعاء `loginUsingCredentials` التي تتحقق من البيانات عبر API. - **التحقق (Verification):** إذا رد السيرفر بأن الحساب غير مفعل، يتم تحويل المستخدم لصفحة `PhoneNumberScreen` للتحقق عبر OTP. ### ب. التحقق عبر الهاتف (OTP) - **المسار:** `lib/controller/auth/otp_controller.dart` - **المنطق:** يستخدم كلاس `PhoneAuthHelper` لإرسال OTP (غالباً عبر WhatsApp أو SMS حسب الدولة) ثم التحقق منه عبر الـ Endpoint `verifyOtp.php`. ### ج. إدارة الجلسة والتوكن - **المخزن:** يتم تخزين الـ JWT في `GetStorage` تحت مفتاح `BoxName.jwt`. - **التشفير:** يتم استخدام `EncryptionHelper` لتشفير البيانات الحساسة محلياً. - **التجديد التلقائي:** في كلاس `CRUD`، إذا رد السيرفر بـ `401 Token expired`، يتم استدعاء `getJWT` تلقائياً لتجديد التوكن دون تسجيل خروج المستخدم. --- ## 3. 🗺️ الشاشة الرئيسية والخريطة (Home & Map Logic) تعتبر `MapPagePassenger` هي الواجهة المركزية التي تديرها `MapPassengerController`. ### أ. تحميل الخريطة والموقع - **المسار:** `lib/controller/home/map_passenger_controller.dart` - **المتحكم:** `MapPassengerController` - **المنطق:** - يتم استخدام `location.getLocation()` لجلب موقع الراكب الحالي عند البدء. - يتم تحديد المنطقة الجغرافية (سوريا، مصر، الأردن) عبر دالة `getLocationArea` التي تفحص وقوع الإحداثيات داخل مضلعات (Polygons) محددة مسبقاً. ### ب. السيارات القريبة (Real-time Updates) - **الدالة:** `getCarsLocationByPassengerAndReloadMarker`. - **الآلية:** تقوم بطلب API (مثل `getSpeed.php`) بناءً على نوع السيارة المختار (Speed, Comfort, Lady). يتم تحديث الـ `markers` على الخريطة، ويتم استخدام دالة `_smoothlyUpdateMarker` لتحريك أيقونة السيارة بسلاسة بدلاً من القفز المفاجئ. ### ج. القائمة الجانبية (Drawer) - **المسار:** `lib/views/home/map_widget.dart/map_menu_widget.dart` - **المتحكم:** `MyMenuController` - **الوظيفة:** تدير حالة القائمة (مفتوحة/مغلقة) وتوفر روابط لصفحات الملف الشخصي، المحفظة، والسجل. --- ## 4. 🚕 دورة طلب الرحلة (Ride Request Flow) هذا هو الجزء الأكثر تعقيداً في التطبيق، حيث يدار عبر آلة حالة (State Machine). ### أ. اختيار الوجهة ورسم المسار - **المسار:** `lib/controller/home/map_passenger_controller.dart` - **الوظيفة:** `getDirectionMap`. - **المنطق:** - يتم إرسال نقطة البداية والنهاية إلى خدمة التوجيه (OSRM/Google). - يتم استلام نقاط المسار (Polyline Points) وفك تشفيرها في `Isolate` منفصل (`decodePolylineIsolate`) لتحسين الأداء. - يتم رسم المسار على الخريطة وضبط الكاميرا لتشمل النقطتين. ### ب. اختيار نوع السيارة والسعر - **المسار:** `lib/views/home/map_widget.dart/car_details_widget_to_go.dart` - **الآلية:** يتم عرض قائمة أنواع السيارات (Fixed Price, Comfort, etc.). عند الاختيار، يتم حساب السعر المتوقع بناءً على المسافة والوقت والتعرفة الخاصة بكل نوع والمخزنة في المتحكم (`totalPassengerSpeed`, `totalPassengerComfort`). ### ج. إرسال الطلب (البحث عن سائق) - **الدالة:** `startSearchingForDriver`. - **العمليات:** 1. تغيير الحالة إلى `RideState.searching`. 2. استدعاء `postRideDetailsToServer` لإنشاء سجل الرحلة في قاعدة البيانات. 3. تشغيل المؤقت `_startMasterTimer` الذي يدير دورة البحث. 4. يتم توسيع نطاق البحث (Radius) تدريجياً (مراحل: 2400م -> 3000م -> 3100م) عبر `_findAndNotifyNearestDrivers`. ### د. انتظار السائق - **الواجهة:** `SearchingCaptainWindow`. - **المنطق:** يظهر رادار بحث. يتم التحقق دورياً (`Polling`) من حالة الرحلة في السيرفر. إذا مر الوقت المحدد (90 ثانية) دون قبول، يظهر خيار "زيادة السعر" (`_showIncreaseFeeDialog`). --- ## 5. 🚘 أثناء الرحلة (Active Ride) يتم إدارة هذه المرحلة عبر تحديثات الحالة في `_handleRideState`. ### أ. قبول السائق - **الحدث:** وصول إشعار FCM أو تغيير الحالة في السيرفر إلى `Apply`. - **الإجراء:** يتم استدعاء `processRideAcceptance`. - يتم جلب بيانات السائق وموقعه. - يتم تفعيل تتبع السائق `startTimerFromDriverToPassengerAfterApplied`. - تتغير الواجهة لعرض معلومات السائق والوقت المقدر للوصول. ### ب. بدء الرحلة وميزات الأمان - **بدء الرحلة:** عند وصول حالة `Begin`، يتم استدعاء `processRideBegin`. - **SOS:** زر الاستغاثة يستدعي `makePhoneCall` مع رقم الشرطة أو جهة اتصال الطوارئ المخزنة. - **مشاركة الرحلة:** الدالة `shareTripWithFamily` تولد رابط تتبع مشفر وترسله عبر واتساب. - **تسجيل الصوت:** يتم استخدام `AudioRecorderController` لتسجيل ما يدور في الرحلة لأغراض الأمان. ### ج. إلغاء الرحلة - **الدالة:** `cancelRide`. - **المنطق:** - يتم إرسال طلب `cancel` للسيرفر لتحديث حالة الرحلة. - يتم إرسال إشعار للسائق بالإلغاء. - يتم تصفير الواجهة والعودة للخريطة. --- ## 6. 🏁 ما بعد الرحلة (Post-Ride) ### أ. شاشة الدفع - **المسار:** `lib/controller/payment/payment_controller.dart` - **المنطق:** - يتم الخصم من المحفظة (`addPassengerWallet`) أو الدفع النقدي. - يتم التعامل مع بوابات الدفع الخارجية (مثل Paymob, Stripe) إذا اختار العميل الدفع الإلكتروني. ### ب. التقييم - **المسار:** `lib/views/Rate/rate_captain.dart` و `RateController`. - **الآلية:** يقوم الراكب باختيار عدد النجوم وإضافة تعليق. يتم إرسال البيانات عبر `addRateToDriver`. ### ج. تقديم الشكاوى - **المسار:** `lib/views/home/profile/complaint_page.dart` - **المتحكم:** `ComplaintController`. - **الميزة:** يمكن للراكب تسجيل رسالة صوتية وإرفاقها مع الشكوى، ثم يتم إرسالها للسيرفر عبر `submitComplaintToServer`. --- ## 7. ⚙️ الإعدادات والملف الشخصي ### أ. تعديل البيانات - **المسار:** `lib/views/home/profile/passenger_profile_page.dart`. - **المتحكم:** `ProfileController`. - يسمح بتعديل الاسم، الجنس، ورقم الطوارئ. ### ب. المحفظة - **المسار:** `lib/views/home/my_wallet/passenger_wallet.dart`. - يعرض الرصيد الحالي وسجل المعاملات (`PassengerWalletHistoryController`). ### ج. اللغة - **المتحكم:** `LocaleController`. - يقوم بتغيير لغة التطبيق وتحديث `Get.updateLocale` وحفظ التفضيل في التخزين المحلي.