# 02 — خطة الباك إند (NestJS) ## الحزمة التقنية - **NestJS 11** + TypeScript + **TypeORM** + **PostgreSQL 16 / PostGIS**. - **Redis** (حضور، مطابقة GEO، pub/sub) + **BullMQ** (مهام). - **Socket.IO** عبر `@nestjs/websockets` + `socket.io-redis-adapter`. - **Swagger** للتوثيق، **class-validator** للتحقق، **Throttler** لتحديد المعدل. - يُعاد استخدام نواة **Tenant + Usage interceptor** من باك إند انطلق كمكتبة مشتركة. ## نمط الطلب (كل request يمر بهذه السلسلة) ``` Request → Guard: JwtAuthGuard (من أنت؟) → Guard: TenantGuard (أي مستأجر؟ يحقن tenantId في السياق) → Guard: RolesGuard (هل يُسمح لدورك؟) → Pipe: ValidationPipe (DTO صالح؟) → Controller → Service (منطق العمل) → Interceptor: UsageInterceptor (سجّل الاستخدام للفوترة) → Interceptor: LoggingInterceptor Response ``` ## الوحدات (Modules) | الوحدة | المسؤولية | نقاط نهاية أساسية | |--------|-----------|-------------------| | `auth` | تسجيل/دخول/OTP/JWT/refresh | `POST /auth/otp`, `/auth/verify`, `/auth/refresh` | | `tenants` | إدارة المستأجرين، الإعداد الديناميكي، country pack | `GET /tenant/config` | | `users` | الراكب/السائق/المشغّل/الأدمن، الأدوار | `GET /me`, `PATCH /me` | | `drivers` | تسجيل بالوثائق، حالة الاتصال، الأرباح | `POST /drivers/apply`, `GET /drivers/earnings` | | `trips` | دورة الرحلة الكاملة، الحالات، السجل | `POST /trips`, `PATCH /trips/:id/status` | | `matching` | إيجاد أقرب سائق مؤهل (Redis GEO) | داخلي (يستدعيه trips) | | `tariff` | حساب/تثبيت/إنهاء السعر — [04](04-tariff-engine.md) | `POST /tariff/quote` | | `dispatch` | لوحة المشغّل، طلبات الهاتف، التوزيع اليدوي | `POST /dispatch/orders` | | `maps` | وكيل انطلق (بلاطات/ترميز/توجيه/snapping) | `GET /maps/geocode`, `/maps/route` | | `payments` | محوّلات الدفع، التسويات — [07](07-integrations.md) | `POST /payments/charge` | | `billing` | فوترة المستأجر الشهرية، GMV، الباقات — [05](05-pricing-billing.md) | `GET /billing/invoices` | | `pricing-zones` | مناطق سعر ثابت (PostGIS polygons) | `GET /zones` | | `notifications` | FCM، SMS، قوالب | داخلي + `POST /notify/test` | | `regulator` | تصدير/بث للمنظّم الحكومي — [07](07-integrations.md) | `GET /regulator/export` | | `webhooks` | أحداث صادرة للمستأجرين المتقدمين | إدارة الاشتراكات | | `admin` | تجميعات My Hub، التقارير، الحملات | `GET /admin/reports` | | `realtime` | WebSocket Gateway — [09](09-realtime.md) | WS namespaces | ## آلة حالة الرحلة (Trip State Machine) مصدر الحقيقة على الباك إند، ويطابقها الـ Bloc على الموبايل: ``` searching → assigned → driver_arriving → driver_arrived → in_progress → completed → paid (فروع: cancelled_by_rider | cancelled_by_driver | no_drivers | expired) ``` - كل انتقال يُسجّل في `trip_events` (سجل تشخيصي + مطلب المنظّم). - الانتقالات تأتي من: المستخدم (API)، الـ socket (السائق)، المؤقتات (BullMQ). ## قواعد الهندسة - **لا استعلام بلا `tenant_id`:** يُفرض بـ Repository scoped أو subscriber على مستوى TypeORM. راجع [06](06-tenant-model.md). - **DTO لكل مدخل/مخرج** — لا كائنات خام تعبر الحدود. - **الخدمات نقية قابلة للاختبار:** المنطق في Services، الـ Controllers رفيعة. - **الهجرات (migrations) فقط** — لا `synchronize: true` في الإنتاج. - **الأسرار من متغيرات البيئة/Vault** — لا مفاتيح في الكود. ## هيكل الكود (backend/) ``` src/ ├── main.ts ├── app.module.ts ├── common/ # guards, interceptors, decorators, filters, pipes │ ├── tenant/ # TenantGuard, tenant-scoped repository, decorator │ └── usage/ # UsageInterceptor (مستعاد من انطلق) ├── config/ # ConfigModule, country-packs loader ├── modules/ │ ├── auth/ tenants/ users/ drivers/ trips/ matching/ │ ├── tariff/ dispatch/ maps/ payments/ billing/ │ ├── pricing-zones/ notifications/ regulator/ webhooks/ admin/ ├── realtime/ # WebSocket gateway + adapters ├── jobs/ # BullMQ processors ├── database/ # entities, migrations, seeds └── integrations/ # payment adapters, sms adapters, regulator adapters ``` ← السابق: [01-architecture](01-architecture.md) · التالي: [03-mobile-plan](03-mobile-plan.md)