feat: المجموعة E (كشف الاحتيال) + تشفير الهاتف at-rest
E — اتصال ثم إلغاء (من driver_ride_scam عند سيرو): - E1: driver_called_passenger + last_call_at/by/count على الرحلة نفسها لا Redis فقط — حقيقة دائمة تفيد التحقيق بعد انتهاء الرحلة وزوالها من الكاش. يُسجَّل عند call:offer (بدء المكالمة الفعلي) في RealtimeGateway عبر Repository<Trip> مباشرة — لا استيراد TripsModule كاملاً (يستورد RealtimeModule أصلاً، فدورة استيراد) - E2: FraudService.recordCallThenCancel — عدّاد يومي منفصل عن عدّاد الإلغاء العام بالساعة. 3/يوم = إنذار لا يمنع الإلغاء، 6/يوم = حظر مؤقت (طلب المالك حرفياً). يرتبط فقط إن كانت المكالمة خلال 30 دقيقة من الإلغاء تشفير الهاتف at-rest (ملاحظة المالك) — بفهرس أعمى منفصل، لا تشفير ساذج: - AES-256-GCM عشوائي IV يمنع WHERE phone = :x من المطابقة أصلاً (كل تشفير مختلف شكلاً حتى لنفس الرقم) — لو طُبِّق التشفير مباشرة بلا هذا لكسر تسجيل الدخول بالكامل بصمت - users.phone_bidx = HMAC-SHA256(الرقم المطبَّع) — حتمي، يصلح للبحث وللقيد الفريد. القيد انتقل من (tenant_id, phone) إلى (tenant_id, phone_bidx) — القديم كان سيقبل تكرار نفس الرقم الحقيقي فعلياً - findByPhone/create يحسبان البصمة؛ لا نقطة أخرى تقرأ phone بمساواة خام - هجرة EncryptPhone تُشفّر الصفوف القائمة فوراً وتبني البصمة بأثر رجعي — استثناء متعمَّد من تسامح decrypt() المعتاد (الهاتف عمود بحث يومي، خطره كنص صافٍ أعلى من name) - يعتمد على تطبيع D1: بصمة حتمية لنفس *النص*، فلا بد أن يصل الرقم مطبَّعاً قبلها وإلا عاد نفس الرقم بصيغتين ليصير رقمين مرة أخرى هجرات: TripCallSignal · EncryptPhone. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
1eb79fee99
commit
253fbb4b2a
@@ -76,12 +76,12 @@
|
||||
|
||||
---
|
||||
|
||||
## المجموعة E — كشف الاحتيال (من `driver_ride_scam`)
|
||||
## المجموعة E — كشف الاحتيال (من `driver_ride_scam`) — ✅ منفَّذة
|
||||
|
||||
| # | البند | التفصيل |
|
||||
|---|-------|---------|
|
||||
| E1 | **تسجيل زر الاتصال** | `isDriverCallPassenger` لكل رحلة (سيرو). |
|
||||
| E2 | **ربط الاتصال بالإلغاء** | اتصال ثم إلغاء = مؤشر اتفاق خارج التطبيق. **3 إلغاءات/يوم → إنذار**؛ التكرار → إجراء. |
|
||||
| # | البند | الحالة |
|
||||
|---|-------|--------|
|
||||
| E1 | **تسجيل زر الاتصال** | ✅ `driver_called_passenger` + `last_call_at`/`last_call_by`/`call_count` على الرحلة نفسها (لا Redis فقط — حقيقة دائمة تفيد التحقيق بعد انتهاء الرحلة). يُسجَّل عند `call:offer` في `RealtimeGateway` — لحظة **بدء** الاتصال الفعلية، لا `answer`/`ice`/`end` (إشارات تفاوض لاحقة لنفس المكالمة). |
|
||||
| E2 | **ربط الاتصال بالإلغاء** | ✅ `FraudService.recordCallThenCancel` — عدّاد **يومي منفصل** عن عدّاد الإلغاء العام (ذاك بالساعة ويعدّ كل إلغاء؛ هذا باليوم ويعدّ فقط الإلغاء **المسبوق باتصال خلال 30 دقيقة**). **3/يوم = إنذار (لا يمنع الإلغاء) — 6/يوم = حظر مؤقت**، طبق طلب المالك حرفياً. يُنادى من `TripsService.cancel` بقراءة خفيفة لعمود واحد قبل التحديث. |
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user