# تقرير العمارة التقنية — Technical Architecture Document

## نظرة عامة

النظام مكون من ثلاثة أقسام رئيسية:
- **Backend:** Laravel API (RESTful)
- **Mobile App:** Flutter / React Native (لم يُحدد بعد — مؤجل لقرار العميل)
- **Admin Panel:** Laravel Web (Filament أو Nova)

---

## الهيكل العام

```
┌──────────────────────────────────────────────────────────────┐
│                     Mobile App (iOS/Android)                   │
│                Flutter / React Native (TBD)                    │
└────────────┬──────────────────────────────┬───────────────────┘
             │ HTTP REST                    │ Push (Expo)
             ▼                              ▼
┌──────────────────────────────────────────────────────────────┐
│                     Laravel API Backend                        │
│  ┌─────────────────────────────────────────────────────────┐  │
│  │                    Modules System                        │  │
│  │  ┌─────────────────────┐  ┌──────────────────────────┐  │  │
│  │  │    Core Module      │  │     Storage Module        │  │  │
│  │  │  - Base Models      │  │  - R2 Presigned URLs     │  │  │
│  │  │  - Response Trait   │  │  - Encryption Service    │  │  │
│  │  │  - Permissions      │  │  - Custom R2 Adapter     │  │  │
│  │  │  - Filterable       │  │  - Tenant Credentials    │  │  │
│  │  │  - Controller       │  │                          │  │  │
│  │  └─────────────────────┘  └──────────────────────────┘  │  │
│  └─────────────────────────────────────────────────────────┘  │
│  ┌──────────┐  ┌────────────────────────────────────────┐    │
│  │ Sanctum  │  │   Laravel Events / Notifications       │    │
│  │  (Auth)  │  │   (قيد التطوير)                        │    │
│  └──────────┘  └────────────────────────────────────────┘    │
└──────────────────────────────────────────────────────────────┘
             │
             ▼
┌─────────────────────┐  ┌─────────────────────────┐
│    PostgreSQL DB    │  │  Cloudflare R2 (Storage) │
└─────────────────────┘  └─────────────────────────┘
```

---

## مكدس التقنيات (Tech Stack)

| الطبقة | التقنية | الحالة | المبرر |
|--------|---------|--------|--------|
| Backend Framework | Laravel 12 | ✅ مثبت | PHP stable, ecosystem rich |
| Modular Architecture | nwidart/laravel-modules v12 | ✅ مثبت | تنظيم الكود في modules مستقلة |
| API Auth | Laravel Sanctum v4 | ✅ مثبت | Token-based لل mobile app |
| Database | PostgreSQL | ✅ مستخدم | أداء، JSON support |
| File Storage | Cloudflare R2 (S3-compatible) | ✅ منفذ | أرخص من S3، بدون رسوم egress |
| Presigned Upload | مخصص (R2PresignedUrlService) | ✅ منفذ | رفع مباشر من التطبيق إلى R2 |
| Encryption | AES-256-GCM (مخصص) | ✅ منفذ | تشفير مفاتيح tenants |
| Cache / Queue | Database Queue (Laravel default) | 📋 مخطط | بسيط، بدون تبعيات إضافية للـ v1 |
| Permissions | AddPermissions Trait (حالياً) ← Spatie | 🔄 قيد التخطيط | أدوار وصلاحيات ديناميكية |
| Media Library | Spatie Media Library | 📋 مخطط | إدارة المرفقات مع علاقات polymorphic |
| Error Tracking | TBD (اختياري للـ v1) | 📋 مخطط | يحدد لاحقاً حسب الحاجة |
| Push Notifications | Expo Push Notifications | 📋 مخطط | Push لل mobile apps عبر Expo |
| Admin Panel | Filament (مقترح) | 📋 مخطط | يبني CRUD كامل بسرعة |

**الحالة:** ✅ مثبت = منفذ ويعمل | 🔄 قيد التطوير | 📋 مخطط = لم يبدأ بعد

---

## هيكل المشروع (الفعلي)

```
├── app/                                   # Laravel app (خفيف)
│   ├── Events/
│   │   └── BaseEvent.php                  # Base event abstract (UUID, timestamp, metadata)
│   ├── Models/                            # فارغ — النماذج في Modules/Core
│   └── Providers/
│       └── AppServiceProvider.php
│
├── Modules/                               # nwidart/laravel-modules
│   ├── Core/                              # ✅ module.json (priority: 1)
│   │   ├── Helpers/
│   │   │   └── Pagination/
│   │   │       └── CustomPaginator.php    # LengthAwarePaginator مخصص
│   │   ├── Http/
│   │   │   ├── Controllers/
│   │   │   │   └── Controller.php         # Base controller abstract (4 traits)
│   │   │   └── Middleware/
│   │   │       └── APILanguageMiddleware.php  # Accept-Language: ar/en/tr
│   │   ├── Interfaces/
│   │   │   └── DTOInterface.php           # contract: fromRequest(array): static
│   │   ├── Models/
│   │   │   ├── BaseModel.php              # Model أساسي (Filterable, auto-code, money rounding)
│   │   │   ├── BaseAuthenticatable.php    # User base model (Authenticatable + Filterable)
│   │   │   └── User.php                   # User model (HasFactory, Notifiable)
│   │   ├── Providers/
│   │   │   └── CoreServiceProvider.php
│   │   └── Traits/
│   │       ├── AddPermissions.php         # صلاحيات تلقائية عن طريق route names
│   │       ├── Filterable.php             # Search, filter, multi-filter, date-range
│   │       ├── InteractWithResponse.php   # توحيد شكل الاستجابة JSON
│   │       └── Loggable.php               # تسجيل النشاطات
│   │
│   └── Storage/                           # ✅ module.json (priority: 0)
│       ├── config/
│       │   └── config.php
│       ├── database/
│       │   ├── migrations/                # .gitkeep (قيد الإنشاء)
│       │   └── seeders/
│       ├── Drivers/
│       │   └── R2TenantFilesystemAdapter.php  # FilesystemAdapter مخصص لـ R2
│       ├── DTOs/
│       │   └── PresignedUploadResult.php  # readonly DTO (url, folder, filename, key)
│       ├── Http/
│       │   ├── Controllers/
│       │   │   └── PresignedUploadController.php  # Invokable — POST /uploads/presigned-url
│       │   └── Requests/
│       │       └── PresignedUploadRequest.php     # FormRequest (filename, mime_type validation)
│       ├── Providers/
│       │   ├── StorageServiceProvider.php         # Register r2-tenant disk + services
│       │   └── RouteServiceProvider.php           # routes/api.php prefix: api
│       ├── routes/
│       │   └── api.php                     # POST /uploads/presigned-url
│       └── Services/
│           ├── EncryptionService.php       # AES-256-GCM encrypt/decrypt
│           ├── R2ClientFactory.php         # S3Client factory لـ R2
│           ├── R2PresignedUrlService.php   # إنشاء presigned upload URLs
│           └── TenantCredentialService.php # إدارة مفاتيح tenants (skeleton)
│
├── boilerplate/                           # مرجع معماري سابق (قبل الـ Modules)
├── docs/                                  # وثائق المشروع
├── routes/
│   ├── api.php                            # routes Laravel الافتراضية (minimal)
│   └── web.php
├── tests/                                 # Pest tests (قيد الإنشاء)
└── stubs/                                 # Custom stubs (e.g., enum.stub)
```

---

## بنية Modules (نظام الوحدات)

### Core Module — البنية التحتية المشتركة

```
Modules/Core/
├── Traits/InteractWithResponse.php    # ← توحيد استجابة API
├── Traits/AddPermissions.php          # ← نظام الصلاحيات التلقائي
├── Traits/Filterable.php              # ← فلترة وبحث موحد
├── Traits/Loggable.php                # ← تسجيل الأنشطة
├── Models/BaseModel.php               # ← Base Model لكل النماذج
├── Models/BaseAuthenticatable.php     # ← Base Model للمستخدمين
├── Http/Controllers/Controller.php    # ← Base Controller (يضم 4 traits)
└── Http/Middleware/APILanguageMiddleware.php  # ← دعم الترجمة
```

### Storage Module — رفع وتخزين الملفات

```
Modules/Storage/
├── Services/R2PresignedUrlService.php       # ← إنشاء presigned URLs
├── Services/R2ClientFactory.php             # ← تهيئة S3Client
├── Services/EncryptionService.php           # ← تشفير F洀فاتاي tenants
├── Services/TenantCredentialService.php     # ← إدارة مفاتيح tenants
├── Drivers/R2TenantFilesystemAdapter.php    # ← Filesystem adapter مخصص
├── DTOs/PresignedUploadResult.php           # ← DTO للنتيجة
├── Http/Controllers/PresignedUploadController.php  # ← API endpoint
└── Http/Requests/PresignedUploadRequest.php         # ← Validation
```

---

## شكل الاستجابة الموحد (Standard API Response)

جميع استجابات API تتبع تنسيقًا موحدًا عبر trait `InteractWithResponse` في `Modules/Core/Traits/InteractWithResponse.php`.

### استجابة ناجحة (sendSuccessResponse)

```json
{
    "success": true,
    "code": 200,
    "message": "تمت العملية بنجاح",
    "result": { ... }
}
```

### استجابة فاشلة (sendFailedResponse)

```json
{
    "success": false,
    "code": 400,
    "message": "حدث خطأ",
    "errors": {
        "field": ["validation error 1", "validation error 2"]
    }
}
```

### استجابة مرقمة (sendPaginatedResponse)

```json
{
    "success": true,
    "code": 200,
    "message": "تمت العملية بنجاح",
    "to": 15,
    "page": 0,
    "pages": 5,
    "count": 50,
    "result": [ ... ]
}
```

يستخدم `CustomPaginator` في `Modules/Core/Helpers/Pagination/CustomPaginator.php` (يمتد `LengthAwarePaginator`) لتوليد هذا التنسيق مع ترقيم صفحات يبدأ من 0.

---

## تدفق رفع الملفات (File Upload Flow)

### المبدأ: رفع مباشر إلى R2 (Presigned URLs)

الملفات **لا تمر عبر سيرفر Laravel** أثناء الرفع، مما يمنع استهلاك الموارد ويدعم الملفات الكبيرة.

#### الخطوة 1: طلب Presigned URL

```
Mobile App                          Laravel API (Storage Module)
    │                                      │
    │  POST /api/uploads/presigned-url     │
    │  {filename: "photo.jpg",             │
    │   mime_type: "image/jpeg"}           │
    │ ───────────────────────────────────> │
    │                                      │─ R2PresignedUrlService
    │                                      │   ينشئ مجلد مؤقت:
    │                                      │   files/tmp/{uniqid}-{ts}/{filename}
    │                                      │─ ينشئ S3 PutObject command
    │                                      │─ يصدر presigned request (60 دقيقة)
    │  200 {                               │
    │   url: "https://r2.cloud/...",       │
    │   folder: "files/tmp/abc-123/",      │
    │   filename: "photo.jpg",             │
    │   key: "files/tmp/abc-123/photo.jpg" │
    │  }                                    │
    │ <─────────────────────────────────── │
```

#### الخطوة 2: رفع الملف مباشرة إلى R2

```
Mobile App                                 Cloudflare R2
    │                                           │
    │  PUT {url من الخطوة 1}                     │
    │  (body: الملف مباشرة)                      │
    │ ──────────────────────────────────────────> │
    │  200 OK                                     │
    │ <────────────────────────────────────────── │
```

#### الخطوة 3 (مستقبلية): تسجيل الملف

```
Mobile App                          Laravel API
    │                                      │
    │  POST /api/media/register            │
    │  {key, model_type, model_id, ...}    │
    │ ───────────────────────────────────> │
    │                                      │─ Queue: ProcessMediaFile
    │                                      │─ Spatie Media Library: attach
    │                                      │─ نقل الملف من tmp إلى المسار النهائي
    │  200 {media_id, url}                │
    │ <─────────────────────────────────── │
```

### المكونات المستخدمة

| المكون | المسار | الوظيفة |
|--------|--------|---------|
| PresignedUploadController | `Modules/Storage/Http/Controllers/PresignedUploadController.php` | API endpoint (invokable) |
| PresignedUploadRequest | `Modules/Storage/Http/Requests/PresignedUploadRequest.php` | Validate (filename, mime_type) |
| R2PresignedUrlService | `Modules/Storage/Services/R2PresignedUrlService.php` | إنشاء presigned URLs |
| R2ClientFactory | `Modules/Storage/Services/R2ClientFactory.php` | تكوين S3Client لـ R2 |
| PresignedUploadResult | `Modules/Storage/DTOs/PresignedUploadResult.php` | DTO: url, folder, filename, key |
| R2TenantFilesystemAdapter | `Modules/Storage/Drivers/R2TenantFilesystemAdapter.php` | Filesystem adapter (url, temporaryUrl) |
| EncryptionService | `Modules/Storage/Services/EncryptionService.php` | AES-256-GCM تشفير |
| TenantCredentialService | `Modules/Storage/Services/TenantCredentialService.php` | إدارة مفاتيح tenants |

### تسجيل الـ Filesystem

في `StorageServiceProvider::boot()`:
```php
Storage::extend('r2-tenant', function ($app, $config) {
    $client = $app->make(R2ClientFactory::class)->getClient();
    $adapter = new AwsS3V3Adapter($client, $bucket);
    $filesystem = new Filesystem($adapter, $config);
    return new R2TenantFilesystemAdapter($filesystem, $adapter, $config);
});
```

---

## نظام الصلاحيات (Permissions System)

### التنفيذ الحالي: AddPermissions Trait

في `Modules/Core/Traits/AddPermissions.php`، يتم التحقق من الصلاحيات تلقائيًا عبر route names:

```php
public function callAction($method, $parameters)
{
    if (config('app.apply_permissions', false)) {
        $this->applyPermission($method);
    }
    return parent::callAction($method, $parameters);
}

protected function applyPermission(string $method): void
{
    $permissionSuffix = Arr::get($this->crudPermissions, $method);  // show, list, create, edit, delete
    $routeName = request()->route()->getName();
    $permission = $routeName . '.' . $permissionSuffix;
    $this->authorize($permission);
}
```

### خريطة الصلاحيات (CRUD Mapping)

| Method | Permission Suffix | مثال (route=auth.users) |
|--------|-------------------|------------------------|
| index | list | `auth.users.list` |
| show | show | `auth.users.show` |
| store | create | `auth.users.create` |
| update | edit | `auth.users.edit` |
| destroy | delete | `auth.users.delete` |

### الأدوار المخطط لها

| الدور | المعرف |
|-------|--------|
| Super Admin | `super_admin` |
| Admin | `admin` |
| Teacher | `teacher` |
| Parent | `parent` |

### الخطة المستقبلية

| المرحلة | الوصف |
|---------|-------|
| 1 | ✅ AddPermissions trait مع `$this->authorize()` |
| 2 | 📋 تثبيت `spatie/laravel-permission` |
| 3 | 📋 إنشاء middleware: `permission:` |
| 4 | 📋 إنشاء Policy classes لكل entity |
| 5 | 📋 Seeder للأدوار والصلاحيات |

---

## Base Controller

جميع الـ Controllers ترث من `Modules/Core/Http/Controllers/Controller.php`:

```php
abstract class Controller
{
    use AddPermissions;       // صلاحيات تلقائية
    use AuthorizesRequests;   // Laravel authorization
    use InteractWithResponse; // توحيد شكل الاستجابة
    use ValidatesRequests;    // Laravel validation
}
```

---

## Base Models

### BaseModel (`Modules/Core/Models/BaseModel.php`)
- **Filterable trait**: search, filter, multi-filter, date range scopes
- Auto rounding للمبالغ المالية
- Auto code generation
- Approval lock mechanism

### BaseAuthenticatable (`Modules/Core/Models/BaseAuthenticatable.php`)
- extends `Authenticatable`
- يستخدم `Filterable` trait

---

## DTO Pattern

جميع Data Transfer Objects تطبق `Modules/Core/Interfaces/DTOInterface.php`:

```php
interface DTOInterface
{
    public static function fromRequest(array $array): static;
}
```

مثال — `Modules/Storage/DTOs/PresignedUploadResult.php`:
```php
final readonly class PresignedUploadResult
{
    public function __construct(
        public string $url,
        public string $folder,
        public string $filename,
        public string $key,
    ) {}
}
```

---

## أحداث النظام (Events)

جميع الأحداث ترث من `app/Events/BaseEvent.php` الذي يضيف:
- **eventId**: UUID فريد لكل حدث
- **timestamp**: ISO 8601 timestamp
- **metadata**: array لداتا إضافية

---

## تدفق المصادقة (Auth Flow)

```
Mobile App                    Laravel API
    │                             │
    │  POST /api/auth/login       │
    │  {email, password}          │
    │────────────────────────────>│
    │                             │─ تحقق من credentials
    │                             │─ إنشاء Sanctum token
    │  200 {                       │
    │   success: true,             │
    │   result: {                  │
    │    token, user, role         │
    │   }                          │
    │  }                           │
    │<────────────────────────────│
    │                             │
    │  GET /api/me                │
    │  Authorization: Bearer TOK  │
    │────────────────────────────>│
    │  200 {                       │
    │   success: true,             │
    │   result: { user, perms }   │
    │  }                           │
    │<────────────────────────────│
    │                             │
    │  POST /api/auth/logout      │
    │────────────────────────────>│
    │                             │─ إلغاء token
```

---

## Middleware

### APILanguageMiddleware
في `Modules/Core/Http/Middleware/APILanguageMiddleware.php`:
- يقرأ `Accept-Language` من الهيدر
- يدعم: `ar` (عربي)، `en` (إنجليزي)، `tr` (تركي)
- مسجل كـ global middleware على API routes في `bootstrap/app.php`:

```php
$middleware->api(prepend: [
    APILanguageMiddleware::class,
]);
```

---

## نقاط التكامل (Integration Points)

| نقطة التكامل | من | إلى | البروتوكول | الحالة |
|-------------|-----|-----|-----------|--------|
| API Calls | Mobile App | Laravel | HTTPS REST | ✅ |
| Presigned Upload Request | Mobile App | Laravel | HTTPS REST | ✅ |
| File Upload (Direct) | Mobile App | R2 مباشرة | HTTPS PUT | ✅ |
| Push | Laravel | Expo | HTTPS | 📋 |

---

## قرارات هندسية هامة

1. **لماذا nwidart/laravel-modules وليس DDD التقليدي؟** — يوفر عزلاً أقوى لكل module مع routes, models, migrations, tests خاصة به دون تلويث cross-contamination. يسمح بتطوير موازٍ وتوزيع المسؤوليات بشكل أوضح.

2. **لماذا PostgreSQL وليس MySQL؟** — دعم أفضل للـ JSON، أداء أعلى مع العلاقات المعقدة.

3. **لماذا رفع مباشر (Presigned URL) إلى R2 وليس عبر Laravel؟** — يمنع استهلاك موارد السيرفر أثناء الرفع، يدعم ملفات كبيرة (فيديو 100MB) بدون timeout، ويقلل التكلفة التشغيلية. الـ Laravel يقتصر على إصدار الـ presigned URL وتسجيل المرجع بعد اكتمال الرفع.

4. **لماذا Sanctum وليس Passport؟** — أبسط لتطبيقات mobile SPA، لا حاجة لـ OAuth2 الكامل.

5. **لماذا AddPermissions trait بدلاً من Spatie مباشرة؟** — في المرحلة الأولى، يوفر صلاحيات تلقائية بالاعتماد على route names مع Gate/Authorization المدمج في Laravel. عند الحاجة لأدوار ديناميكية وواجهة إدارة، يتم الترقية إلى Spatie.

6. **لماذا تنسيق response موحد؟** — لتسهيل التعامل مع الاستجابات من التطبيق (mobile app) دون الحاجة لمعالجة formats مختلفة لكل endpoint.

7. **لماذا Database Queue بدلاً من Redis/Horizon؟** — للـ v1، حجم المهام الخلفية محدود ولا يبرر تعقيد إدارة Redis + Horizon. قاعدة البيانات كـ queue driver كافية تماماً ومدمجة مع Laravel بدون أي تبعيات إضافية، ويمكن الترقية إلى Redis/Horizon لاحقاً عند الحاجة.

8. **لماذا Expo Push Notifications بدلاً من FCM؟** — Expo يوفر واجهة موحدة للإشعارات عبر iOS و Android دون الحاجة لكتابة كود منفصل لكل منصة. يتكامل مباشرة مع تطبيقات React Native (المحتملة) ويبسط إدارة الـ push tokens مقارنة بـ FCM.

---

## مسار التطوير المقترح

| المرحلة | المهام |
|---------|--------|
| 1 ✅ | إعداد Core Module (Base Models, Traits, Controller) |
| 2 ✅ | إعداد Storage Module (Presigned Upload, R2, Encryption) |
| 3 🔄 | إنشاء نظام المصادقة (Sanctum) |
| 4 📋 | تثبيت Spatie Permission وإنشاء الأدوار والصلاحيات |
| 5 📋 | تطوير Domain Modules (Students, Attendance, Meals, ...) |
| 6 📋 | إضافة Spatie Media Library لإدارة المرفقات |
| 7 📋 | إعداد Database Queue |
| 8 📋 | إعداد Expo Push Notifications |
| 9 📋 | Admin Panel (Filament) |
