feat(apps): سقالة rider_new و driver_new على Cubit — المرحلة 1

بناء من الصفر على باك إند NestJS، بقرار المالك 2026-08-04 الذي يعكس قرارَي
نقل GetX (2026-07-21) واعتماد باك إند PHP (2026-07-27). لا يُورَّث سطر دارت
من apps/*-archive-cubit، وسيرو مرجع بصري وسلوكي لا مصدر نسخ.

الوثائق:
- docs/37: الخطة الكاملة بستّ مراحل وبواباتها
- docs/38: عقد الـAPI من 37 controller، معظمه متحقَّق حيّاً من السيرفر المنشور
- docs/39: جرد 202 شاشة في تطبيقَي سيرو، مصنّفة داخل/خارج النطاق

الطبقة الأصلية منقولة من *-archive-cubit وحدها لأنها هوية النشر:
- rider_new  → com.mobileapp.store.ride · shorebird 496cb3ac
- driver_new → com.sefer_driver (أندرويد) · com.sefer.driver (iOS) · 68cc9345
- أُصلح تعارض: هدف RunnerTests في driver_new كان يحمل bundle الراكب

الأصول مصدرها *-archive-cubit لا سيرو: أصول الأرشيف مجموعة أشمل (كل صور
سيرو + صور تريبز) وخطوطها هي خطوط docs/26. استُكمل السائق بعشرة ملفات
ناقصة من سيرو (شعارات مزوّدي الدفع + صوتان).

lib/ مكتوب من الصفر (11 ملف لكل تطبيق):
- AppConfig بأعلام const — أساس نموذج lite/pro/max
- TokenStore على التخزين الآمن، يقرأ exp محليّاً بلا حزمة خارجية
- AuthInterceptor بتجديد استباقي وطلقة واحدة — عمر التوكن 15 دقيقة فقط
- ApiClient و ApiException يفهم مصفوفة message في NestJS

flutter analyze نظيف في التطبيقين. البناء الفعلي لم يُجرَّب بعد: بوابة
المرحلة 1 تتطلّب البناء على السيرفر، والوصول إليه غير متاح حالياً.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Hamza-Ayed
2026-08-04 21:21:26 +03:00
co-authored by Claude Opus 5
parent 1243e5a3b2
commit 69da4abc01
379 changed files with 15686 additions and 0 deletions
+31
View File
@@ -0,0 +1,31 @@
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:get_it/get_it.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../network/api_client.dart';
import '../storage/token_store.dart';
final sl = GetIt.instance;
/// يُنادى مرة واحدة قبل `runApp`.
Future<void> setupInjector() async {
sl.registerSingleton<SharedPreferences>(
await SharedPreferences.getInstance(),
);
const secure = FlutterSecureStorage(
iOptions: IOSOptions(accessibility: KeychainAccessibility.first_unlock),
);
final tokens = TokenStore(secure);
await tokens.load();
sl.registerSingleton<TokenStore>(tokens);
sl.registerSingleton<ApiClient>(
ApiClient.create(
tokens: tokens,
// يُربط بالتوجيه في م3 (إخراج للمستخدم عند انتهاء الجلسة).
onSessionExpired: () async {},
),
);
}