From b7e91e5de62ff0942f88715ceba56b49da3cc061 Mon Sep 17 00:00:00 2001 From: Hamza Date: Fri, 17 Jul 2026 01:42:04 +0300 Subject: [PATCH] docs: backend backlog from owner review + Siro schema comparison (17) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Groups: A realtime/FCM/Redis/race · B trip model (started/waiting/price split/stops) · C driver+car data (color_hex, ai_data) · D security (phone normalize EG, device fingerprint, HMAC) · E fraud (driver_ride_scam) · F chat Co-Authored-By: Claude Opus 4.8 --- docs/17-backend-backlog.md | 86 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 docs/17-backend-backlog.md diff --git a/docs/17-backend-backlog.md b/docs/17-backend-backlog.md new file mode 100644 index 0000000..2579da5 --- /dev/null +++ b/docs/17-backend-backlog.md @@ -0,0 +1,86 @@ +# 17 — Backlog الباك إند (مراجعة المالك + مقارنة سيرو) + +> مصدره: مراجعة المالك (2026-07-17) + قراءة مباشرة لجداول سيرو (`schema_primary.sql`, `schema_ride.sql`). +> الترتيب حسب الأثر. نمشي **مجموعة مجموعة**. + +--- + +## المجموعة A — الزمن الحقيقي والإشعارات (الأعلى أولوية) +> شكوى المالك الأساسية: «تسأل القاعدة كثيراً، أقرب للـ polling»، والإشعارات ناقصة. + +| # | البند | التفصيل | +|---|-------|---------| +| A1 | **FCM على كل حالات الرحلة** | حالياً push عند `assigned` فقط. المطلوب: FCM **+** WebSocket على **كل** انتقال. ضروري للخلفية (background). | +| A2 | **ترجمة الإشعارات** | الإشعارات تُرسل إنجليزي والهاتف عربي → نصوص الإشعارات في **ملفات ترجمة** وتُرسل حسب لغة المستخدم. | +| A3 | **تقليل استعلامات القاعدة** | حالة الرحلة الجارية + المواقع في **Redis**؛ القاعدة للحقيقة الدائمة فقط. (الآن كل انتقال يقرأ/يكتب عدة مرات + يقرأ السائق ثانيةً). | +| A4 | **Race condition عند القبول** | سائقان يقبلان بنفس اللحظة → **قبول ذرّي** (Redis SETNX / UPDATE شرطي `WHERE status='searching'`). أول قبول يفوز، والثاني يُرفض بوضوح. | +| A5 | **إلغاء العرض عند القبول** | فور القبول: بث WebSocket **+ FCM** لبقية السائقين المعروض عليهم → «الرحلة لم تعد متاحة» فتختفي من شاشتهم/الـ overlay. | +| A6 | **الرحلات المتاحة (available rides)** | قائمة طلبات متاحة يسحبها السائق (بديل/مكمّل للعرض المباشر). | +| A7 | **overlay أندرويد** | معلومات الرحلة للقبول/الرفض فوق التطبيقات — يحتاج FCM data-message + payload كامل. | + +--- + +## المجموعة B — اكتمال نموذج الرحلة +> مقارنة بجدول `ride` في سيرو + قواعد التشغيل. + +| # | البند | التفصيل | +|---|-------|---------| +| B1 | **حالة `started` وفصل الوصول عن البدء** | السائق وصل ≠ الرحلة بدأت. الراكب قد لا يرد/يلغي. نحتاج تمييزاً صريحاً. | +| B2 | **عدّاد انتظار 5 دقائق (قانون)** | يبدأ عند وصول السائق (بعد **تأكيد المسافة** من فلاتر). عند انتهائه: خيار للراكب — يبقى السائق منتظراً، أو **تعويض** فترة الانتظار. | +| B3 | **احتساب مشوار الوصول للراكب** | المسافة/الزمن من موقع السائق حتى الراكب تُحتسب بالتعرفة (دقائق + مسافة). | +| B4 | **نقاط توقف (stops)** | نقطتا توقف ضمن الرحلة (كما في سيرو/شير). | +| B5 | **حجز مسبق/جدولة** | جداول الرحلة (`date`/`time`/`endtime` في سيرو). | +| B6 | **فصل السعر** | `price_for_driver` مقابل `price_for_passenger` (العمولة) — **ناقص عندنا**. | +| B7 | **طوابع زمنية دقيقة** | `DriverIsGoingToPassenger` · `rideTimeStart` · `rideTimeFinish` (سيرو) — عندنا `assigned_at`/`completed_at` فقط. | +| B8 | **مطابقة الوجهة** | `is_destination_match` + خصم الراكب. | +| B9 | **تعديل التعرفة من لوحة الأدمن** | جداول تعرفة قابلة للتحرير (موجودة كـ jsonb — نحتاج واجهة/نقاط CRUD). | + +--- + +## المجموعة C — بيانات السائق والمركبة (من سيرو) + +| # | البند | التفصيل | +|---|-------|---------| +| C1 | **CarRegistration كامل** | `vin` · `car_plate` · `make` · `model` · `year` · `expiration_date` · **`color` + `color_hex`** (لتلوين السيارة في فلاتر) · `owner` · `fuel` · `isDefault` · `vehicle_category_id` · `fuel_type_id` · `status`. | +| C2 | **حقول السائق** | `gender` · `national_number` (فريد) · `name_arabic` · `first/last_name` · `birthdate` · `license_type/categories/issue/expiry` · `address` · `accountBank`/`bankCode` · `employmentType` · `maritalStatus` · **`rejected_reason`** (سبب رفض خدمة العملاء). | +| C3 | **`ai_data` + `user_input`** | تخزين مخرجات Gemini الخام **و** ما أدخله السائق — للمقارنة والتدقيق (نمط سيرو). | +| C4 | **صور السيارة ×2** | صورتان للمركبة (لا واحدة). | +| C5 | **فيديو/liveness للوجه** | تأكيد حيّ للوجه (غير السيلفي الثابت). | + +--- + +## المجموعة D — الأمان والمصادقة + +| # | البند | التفصيل | +|---|-------|---------| +| D1 | **تطبيع أرقام الهاتف (JO/EG/SY)** | خصوصاً **مصر**: الناس تكتب `01…` بدل `1…` وتظن المفتاح `2` لا `20`. نحتاج normalize احترافي لكل دولة. | +| D2 | **بصمة الجهاز (device fingerprint)** | تُرسل من فلاتر مع **كل** request وتُربط بالجلسة (نمط سيرو: التوكن المسروق لا يعمل على جهاز آخر). | +| D3 | **HMAC للعمليات الحساسة** | خصوصاً **المدفوعات** — توقيع الطلب. | + +--- + +## المجموعة E — كشف الاحتيال (من `driver_ride_scam`) + +| # | البند | التفصيل | +|---|-------|---------| +| E1 | **تسجيل زر الاتصال** | `isDriverCallPassenger` لكل رحلة (سيرو). | +| E2 | **ربط الاتصال بالإلغاء** | اتصال ثم إلغاء = مؤشر اتفاق خارج التطبيق. **3 إلغاءات/يوم → إنذار**؛ التكرار → إجراء. | + +--- + +## المجموعة F — الدردشة +| F1 | إشعار الرسالة يُرسل **فقط** إذا لم تكن صفحة الدردشة مفتوحة (المعالجة الأساسية في فلاتر؛ الباك إند يرسل دائماً ويترك القرار للعميل أو عبر presence). | + +--- + +## مؤجَّل عمداً (قرار المالك) +المفاوض الذكي · تدرّج السائق · خصم العمولة — **آخر شيء** (جديدة حتى على سيرو). + +--- + +## ترتيب التنفيذ المقترح +1. **A** (الزمن الحقيقي + FCM + Redis + race) — الأعلى أثراً وأهم شكوى. +2. **B** (نموذج الرحلة: started/انتظار/فصل السعر/الطوابع/stops). +3. **C** (بيانات المركبة والسائق + ai_data). +4. **D** (تطبيع الهاتف + بصمة الجهاز + HMAC). +5. **E** (الاحتيال) ثم **F**.