Update: 2026-08-08 12:58:16
This commit is contained in:
@@ -0,0 +1,271 @@
|
||||
# سيرو — سجلّ الإضافات وسياساتها
|
||||
|
||||
> **ما هذا الملف؟** شرحٌ بلغة غير تقنية لكل ميزة نضيفها: ما هي، لماذا أضفناها، كيف تعمل، وما قواعدها الرقمية.
|
||||
>
|
||||
> **لمن؟** للمالك ليتابع بلا قراءة كود، ولخدمة العملاء لتجيب السائق والراكب، ولعرضه على المستثمرين.
|
||||
>
|
||||
> **قاعدة التحديث:** كل ميزة جديدة تُضاف هنا فور إنجازها. الملف مرتّب من الأحدث إلى الأقدم.
|
||||
>
|
||||
> آخر تحديث: 2026-08-10 · المصدر: [دراسة الفرص](../04_features/SIRO_OPPORTUNITY_STUDY_AR.md)
|
||||
|
||||
---
|
||||
|
||||
# شاشة أرباح السائق (جديدة)
|
||||
|
||||
### ما هي
|
||||
شاشة واحدة تجيب السائق عن: كم كسبت اليوم؟ كم اقتُطع مني ولماذا؟ وكم أخذت من **كل رحلة** بالتفصيل؟
|
||||
|
||||
### لماذا أعدنا بناءها
|
||||
ثلاثة أسباب، أولها الأخطر:
|
||||
|
||||
**١) كان فشل الشبكة يظهر للسائق كـ«دخلك صفر».** عند تعذّر التحميل كان التطبيق يولّد سبعة أيام بأصفار ويعرضها كأنها أرباحه الحقيقية. السائق يرى دخل أسبوعه وقد تبخّر بسبب انقطاع إنترنت لحظي. لا يُقاس هذا بالجهد بل بالثقة.
|
||||
|
||||
**٢) الأرقام كانت لا تتفق.** شاشة الرصيد تُحدَّث فوراً، وشاشة الإحصائيات كانت مخزّنة **٣ ساعات** بلا أي إشارة إلى قِدَمها. السائق يفتح شاشتين فيجد رقمين مختلفين، فلا يثق بأيّهما.
|
||||
|
||||
**٣) لم يكن هناك تفصيل للرحلة.** السؤال الأول عند كل سائق في العالم — «لماذا أخذت هذا المبلغ من هذه الرحلة؟» — لم يكن له جواب في التطبيق. وهذا مصدر أغلب شكاوى «الحساب غلط».
|
||||
|
||||
### كيف تعمل الآن
|
||||
|
||||
شاشة **واحدة** اسمها «أرباحي» حلّت محل شاشتين منفصلتين (الأرباح والإحصائيات). الترتيب فيها مقصود: **المال أولاً، ثم التقدّم**.
|
||||
|
||||
| الترتيب | القسم |
|
||||
|---|---|
|
||||
| ١ | أرباح اليوم + تركيبة المبلغ |
|
||||
| ٢ | الاقتطاعات (تأمين، وقود) |
|
||||
| ٣ | آخر ٧ أيام — رسم بياني **يُنقر** لعرض رحلات أي يوم |
|
||||
| ٤ | هذا الشهر — الصافي، معدّل الساعة، معدّل اليوم |
|
||||
| ٥ | الرحلات بتفصيل كل واحدة |
|
||||
| ٦ | تقدّمي: هدف اليوم، المستوى، سلوك القيادة، الإنجازات |
|
||||
|
||||
كان التلعيب والمستويات في شاشة منفصلة تسبق الأرباح، فيمرّر السائق ثلاث شاشات ليصل إلى ما فتح التطبيق من أجله.
|
||||
|
||||
| كان | صار |
|
||||
|---|---|
|
||||
| شاشتان بأرقام لا تتفق | شاشة واحدة بمصدر واحد |
|
||||
| أربعة نداءات تصل في لحظات مختلفة | نداء واحد بختم زمني واحد |
|
||||
| فشل التحميل = أصفار | «تعذّر التحميل» + آخر رقم صادق معلَّم بوقته |
|
||||
| كاش ٣ ساعات صامت | دقيقتان، وأي رقم قديم يظهر بلافتة «هذه أرقام قبل كذا» |
|
||||
| يبدأ بتقرير شهري | يبدأ بـ**أرباح اليوم** |
|
||||
| الصافي فقط | دفع الراكب ← عمولة المنصة ← صافيك |
|
||||
| لا شيء عن الاقتطاعات | التأمين والوقود ظاهران بجانب الأرباح |
|
||||
|
||||
**تعريف مهم للجميع:** «أرباحي» ≠ «رصيدي». الأول عن العمل (الرحلات)، والثاني عن المال المتاح بعد الشحن والسحب والاقتطاعات. خلطهما هو ما أنتج الرقمين المتناقضين، وقد فُصلا الآن: الأرباح في شاشة الأرباح، والرصيد في شاشة المحفظة.
|
||||
|
||||
### قرارات منتج
|
||||
- **العمولة تُعرض صراحةً** لا تُطرح بصمت. من يرى التركيبة يفهم، ومن يرى الصافي وحده يخمّن ويشكّ.
|
||||
- **إعفاء العمولة ٠٪** صار مرئياً كوسم على الرحلة. كنا ندفع ثمن هذه الهدية ولا نحصد أثرها لأن السائق لا يراها.
|
||||
- **المقارنة بالذات لا بالآخرين**: «أعلى من أسبوعك الماضي بـ١٢٪». ترتيب السائقين يُحبط أكثر من يحتاج التحفيز — فهو من سيقع في أسفله.
|
||||
- **الاقتطاعات في شاشة الأرباح إلزامياً.** خصمٌ لا يظهر بجانب الأرباح التي اقتُطع منها يُقرأ سرقةً مهما كان مشروعاً. هذا شرط قبل تشغيل محفظة الوقود لا بعده.
|
||||
|
||||
### خطآن حسابيان صُحّحا
|
||||
- كانت الأرباح تُحسب على حالة `Finished` وحدها، والحالة مكتوبة في قاعدة البيانات بحرفين مختلفين تاريخياً — أي أن **نحو نصف رحلات السائق كان يسقط من أرباحه المعروضة**.
|
||||
- ساعات العمل كانت تُحسب بطريقة تجعل رحلة تبدأ ١١:٤٠ ليلاً وتنتهي ١٢:١٠ تُحسب بـ**سالب** ٢٣ ساعة ونصف، فتأكل ساعات يوم كامل.
|
||||
|
||||
### لخدمة العملاء
|
||||
|
||||
**«أرباحي اختفت / صارت صفراً»** — لم يعد ممكناً بعد هذا التحديث. إن ظهرت رسالة «تعذّر تحميل أرباحك» فهي مشكلة اتصال فقط، والشاشة تقول ذلك صراحةً: أرباحك محفوظة ولم يضع منها شيء.
|
||||
|
||||
**«الرقم في شاشة الأرباح غير الرقم في المحفظة»** — طبيعي ومقصود. الأرباح = ما كسبته من الرحلات. الرصيد = المتاح فعلاً بعد الشحن والسحب والاقتطاعات.
|
||||
|
||||
**«لماذا أخذت هذا المبلغ من الرحلة؟»** — يفتح السائق الرحلة في شاشة أرباحي فيرى: ما دفعه الراكب، المكافأة إن وُجدت، عمولة المنصة، ثم صافيه.
|
||||
|
||||
**«خُصم مني ولا أعرف لماذا»** — بطاقة «الاقتطاعات» في شاشة الأرباح تعرض كل التزام باسمه والمتبقي عليه.
|
||||
|
||||
---
|
||||
|
||||
# محور اقتصاد السائق
|
||||
|
||||
> **الفكرة الجامعة:** مشكلة السائق في أسواقنا ليست نسبة العمولة، بل **رأس المال**: الوقود يومياً، والصيانة فجأة، والسيارة نفسها. من يحلّ له هذه المشكلة يربطه بالمنصة لسنوات — وهذا أعمق خندق تنافسي متاح لنا.
|
||||
>
|
||||
> بنينا هذا المحور على ثلاث مراحل: محرك عام يدير أي التزام مالي على السائق، ثم بوابة تحمي المنصة من الإقراض بلا استرداد، ثم أول منتج فعلي فوقهما: محفظة الوقود.
|
||||
|
||||
---
|
||||
|
||||
## ١) محرك الالتزامات — الأساس المشترك
|
||||
|
||||
### ما هو
|
||||
نظام واحد يدير أي مبلغ مستحق على السائق للمنصة أو لشريك: قسط تأمين، دَين وقود، قسط صيانة، وقرض مركبة مستقبلاً.
|
||||
|
||||
### لماذا بنيناه
|
||||
كنا أمام خيارين: بناء نظام تحصيل منفصل لكل منتج، أو نظام واحد يخدمها جميعاً. اخترنا الثاني لسببين:
|
||||
|
||||
**الأول — سبب مباشر:** التأمين كان يسجّل الأقساط على السائقين منذ إطلاقه، **ولم يكن هناك ما يحصّلها**. الأقساط تتراكم على الورق فقط. اكتُشف هذا عند التخطيط لمحفظة الوقود.
|
||||
|
||||
**الثاني — سبب استراتيجي:** كل منتج مالي جديد كان سيحتاج نسخة من أخطر منطق في المنصة، وهو الذي يلمس مال السائق. أربع نسخ = أربعة أضعاف احتمال الخطأ.
|
||||
|
||||
### كيف يعمل — بثلاث خطوات
|
||||
1. **التسجيل:** المنتج يسجّل «على السائق كذا» (قسط اليوم، قيمة الوقود الذي أخذه).
|
||||
2. **الدفتر:** كل هذه المبالغ تدخل سجلاً واحداً دائماً، لا يُمحى منه شيء.
|
||||
3. **التحصيل:** برنامج واحد يعمل كل ليلة الساعة ١١:٣٠ مساءً، يمرّ على الدفتر ويخصم من أرباح السائق.
|
||||
|
||||
**نقطة مهمة:** لا يوجد في المنصة كلها إلا جهة واحدة تخصم من رصيد السائق. أي منتج جديد يسجّل مبلغاً فقط ولا يلمس المال.
|
||||
|
||||
### السياسات الرقمية
|
||||
|
||||
| القاعدة | القيمة | لماذا |
|
||||
|---|---|---|
|
||||
| سقف الخصم اليومي | نسبة من **أرباح اليوم** لا مبلغ ثابت | حتى لا يجد السائق محفظته صفراً في يوم ضعيف |
|
||||
| أرضية الرصيد | لا يُدفع السائق إلى السالب أبداً | الرصيد السالب يوقفه عن العمل، فيتعذّر السداد أصلاً |
|
||||
| المتبقي | يُرحَّل لليوم التالي، **لا يُسقَط** | الدَّين لا يضيع، لكنه لا يُجبى بالقوة |
|
||||
| ترتيب الأولوية | التأمين ← الوقود ← الصيانة | انقطاع التأمين يُفقد السائق تغطيته؛ تأخّر قسط صيانة يوماً لا يضرّ أحداً |
|
||||
| السقف مشترك | ثلاثة منتجات لا تأخذ ثلاثة أسقف | وإلا اقتُطع ٧٥٪ من يوم السائق |
|
||||
|
||||
### لخدمة العملاء
|
||||
|
||||
**«لماذا خُصم مني مبلغ اليوم؟»** — عليك التزام مسجّل (تأمين أو وقود). الخصم نسبة من أرباح اليوم لا مبلغ ثابت. التفاصيل كاملة في شاشة المنتج داخل التطبيق.
|
||||
|
||||
**«خُصم مني أقل من قيمة القسط»** — هذا مقصود. النظام لا يأخذ أكثر من النسبة المسموحة من دخل اليوم. الباقي يُلاحَق غداً بلا أي غرامة تأخير.
|
||||
|
||||
**«لم يُخصم مني شيء اليوم»** — لم تدخل أرباح إلى محفظتك اليوم، أو دخلت بمبلغ صغير. لا شيء مطلوب من السائق.
|
||||
|
||||
**«ألغيت اشتراكي، هل يسقط ما عليّ؟»** — لا. الإلغاء يوقف الأقساط **القادمة** ولا يمسّ الماضي. أيام التغطية التي استفاد منها السائق مستحقة.
|
||||
|
||||
---
|
||||
|
||||
## ٢) بوابة الائتمان — من يستحق أن نموّله
|
||||
|
||||
### ما هي
|
||||
شرط إضافي قبل منح السائق أي التزام مالي: **يجب أن تمرّ أرباحه بمحفظة سيرو**.
|
||||
|
||||
### لماذا أضفناها
|
||||
سقف الخصم نسبة من الأرباح المارّة بالمحفظة. سائق يحصّل نقداً ولا يمرّ ماله بالمحفظة يظهر بأرباح صفر كل يوم — فلا يُخصم منه شيء **أبداً**.
|
||||
|
||||
هذا محتمَل في التأمين (قسط صغير، خسارة محدودة). وهو غير محتمَل في الوقود: هناك نسلّم السائق قيمةً فعلية في خزّان سيارته مقابل وعد بالسداد من قناة لا يمرّ بها ماله. **هذه هبة لا ائتمان.**
|
||||
|
||||
### كيف تعمل
|
||||
قبل تفعيل أي منتج، يقيس النظام كم **يوماً** دخل فيه مالٌ إلى محفظة السائق خلال آخر ٣٠ يوماً.
|
||||
|
||||
**المقياس أيام لا مبلغ** — والسبب أن السؤال ليس «كم يكسب؟» بل «هل قناة التحصيل تعمل؟». دخل واحد كبير قد يكون استرداداً أو تسوية حادثة؛ اثنا عشر يوماً متفرّقاً يعني قناة حيّة.
|
||||
|
||||
### السياسات الرقمية
|
||||
|
||||
| المنتج | أيام الدخل المطلوبة (من ٣٠) | لماذا هذه العتبة |
|
||||
|---|---|---|
|
||||
| التأمين | ٨ أيام | مشروط أصلاً بـ٢٠٠ رحلة وتقييم ٤.٥ — التشديد فوقها يفرغه من غرضه |
|
||||
| محفظة الوقود | ١٢ يوماً | قيمة فعلية تُسلَّم، والاسترداد الوحيد من أرباح تمرّ بالمحفظة |
|
||||
|
||||
**قواعد إضافية:**
|
||||
- تعذّر التحقق = **رفض** لا قبول. تأجيل منح ائتمان أهون من منحه لمن لا يُسترد منه.
|
||||
- الشرط على الاشتراكات **الجديدة** فقط. لا يُسحب التزام قائم من سائق بسبب شرط سُنّ بعده.
|
||||
- العتبات قابلة للتغيير بتعديل رقم في قاعدة البيانات، بلا إصدار جديد من التطبيق.
|
||||
|
||||
### لخدمة العملاء
|
||||
|
||||
**«لماذا رُفض طلبي رغم أن رحلاتي كافية؟»** — الشرط ليس عدد الرحلات وحده، بل أن تمرّ الأرباح بالمحفظة. الرسالة في التطبيق تذكر العدد الحالي والمطلوب بالضبط.
|
||||
|
||||
**«كيف أستوفي الشرط؟»** — بالعمل عبر المحفظة بدل النقد. الشرط يُعاد قياسه تلقائياً كل مرة، فلا حاجة لطلب مراجعة.
|
||||
|
||||
**«رُفض طلبي برسالة تعذّر التحقق»** — عطل مؤقت. يُعاد المحاولة بعد قليل. ليس رفضاً نهائياً.
|
||||
|
||||
---
|
||||
|
||||
## ٣) محفظة الوقود — أول منتج فعلي
|
||||
|
||||
### ما هي
|
||||
السائق يتزوّد وقوداً من محطة شريكة **بلا نقد**، والقيمة تُقيَّد ديناً عليه يُخصم من أرباحه تدريجياً.
|
||||
|
||||
### لماذا
|
||||
الوقود هو مشكلة السائق اليومية الأولى، ونقص السيولة صباحاً يمنعه من العمل. حلّ هذه المشكلة أثره أقوى من أي زيادة في نسبته — لأننا نعالج **توقيت** المال لا مقداره. وهو أيضاً ما يجعل مغادرته إلى منافس قراراً مكلفاً.
|
||||
|
||||
### كيف تعمل — دورة كاملة
|
||||
1. السائق يفعّل المحفظة مرة واحدة (بشرط الأهلية وبوابة الائتمان).
|
||||
2. عند الحاجة، يطلب من التطبيق قسيمة بمبلغ محدّد.
|
||||
3. يحصل على **رمز من ١٠ أرقام** صالح ٤٥ دقيقة.
|
||||
4. يعطي الرمز لعامل المحطة، والمحطة تؤكّد المبلغ المصروف فعلاً.
|
||||
5. عند التأكيد — **وليس قبله** — يُسجَّل الدَّين على السائق.
|
||||
6. محرك التسوية يحصّله ليلاً بنسبة ١٥٪ من أرباح اليوم.
|
||||
7. كلما سدّد، عاد سقفه متاحاً — كبطاقة ائتمان متجدّدة.
|
||||
|
||||
**لماذا قسيمة مسبقة لا خصم عند المضخة؟** لأن عامل المحطة لا يملك وسيلة للتحقق من هوية السائق ولا من سقفه. القسيمة تنقل القرار إلى التطبيق حيث الهوية مؤكَّدة والسقف معلوم، ولا يبقى على المحطة إلا تأكيد رقم.
|
||||
|
||||
### السياسات الرقمية
|
||||
|
||||
| القاعدة | القيمة | لماذا |
|
||||
|---|---|---|
|
||||
| السقف المبدئي | ٣٠ (بعملة البلد) | موحّد للجميع مبدئياً؛ التدرّج بحسب السداد قرار لاحق يحتاج بيانات |
|
||||
| نسبة الخصم اليومي | ١٥٪ من أرباح اليوم | أقل من التأمين (٢٥٪) لأن دَين الوقود أكبر، وخنق السائق يعيده محتاجاً للدَّين |
|
||||
| صلاحية القسيمة | ٤٥ دقيقة | القسيمة تحجز من السقف؛ المفتوحة إلى الأبد تمنع صاحبها من التزوّد |
|
||||
| قسائم مفتوحة | واحدة فقط في كل وقت | رمزان في يد السائق = صرف المبلغ الخطأ |
|
||||
| المبلغ المصروف | لا يتجاوز المأذون | تجاوزه دَين لم يوافق عليه السائق |
|
||||
| المصروف أقل من المأذون | مسموح وطبيعي | يطلب ٢٠ ويتزوّد بـ١٥ — الدَّين على ١٥ |
|
||||
|
||||
**حماية الأموال المدمجة:**
|
||||
- كل محطة لها مفتاح خاص مخزَّن مشفَّراً. تسريب مفتاح محطة يكشف تلك المحطة وحدها ويُبطَل فوراً.
|
||||
- صرف القسيمة مرة واحدة قطعاً. الضغط المكرّر على جهاز المحطة أو محاولة صرف مزدوج لا تُنتج ديناً مضاعفاً.
|
||||
- السائق لا يستطيع تأكيد الصرف بنفسه — هو الطرف المستفيد، وتأكيده يعني أن ينفي ما استلمه.
|
||||
|
||||
### لخدمة العملاء
|
||||
|
||||
**«الرمز لا يعمل عند المحطة»** — تحقّق من ثلاثة: هل مضت ٤٥ دقيقة؟ هل صُرف سابقاً؟ هل المحطة ضمن الشبكة الشريكة؟ رسالة جهاز المحطة تحدّد السبب بالضبط.
|
||||
|
||||
**«ألغيت القسيمة، متى يعود سقفي؟»** — فوراً.
|
||||
|
||||
**«سقفي المتاح أقل من ٣٠ رغم أني لم أستخدم شيئاً»** — إمّا عليك دَين سابق لم يُسدَّد بالكامل، أو لديك قسيمة سارية تحجز مبلغاً. الشاشة تعرض الأربعة أرقام منفصلة: السقف، المستحق، المحجوز، المتاح.
|
||||
|
||||
**«صُرف مبلغ أقل مما طلبت»** — طبيعي. الدَّين على ما صُرف فعلاً لا ما طُلب.
|
||||
|
||||
**«لماذا سقف الوقود ١٥٪ والتأمين ٢٥٪؟»** — دَين الوقود أكبر من قسط يومي. اقتطاع ربع الدخل لسداده يترك السائق بلا ما يكفي ليعمل غداً، فيعود محتاجاً وقوداً بالدَّين — وتلك حلقة لا تُغلق.
|
||||
|
||||
---
|
||||
|
||||
## ٤) التأمين على السائق (سابق — أُعيد ربطه)
|
||||
|
||||
### ما هو
|
||||
تغطية تأمينية من شريك مرخّص، بقسط يومي أو شهري يُخصم من أرباح السائق.
|
||||
|
||||
### الحالة
|
||||
كان مبنياً وتُسجَّل أقساطه، **بلا أي تحصيل**. بعد بناء محرك الالتزامات صار يعمل ضمنه بالكامل: الأقساط المتراكمة سابقاً صارت قابلة للتحصيل، والاشتراكات الجديدة تدخل النظام تلقائياً.
|
||||
|
||||
### السياسات الرقمية
|
||||
|
||||
| القاعدة | القيمة |
|
||||
|---|---|
|
||||
| الحد الأدنى للرحلات المكتملة | ٢٠٠ |
|
||||
| الحد الأدنى للتقييم | ٤.٥ |
|
||||
| الحد الأدنى لعمر الحساب | ٣٠ يوماً |
|
||||
| أيام الدخل بالمحفظة | ٨ من ٣٠ |
|
||||
| نسبة الخصم اليومي | ٢٥٪ من أرباح اليوم |
|
||||
| وثيقة نشطة لكل سائق | واحدة |
|
||||
|
||||
**قرار المنتج:** التأمين ليس خدمة تُمنح لكل من سجّل، بل **مكافأة استمرار**. منحه لمن قد يختفي بعد أسبوع يحوّله من أداة ولاء إلى نزيف. والشروط معروضة في التطبيق لمن لم يستوفها بعد — مع تقدّمه نحوها — لأن الشرط الظاهر هدفٌ يُسعى إليه، والمخفي مجرد رفض.
|
||||
|
||||
### لخدمة العملاء
|
||||
|
||||
**«تبديل الخطة»** — لا يتم بصمت. إلغاء صريح ثم اشتراك جديد، ليبقى في السجل أثر لكل تغيير مالي.
|
||||
|
||||
**«ألغيت وثيقتي وبقي عليّ مبلغ»** — نعم، أقساط أيام التغطية التي مضت. الإلغاء لا يمحو الماضي.
|
||||
|
||||
---
|
||||
|
||||
# ما قبل هذا المحور
|
||||
|
||||
بنود أخرى من دراسة الفرص أُنجزت أو بدأت قبل هذا العمل، ولم تُوثَّق هنا بعد بالتفصيل نفسه:
|
||||
|
||||
- **الحجز المسبق** — يعمل
|
||||
- **الطلب عبر SMS** (للمناطق بلا إنترنت) — البنية قائمة
|
||||
- **محرك الإسناد بالدفعات** — مبني ويمكن تشغيله بمفتاح إعداد
|
||||
- **تعويض السائق عن عدم حضور الراكب** — يعمل
|
||||
- **زر السلامة (SOS)** — مبني، وتنقصه غرفة عمليات تستقبله
|
||||
- **مواصلاتي (النقل الجامعي والمؤسسي)** — الكود شبه مكتمل، وفيه ثغرات معروفة
|
||||
|
||||
*تُوثَّق تباعاً بالتنسيق نفسه.*
|
||||
|
||||
---
|
||||
|
||||
# لم يُنجز بعد من دراسة الفرص
|
||||
|
||||
سيرو للأعمال · الطرود والمشاوير · اشتراك الراكب · إغلاق التسرّب خارج المنصة · طبقة المعالم الشعبية · الصيانة بالتقسيط · تمويل المركبات
|
||||
|
||||
**تنبيه قائم:** أي تمويل حقيقي يمرّ عبر شريك مرخّص، لا من ميزانية سيرو مباشرة — هذا الخط يقترب من التمويل المنظَّم قانونياً.
|
||||
|
||||
---
|
||||
|
||||
# ملاحظات للعرض على المستثمرين
|
||||
|
||||
**ما يميّز هذا المحور:** المنافسون يتنافسون على نسبة العمولة — وهي حرب أسعار تنتهي بخسارة الجميع. نحن نعالج **رأس مال السائق** ومشكلة توقيت السيولة، وهي مشكلة لا يحلّها خفض العمولة إطلاقاً.
|
||||
|
||||
**الأصل الحقيقي المتكوّن:** بيانات دخل السائق المؤكَّدة والمارّة بمحفظتنا. هي التي تجعلنا أقدر من أي بنك على تقييم جدارته الائتمانية — وهي المنتج الذي يُعرض على شريك التمويل لاحقاً. القرض ليس الهدف؛ البيانات هي.
|
||||
|
||||
**الأثر على البقاء:** السائق الذي يعتمد على محفظة الوقود يومياً ينتقل من «مورّد» إلى «شريك بحساب مفتوح». مغادرته لمنافس تعني تسوية حساب، لا مجرد حذف تطبيق.
|
||||
|
||||
**صدقٌ في العرض:** المحفظة أُطلقت بمنتج واحد (الوقود) وسقف محافظ (٣٠)، لأن التوسّع في الائتمان قبل رؤية سلوك السداد الفعلي مخاطرة لا داعي لها. التوسّع قرار بيانات لا طموح.
|
||||
@@ -0,0 +1,178 @@
|
||||
# محرك الالتزامات العام — تصميم وتنفيذ
|
||||
|
||||
> بند 3.4 من [دراسة الفرص](SIRO_OPPORTUNITY_STUDY_AR.md) — اقتصاد السائق: الوقود، الصيانة، والتمويل.
|
||||
> تاريخ التنفيذ: 2026-08-08. الحالة: الخطوتان ١ و٢ منفَّذتان (الجداول + التسوية).
|
||||
|
||||
---
|
||||
|
||||
## لماذا الآن — ثغرة قائمة لا تحسين مستقبلي
|
||||
|
||||
`cron_insurance_premiums.php` يقيّد أقساط التأمين منذ إطلاقه، وتعليقه يقول إن الدفتر «تقرأه التسوية». **لم تكن التسوية موجودة.** لا مرجع واحد لجدول `insurance_premium_ledger` في المشروع كله خارج الكرون والـmigration.
|
||||
|
||||
النتيجة العملية: كل قسط تأمين قُيّد حتى اليوم بقي بحالة `pending`، ولم يُحصَّل منه شيء.
|
||||
|
||||
الخيار كان: كتابة تسوية خاصة بالتأمين، أو تعميم النموذج مرة واحدة. والوقود والصيانة والتمويل — البنود الثلاثة التالية في اقتصاد السائق — كلها نفس الشكل: التزام دوري أو مقسّط يُخصم من أرباح السائق. كتابة تسوية لكل منها تعني أربع نسخ من أخطر منطق في المنصة: الذي يلمس مال السائق.
|
||||
|
||||
---
|
||||
|
||||
## البنية
|
||||
|
||||
فصل ثلاث مسؤوليات كان الكود يخلطها:
|
||||
|
||||
| المسؤولية | الملف | ماذا يفعل |
|
||||
|---|---|---|
|
||||
| مُصدِر الاستحقاق | `bot/cron_insurance_premiums.php` وما يليه | يقيّد «على السائق كذا». لا يلمس مالاً |
|
||||
| الدفتر الموحّد | `obligation_ledger` | سجل دائم واحد مهما كان المصدر |
|
||||
| محرك التسوية | `bot/cron_obligation_settlement.php` | **الجهة الوحيدة** التي تخصم من الرصيد |
|
||||
|
||||
منتج جديد = صفّ في `obligation_products` + مُصدِر استحقاق صغير. لا يلمس التسوية ولا الرصيد إطلاقاً.
|
||||
|
||||
### الجداول
|
||||
|
||||
| الجديد | يعمّم |
|
||||
|---|---|
|
||||
| `obligation_products` | `insurance_plans` |
|
||||
| `driver_obligations` | `driver_insurance_policies` |
|
||||
| `obligation_ledger` | `insurance_premium_ledger` |
|
||||
| `obligation_settlements` (قاعدة المحفظة) | — جديد كلياً |
|
||||
|
||||
ثلاثة فروق جوهرية عن نموذج التأمين:
|
||||
|
||||
**`kind`** يحدّد سلوك الاستحقاق: `recurring` يتكرّر بلا نهاية (تأمين)، `installment` له أصل ينتهي بسداده (صيانة، تمويل)، `drawdown` يُقيَّد عند السحب لا على جدول (وقود).
|
||||
|
||||
**`amount_collected` / `amount_remaining`** في الدفتر. القسط يُدفع كاملاً أو لا يُدفع، أما الوقود والصيانة فتحصيلهما جزئي بطبعه: قيدٌ بقيمة عشرة قد يُحصَّل على ثلاثة أيام. بلا هذين العمودين لا يمكن تمثيل ذلك إلا بتفتيت القيد، فيضيع أثر الاستحقاق الأصلي.
|
||||
|
||||
**`priority`** لترتيب المزاحمة: التأمين (١٠) قبل الوقود (٢٠) قبل الصيانة (٣٠). انقطاع التأمين يُلغي وثيقة ويفقد السائق تغطيته؛ تأخّر قسط صيانة يوماً لا يكلّف أحداً شيئاً.
|
||||
|
||||
---
|
||||
|
||||
## سقف الخصم اليومي — القرار الذي يقرّر نجاح الميزة
|
||||
|
||||
الخصم نسبة من **أرباح اليوم** لا مبلغ ثابت، بسقف على مستوى المنتج (`daily_cap_percent`، افتراضي ٢٥٪) وأرضية للرصيد (`OBLIGATION_MIN_BALANCE`، افتراضي صفر).
|
||||
|
||||
السبب: سائق عليه قسط تأمين وقرض صيانة في يوم ضعيف سيفتح التطبيق ويجد صفراً — ويهجر المنصة. المتبقي يُرحَّل، لا يُسقَط.
|
||||
|
||||
الأساس هو دخل اليوم لا الرصيد المتراكم: الخصم من رصيد قديم يفاجئ سائقاً لم يعمل اليوم، والخصم من دخل حاضر يبقى محسوساً كاقتطاع من كسبٍ وقع للتوّ.
|
||||
|
||||
**السقف مشترك بين المنتجات:** نقطة الخصم تطرح ما اقتُطع اليوم من كل المنتجات قبل حساب المتاح. بدون هذا الطرح تصير ثلاثة منتجات بسقف ٢٥٪ تأخذ ٧٥٪ من يوم السائق.
|
||||
|
||||
---
|
||||
|
||||
## بوابة الائتمان — لا التزام إلا لمن تمرّ أرباحه بالمحفظة
|
||||
|
||||
قرار المالك (2026-08-09). سببه المباشر أن سقف الخصم نسبة من الدخل المارّ بالمحفظة: **سائق الكاش الذي يحصّل نقداً سقفه صفر كل يوم، فلا يُحصَّل منه شيء أبداً.** منحه وقوداً أو صيانة بالدَّين تسليمُ قيمةٍ فعلية مقابل قناة سداد لا وجود لها — أي هبة لا ائتمان.
|
||||
|
||||
الشرط مخزَّن مع المنتج (`requires_wallet_income`, `min_wallet_days_30d`, `min_wallet_income_30d`) على غرار شروط الرحلات والتقييم القائمة، لأن العتبة تختلف بطبيعة المنتج.
|
||||
|
||||
**المقياس أيام لا مبلغ.** السؤال ليس «كم يكسب؟» بل «هل قناة التحصيل تعمل؟». دخل واحد كبير قد يكون استرداداً أو تسوية حادثة؛ اثنا عشر يوماً متفرّقاً قناةٌ حيّة.
|
||||
|
||||
**الفشل مغلق.** تعذُّر الوصول إلى سيرفر المحفظة يعني رفضاً لا قبولاً. عطلٌ شبكي عابر يؤجّل منح ائتمان، بينما القبول عند الشك يمنحه لمن قد لا يُسترد منه — والخطأ الثاني وحده يكلّف مالاً.
|
||||
|
||||
**الفحص في طبقتين.** نقطة الاستدعاء تفحص لتعرض للسائق سبباً مفهوماً وما ينقصه؛ و`obligationOpen` تفحص ثانيةً عند الكتابة كحارس أخير. النقطة قد تنسى، أو يُضاف منتج جديد بمسار جديد يُغفلها — والفحص عند الكتابة وحده هو الذي لا يمكن الالتفاف عليه بالسهو.
|
||||
|
||||
**التأمين يخضع للبوابة بعتبة متساهلة** (ثمانية أيام، بلا شرط مبلغ): القسط الذي تتحمّله الشركة ثم تسترده ائتمانٌ بالمعنى نفسه، لكن التأمين مشروط أصلاً بمئتي رحلة وتقييم جيد، وتشديد بوابة ثانية فوقها يفرغ المنتج من غرضه. تغيير العتبة صفٌّ واحد في `obligation_products`.
|
||||
|
||||
الشرط يمسّ الاشتراكات **الجديدة** وحدها. الالتزامات القائمة لا تُفحص ثانيةً: سحب تغطية من سائق مؤمَّن اليوم بسبب شرط سُنّ اليوم عقوبة بأثر رجعي.
|
||||
|
||||
---
|
||||
|
||||
## الحد بين الخادمين
|
||||
|
||||
الرصيد في `payment_server`، القيد في القاعدة الرئيسية. لا كتابة عابرة للحدود.
|
||||
|
||||
### لماذا نقطة خصم جديدة بدل `add_s2s_reward.php` بمبلغ سالب
|
||||
|
||||
**`add_s2s_reward.php` لا يضمن عدم التكرار.** لا مفتاح فريد على `driverWallet.paymentID`، ولا فحص تكرار فيها إلا لتحديات `daily_/weekly_`. تعليق `food/admin/courier_settlement.php` يقول إن `paymentID` «يمنع ازدواج الصرف عند إعادة المحاولة» — وهذا غير صحيح، لا شيء يفرضه.
|
||||
|
||||
هذا مقبول تقريباً للإيداعات (إيداع مكرّر يُسترد)، وغير مقبول إطلاقاً للخصومات: محرك التسوية يعيد المحاولة بطبعه.
|
||||
|
||||
ولا يمكن ببساطة إضافة مفتاح فريد على `driverWallet.paymentID`: الجدول يحمل سنوات من صفوف قد تحمل معرّفات مكرّرة أصلاً. فالضمان بُني خارجه، في `obligation_settlements`.
|
||||
|
||||
### المرجع مبنيّ على عدّاد المحاولات لا على التاريخ
|
||||
|
||||
`settlement_ref = obl_{ledgerId}_{attempts}`
|
||||
|
||||
`attempts` لا يزيد إلا بعد تحديث الدفتر بنجاح. فنداء نجح في المحفظة وضاع ردّه في الطريق يُعاد لاحقاً — ولو بعد أيام — بالمرجع نفسه، فتُرجع المحفظة خصمه الأول بدل تنفيذ خصم ثانٍ.
|
||||
|
||||
مرجعٌ مبنيّ على التاريخ (`obl_{id}_{YYYYMMDD}`، وهو ما كُتب أولاً) كان سيصل في اليوم التالي بمرجع جديد ويخصم المبلغ مرتين في هذه الحالة بالضبط.
|
||||
|
||||
---
|
||||
|
||||
## التوقيت
|
||||
|
||||
| الوقت | المهمة |
|
||||
|---|---|
|
||||
| 00:15 | مُصدِر الاستحقاق — يقيّد أقساط اليوم |
|
||||
| 23:30 | محرك التسوية — يحصّل من أرباح اليوم |
|
||||
|
||||
التسوية **لا** تعمل بعد المُصدِر مباشرة. السقف نسبة من أرباح اليوم، وتشغيلها الساعة 00:45 يعني قراءة يومٍ عمره خمس وأربعون دقيقة: أرباحه صفر، فالسقف صفر، فلا يُخصم شيء أبداً. كان المحرك سيعمل كل ليلة بلا خطأ واحد وبلا تحصيل قرش.
|
||||
|
||||
23:30 تقرأ يوم عمل مكتملاً تقريباً. النصف ساعة المتبقية ليست ضياعاً: ما لم يُحصَّل يبقى في الدفتر ويُلاحَق غداً.
|
||||
|
||||
**لا خصم داخل `finish_ride_updates.php`.** المسار حرج والسائق ينتظر ردّه؛ نداء شبكي إلى سيرفر المحفظة داخله يعني تعليق شاشته على بطء طرف ثالث، وفشلاً في التسوية يظهر له كفشل في إنهاء رحلته.
|
||||
|
||||
---
|
||||
|
||||
## ما نُفِّذ
|
||||
|
||||
| الملف | الدور |
|
||||
|---|---|
|
||||
| `backend/migrations/2026_08_08_obligations_engine.sql` | الجداول الثلاثة + ترحيل التأمين |
|
||||
| `backend/migrations/2026_08_09_obligation_credit_gate.sql` | أعمدة بوابة الائتمان |
|
||||
| `payment_server/v2/main/ride/driverWallet/income_summary_s2s.php` | ملخّص الدخل المارّ بالمحفظة |
|
||||
| `payment_server/migrations/2026_08_08_obligation_settlements.sql` | سجل الخصومات (ضمان عدم التكرار) |
|
||||
| `payment_server/v2/main/ride/driverWallet/deduct_s2s_obligation.php` | نقطة الخصم — سقف + عدم تكرار |
|
||||
| `backend/bot/cron_obligation_settlement.php` | محرك التسوية |
|
||||
| `backend/obligations/functions.php` | فتح/إغلاق التزام وقراءة المستحق |
|
||||
| `backend/bot/cron_insurance_premiums.php` | صار مُصدِر استحقاق عاماً |
|
||||
| `backend/driver_assurance/{subscribe,cancel,get,plans}.php` | ربط بالدفتر الموحّد + بوابة الائتمان |
|
||||
| `docker/crontab.production` | جدولة التسوية |
|
||||
|
||||
### الترحيل
|
||||
|
||||
جداول التأمين **تبقى كما هي** — لا تُحذف ولا تُعدَّل، وتصير شاهداً تاريخياً. بياناتها تُنقل إلى النموذج العام، والقيود المعلّقة (وهي مال حقيقي تراكم بلا تحصيل) تصير مرئية لمحرك التسوية.
|
||||
|
||||
القيود القديمة بحالة `failed` تعود `pending`: الفشل السابق لم يكن قراراً بل غياب محرك، وحجبها الآن يعني إسقاط مال مستحق فعلاً.
|
||||
|
||||
قسم الترحيل يعمل أكثر من مرة بلا ضرر — كل إدراج مشروط بعدم وجود ما يقابله.
|
||||
|
||||
**لماذا لم يكفِ الترحيل وحده:** `driver_assurance/subscribe.php` كان يكتب في جداوله الخاصة فقط. بقاؤه كذلك كان يعني أن كل اشتراك **جديد** لا يظهر في الدفتر الموحّد — أي لا يُقيَّد له قسط ولا يُحصَّل منه شيء. الترحيل يعالج الماضي؛ ربط `subscribe/cancel` يمنع تكرار الثغرة مستقبلاً.
|
||||
|
||||
---
|
||||
|
||||
## حدود معروفة — تُحسم قبل الخطوة ٤
|
||||
|
||||
**سائق الكاش محجوب لا محصَّل منه.** بوابة الائتمان تمنع منحه التزاماً أصلاً، وهذا هو القرار المتّخذ. لكنها تعالج الدخول لا الخروج: سائق كان دخله يمرّ بالمحفظة ثم تحوّل إلى الكاش بعد فتح التزامه يبقى التزامه قائماً بسقف صفر — يتراكم في الدفتر بلا تحصيل. لا يوجد بعد ما يرصد هذا التحوّل أو ينبّه عليه.
|
||||
|
||||
**تعارض قيد وحساب.** لو خُصم من المحفظة ولم يُحدَّث الدفتر (فشل قاعدة بيانات بعد نجاح النداء)، يُسجَّل السطر في `error_log` بصيغة صريحة ولا تُعاد المحاولة تلقائياً. المرجع الثابت يمنع الخصم المزدوج، لكن التباين بين الدفترين يحتاج عيناً بشرية. لا توجد بعد لوحة تعرض هذه الحالات.
|
||||
|
||||
**لم يُختبر مقابل قاعدة بيانات.** كل ملفات PHP اجتازت `php -l`، أما الـmigrations فلم تُنفَّذ — لا MySQL ولا Docker على جهاز التطوير هذا. يجب تشغيلها على بيئة اختبار قبل الإنتاج.
|
||||
|
||||
---
|
||||
|
||||
## محفظة الوقود (الخطوة ٣ — منفَّذة)
|
||||
|
||||
أول منتج من نوع `drawdown`: لا دورة فوترة، والاستحقاق يُقيَّد لحظة الصرف من المحطة.
|
||||
|
||||
| الملف | الدور |
|
||||
|---|---|
|
||||
| `backend/migrations/2026_08_10_fuel_wallet.sql` | `source_ref` + `credit_limit` + المحطات + القسائم + المنتج |
|
||||
| `backend/fuel/functions.php` | حساب السقف وتوليد الرموز |
|
||||
| `backend/fuel/{enroll,get,stations,request_voucher,cancel_voucher}.php` | مسار السائق |
|
||||
| `backend/fuel/redeem.php` | مُصدِر الاستحقاق — تأكيد المحطة |
|
||||
|
||||
**تعديل على المخطّط اقتضاه المنتج:** المفتاح الفريد `(obligation_id, charge_date)` كان يمنع قيدين لالتزام واحد في يوم واحد — وهو المطلوب للتأمين، وكاسرٌ للوقود: سائق يتزوّد مرتين في يوم يُرفض قيده الثاني فيحصل على وقود بلا دَين. أُضيف `source_ref` إلى المفتاح، فارغاً للمنتجات الدورية (فيبقى ضمانها حرفياً) ومملوءاً برقم القسيمة للوقود. سلسلة فارغة لا `NULL`: MySQL يعتبر كل `NULL` مختلفاً، فعمود قابل للتفريغ كان سيلغي الحماية عن التأمين بصمت.
|
||||
|
||||
**`credit_limit` لا `principal_amount`:** الأصل ينفد بالسداد (قرض صيانة)، وسقف الوقود متجدّد — يُسدَّد فيعود متاحاً.
|
||||
|
||||
**السقف المتاح** = `credit_limit` − الدَّين القائم − القسائم السارية. حجز القسائم يُطرح كالدَّين تماماً: قسيمة قد تُصرف بعد لحظة، والسماح بإصدار قسائم تتجاوز السقف يعني سائقاً يتزوّد بضعف ما يستحق.
|
||||
|
||||
---
|
||||
|
||||
## الخطوات التالية
|
||||
|
||||
4. الصيانة بالتقسيط (`installment`) — المحرك يدعمها بالكامل، ينقصها منتج ومسار ورشة
|
||||
5. مؤشر الجدارة الائتمانية — قراءة فقط، بلا التزام مالي، تمهيداً لشريك التمويل
|
||||
6. رصد تحوّل السائق من المحفظة إلى الكاش بعد فتح التزامه (انظر الحدود المعروفة)
|
||||
|
||||
تحذير الدراسة قائم: أي تمويل حقيقي يمرّ عبر شريك مرخّص، لا من ميزانية سيرو.
|
||||
Reference in New Issue
Block a user