/// إعداد وقت التشغيل — يُمرَّر بـ`--dart-define` عند البناء (docs/23 §1). /// /// ما يخصّ **هوية المستأجر البصرية** (لون · لوغو · اسم) يعيش في /// `build_config.dart` المُولَّد، لا هنا. class AppConfig { const AppConfig._(); /// أصل الـAPI **مع** `/api` (docs/38). static const String apiBaseUrl = String.fromEnvironment( 'API_BASE_URL', defaultValue: 'https://tripz-api.intaleqapp.com/api', ); /// أصل الـWebSocket — بلا `/api` (docs/38 §9). static const String wsBaseUrl = String.fromEnvironment( 'WS_BASE_URL', defaultValue: 'https://tripz-api.intaleqapp.com', ); /// يحدّد هوية المستخدم على الخادم: نفس الرقم بدورين = حسابان منفصلان /// (docs/38 §1). **يُثبَّت عند البناء ولا يتغيّر في وقت التشغيل أبداً.** static const String appRole = 'driver'; // ── الخرائط ────────────────────────────────────────────────────────── // قرار المالك 2026-07-20: كل الخرائط — البلاطات والجيوكودنغ والمسار — // **مباشرة** إلى map-saas بلا مرور بباك إند تريبز. map-saas مِلك المالك، // والمفتاح يُقيَّد ببصمة التطبيق (نفس نموذج Google Maps SDK). هذا يُلغي // نقاط `/maps/*` في باك إند تريبز، وهو ما حسم التعارض المسجّل في // docs/38 §7 — ومنها `/maps/geocode` المعطوب على الخادم المنشور. static const String mapBaseUrl = String.fromEnvironment( 'MAP_BASE_URL', defaultValue: 'https://map-saas.intaleqapp.com/api', ); /// المفتاح ترويسة **`x-api-key`** لا معامل استعلام — map-saas يرفض /// المفتاح في الـquery بـ400. الحالي مفتاح سيرو حتى يُصدر المالك مفتاح /// تريبز المقيّد بالبصمة. static const String mapApiKey = String.fromEnvironment( 'MAP_API_KEY', defaultValue: 'in_9478b32836d19cff73db3063', ); /// كل كم متر يُرفع موقع السائق. أقل من ذلك يستنزف البطارية بلا فائدة. static const int locationFilterMeters = 25; /// مهلة البحث عن سائق قبل عرض «لا يوجد سائقون». /// /// **إلزامية**: الخادم قد لا يُطلق `expired`/`no_drivers` أبداً (ثغرة R1، /// docs/38 §4)، فانتظار حدثٍ قد لا يصل يعني شاشة بحث أبدية. static const Duration searchingTimeout = Duration(seconds: 90); /// طول رمز التحقّق كما يولّده الخادم (docs/38 §2). static const int otpLength = 4; /// مهلة إعادة إرسال الرمز. الخادم يحدّ `send-otp` بثلاثة طلبات كل خمس /// دقائق، فبلا عدّاد تنازلي يُحظر المستخدم بثلاث ضغطات (docs/39 §2). static const Duration otpResendCooldown = Duration(seconds: 60); /// هامش التجديد الاستباقي. عمر التوكن 15 دقيقة فقط (docs/38 §2)، /// فالانتظار حتى 401 يعني فشل طلب في منتصف رحلة. static const Duration tokenRefreshLeeway = Duration(seconds: 60); static const Duration connectTimeout = Duration(seconds: 20); static const Duration receiveTimeout = Duration(seconds: 30); }