/// إعداد وقت التشغيل — يُمرَّر بـ`--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 = 'rider'; /// طول رمز التحقّق كما يولّده الخادم (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); }