# 03 — البرامج التدريبية والمجموعات

## نظرة عامة

**البرنامج التدريبي** = المنهج/الخطة (مثل: "كرة قدم - مبتدئين 6-8 سنوات")
**المجموعة** = التطبيق الفعلي للبرنامج (مثل: "مجموعة السبت والثلاثاء - المعادي")
**الجدول** = مواعيد المجموعة الأسبوعية
**الحصة** = جلسة تدريبية واحدة في يوم محدد

```
برنامج → مجموعة → جدول أسبوعي → حصص يومية
```

---

## الشاشات المنفذة

### 1. إدارة الأنشطة (`/activities`)

**من يراها:** من لديه صلاحية `activities.list`

**الوصف:** النشاط هو الرياضة نفسها (كرة قدم، سباحة، جمباز...). كل برنامج مرتبط بنشاط واحد.

**شاشة القائمة:**
| العمود | الوصف |
|--------|-------|
| الاسم بالعربية | name_ar |
| الاسم بالإنجليزية | name |
| التصنيف | category (فردي/جماعي/مائي/قتالي...) |
| مفعّل | is_active |
| الإجراءات | تعديل |

**شاشة الإنشاء/التعديل (`/activities/create`, `/activities/{id}/edit`):**
| الحقل | النوع | مطلوب | ملاحظات |
|--------|------|-------|---------|
| الاسم بالعربية | text | ✓ | |
| الاسم بالإنجليزية | text | ✓ | |
| التصنيف | select | ✓ | team_sport, individual_sport, aquatic, combat, fitness, dance, gymnastics, other |
| الوصف بالعربية | textarea | ✗ | |
| الوصف بالإنجليزية | textarea | ✗ | |
| مفعّل | toggle | — | |

---

### 2. قائمة البرامج التدريبية (`/programs`)

**من يراها:** من لديه صلاحية `programs.list`

**الفلاتر:**
- بحث بالاسم
- تصفية بالنشاط
- تصفية بالفرع
- تصفية بالحالة

**أعمدة الجدول:**
| العمود | الوصف |
|--------|-------|
| الاسم | name_ar |
| النشاط | activity.name_ar |
| الفرع | branch.name_ar |
| الحصص/الأسبوع | sessions_per_week |
| مدة الحصة | session_duration_minutes |
| السعة | min - max |
| الحالة | draft/active/archived |
| التسجيل مفتوح | ✓/✗ |

---

### 3. إنشاء برنامج — نموذج (`/programs/create`)

**من يراها:** من لديه صلاحية `programs.create`

**الحقول:**
| الحقل | النوع | مطلوب | ملاحظات |
|--------|------|-------|---------|
| الاسم بالعربية | text | ✓ | |
| الاسم بالإنجليزية | text | ✓ | |
| المعرّف (slug) | text | ✓ | يُولّد من الاسم |
| النشاط | select | ✓ | |
| الفرع | select | ✗ | |
| الوصف بالعربية | textarea | ✗ | |
| الوصف بالإنجليزية | textarea | ✗ | |
| مستوى المهارة | select | — | all, beginner, intermediate, advanced, professional |
| العمر الأدنى | number | ✗ | |
| العمر الأقصى | number | ✗ | |
| الجنس | select | — | all, male, female |
| حصص في الأسبوع | number | ✓ | افتراضي: 2 |
| مدة الحصة (دقائق) | number | ✓ | افتراضي: 60 |
| إجمالي الحصص | number | ✗ | للبرامج المحددة |
| مدة البرنامج (أسابيع) | number | ✗ | |
| الحد الأدنى للمشتركين | number | ✓ | افتراضي: 1 |
| الحد الأقصى للمشتركين | number | ✓ | افتراضي: 20 |
| السماح بقائمة الانتظار | toggle | — | افتراضي: نعم |
| نسبة الحضور المطلوبة | number | ✗ | % |
| تقييم مطلوب | toggle | — | |
| التسجيل مفتوح | toggle | — | |
| آخر موعد للتسجيل | date | ✗ | |
| تاريخ بدء البرنامج | date | ✗ | |
| تاريخ انتهاء البرنامج | date | ✗ | |
| سياسة التجديد | select | ✓ | manual_renew, auto_renew, no_renew |
| سياسة الإلغاء | textarea | ✗ | |
| سياسة الاسترداد | textarea | ✗ | |
| الحالة | select | ✓ | draft, active, archived |
| مميز | toggle | — | |
| سعر الأعضاء | money | ✗ | ج.م |
| سعر غير الأعضاء | money | ✗ | ج.م |

---

### 4. إنشاء برنامج — ويزارد (`/programs/wizard`)

**ويزارد من 3 خطوات:**

**الخطوة 1: البيانات الأساسية**
- الاسم، النشاط، الفرع، المستوى، العمر، الجنس

**الخطوة 2: هيكل البرنامج**
- حصص/أسبوع، مدة الحصة، إجمالي الحصص، السعة

**الخطوة 3: السياسات والتسعير**
- التجديد، الإلغاء، الأسعار

---

### 5. قائمة المجموعات (`/groups`)

**من يراها:** من لديه صلاحية `groups.list`

**الفلاتر:**
- بحث بالاسم أو الكود
- تصفية بالبرنامج
- تصفية بالفرع
- تصفية بالحالة

**أعمدة الجدول:**
| العمود | الوصف |
|--------|-------|
| الكود | code |
| الاسم | name_ar |
| البرنامج | program.name_ar |
| المدرب الرئيسي | head_trainer.name |
| السعة | current_count / max_capacity |
| الموسم | season |
| الحالة | شارة ملونة |
| الإجراءات | تعديل |

---

### 6. إنشاء مجموعة — نموذج (`/groups/create`)

**من يراها:** من لديه صلاحية `groups.create`

**الحقول:**
| الحقل | النوع | مطلوب | ملاحظات |
|--------|------|-------|---------|
| البرنامج | select | ✓ | عند الاختيار: يملأ السعة والفرع تلقائياً |
| الفرع | select | ✗ | |
| الاسم بالإنجليزية | text | ✓ | |
| الاسم بالعربية | text | ✓ | |
| الكود | text | ✗ | حتى 10 أحرف |
| المدرب الرئيسي | select | ✗ | |
| الحد الأقصى للسعة | number | ✓ | 1-500 |
| الموسم | text | ✗ | مثل: "2024-2025" |
| تاريخ البداية | date | ✗ | |
| تاريخ الانتهاء | date | ✗ | بعد أو يساوي تاريخ البداية |
| ملاحظات | textarea | ✗ | حتى 1000 حرف |

---

### 7. إنشاء مجموعة — ويزارد (`/groups/wizard`)

**ويزارد متعدد الخطوات:**
1. اختيار البرنامج والفرع
2. بيانات المجموعة (اسم، كود، مدرب)
3. إعداد الجدول الأسبوعي (أيام + أوقات)
4. تأكيد ومراجعة

---

### 8. الجدول الأسبوعي (`/schedule`)

**من يراها:** من لديه صلاحية `schedules.view`

**الوصف:** عرض أسبوعي يُظهر كل الحصص مرتبة بالأيام والأوقات.

**التصفية:** بالفرع، بالمجموعة، بالمدرب، بالملعب

**المعلومات لكل حصة:**
- المجموعة
- المدرب
- الملعب
- الوقت (من - إلى)
- الحالة (مجدولة / جارية / مكتملة / ملغاة)

---

### 9. إعادة جدولة حصة (Reschedule)

**المكوّن:** `RescheduleSession`

**الحقول:**
- التاريخ الجديد
- الوقت الجديد
- السبب

**السلوك:**
- الحصة الأصلية → حالة "rescheduled"
- تُنشأ حصة جديدة بالتاريخ/الوقت الجديد
- تُرسل إشعارات للمشتركين

---

### 10. طباعة جدول المجموعة (`/groups/{id}/print`)

**من يراها:** من لديه صلاحية `groups.list`

**المحتوى:**
- اسم المجموعة والبرنامج
- جدول الأيام والأوقات
- المدرب
- الملعب
- قابل للطباعة

---

## حالات المجموعة

```mermaid
stateDiagram-v2
    [*] --> تكوين
    تكوين --> نشطة : بدء التدريب
    تكوين --> ملغاة : إلغاء قبل البدء

    نشطة --> ممتلئة : وصول السعة القصوى
    نشطة --> متوقفة : إيقاف مؤقت
    نشطة --> مكتملة : انتهاء البرنامج
    نشطة --> ملغاة : إلغاء

    ممتلئة --> نشطة : فتح مكان (انسحاب مشترك)

    متوقفة --> نشطة : استئناف
```

| الحالة | المعنى |
|--------|--------|
| forming | تكوين — لم تبدأ بعد |
| active | نشطة — تدريب جارٍ |
| full | ممتلئة — لا أماكن |
| on_hold | متوقفة مؤقتاً |
| completed | مكتملة — انتهى البرنامج |
| cancelled | ملغاة |

---

## حالات الحصة

```mermaid
stateDiagram-v2
    [*] --> مجدولة
    مجدولة --> جارية : بدء الحصة
    مجدولة --> ملغاة : إلغاء
    مجدولة --> معاد_جدولتها : نقل لموعد آخر

    جارية --> مكتملة : انتهاء الحصة
```

| الحالة | المعنى |
|--------|--------|
| scheduled | مجدولة — لم تبدأ |
| in_progress | جارية — الحصة الآن |
| completed | مكتملة |
| cancelled | ملغاة |
| rescheduled | أُعيدت جدولتها |

---

## توليد الحصص التلقائي

**المهمة المجدولة:** `sessions:generate-upcoming` (يومياً 02:00)

**الآلية:**
1. لكل مجموعة نشطة لها جدول أسبوعي:
2. تولّد حصص الأسبوع القادم
3. تتخطى أيام العطل (جدول `holidays`)
4. تتخطى الحصص الموجودة بالفعل (لا تكرار)

```mermaid
flowchart TD
    A[مهمة يومية 02:00] --> B[لكل مجموعة نشطة]
    B --> C[قراءة الجدول الأسبوعي]
    C --> D[لكل يوم في الأسبوع القادم]
    D --> E{هل هو عطلة؟}
    E -->|نعم| F[تخطي]
    E -->|لا| G{هل الحصة موجودة؟}
    G -->|نعم| F
    G -->|لا| H[إنشاء حصة جديدة]
    H --> I[توليد سجلات حضور متوقعة]
    I --> J[إنشاء حجز مساحة - إن وُجد تعيين]
```

---

## دورة العمل — إنشاء برنامج كامل

```mermaid
sequenceDiagram
    participant M as المدير
    participant S as النظام

    M->>S: إنشاء نشاط "كرة قدم"
    S-->>M: ✓ تم

    M->>S: إنشاء برنامج "كرة قدم - مبتدئين 6-8"
    Note over S: النشاط: كرة قدم<br>العمر: 6-8<br>المستوى: beginner<br>حصص/أسبوع: 3<br>مدة: 60 دقيقة<br>سعة: 15-20
    S-->>M: ✓ تم

    M->>S: إنشاء مجموعة "سبت-اثنين-أربعاء"
    Note over S: البرنامج: كرة قدم مبتدئين<br>المدرب: كابتن أحمد<br>السعة: 20
    S-->>M: ✓ تم

    M->>S: إنشاء جدول أسبوعي
    Note over S: السبت 16:00-17:00<br>الاثنين 16:00-17:00<br>الأربعاء 16:00-17:00
    S-->>M: ✓ تم

    M->>S: تفعيل البرنامج
    S->>S: توليد حصص الأسبوع القادم
    S-->>M: ✓ البرنامج جاهز لاستقبال مشتركين
```

---

## أمثلة عملية

### مثال 1: أكاديمية كرة قدم بـ 3 فئات عمرية
> - برنامج "براعم 4-6 سنوات" — حصتين/أسبوع × 45 دقيقة — سعة 12
> - برنامج "أشبال 7-9 سنوات" — 3 حصص/أسبوع × 60 دقيقة — سعة 18
> - برنامج "ناشئين 10-14 سنة" — 3 حصص/أسبوع × 90 دقيقة — سعة 20
>
> كل برنامج له مجموعتين أو أكثر بأيام مختلفة.

### مثال 2: أكاديمية سباحة — برنامج محدد المدة
> - برنامج "تعليم سباحة - مستوى 1" — 12 حصة إجمالي — 3/أسبوع — 4 أسابيع
> - بعد انتهاء 12 حصة: الحالة → "مكتمل"
> - يمكن الانتقال لمستوى 2

### مثال 3: مجموعة امتلأت
> - المجموعة سعتها 20 — وصل عدد المشتركين 20
> - الحالة → "ممتلئة" تلقائياً
> - المشترك الجديد يُضاف لقائمة الانتظار (إذا مفعّلة)
> - عند انسحاب مشترك: الحالة → "نشطة" + إشعار لأول شخص في الانتظار

### مثال 4: إعادة جدولة حصة بسبب المطر
> 1. المدرب يطلب إلغاء حصة الأربعاء
> 2. المدير يستخدم "إعادة جدولة" → الخميس 16:00
> 3. الحصة الأصلية → "rescheduled"
> 4. حصة جديدة الخميس → "scheduled"
> 5. إشعار لجميع المشتركين

### مثال 5: عطلة رسمية
> 1. تُسجّل في جدول العطلات: "6 أكتوبر"
> 2. عند توليد الحصص: يوم 6 أكتوبر يُتخطّى تلقائياً
> 3. لا تُنشأ حصص ولا سجلات حضور لذلك اليوم

---

## العطلات (Holidays)

**جدول `holidays`:**
| الحقل | الوصف |
|--------|-------|
| name_ar | اسم العطلة |
| date | التاريخ |
| affects | يؤثر على: all, specific_activities, specific_branches |
| is_recurring | سنوي متكرر؟ |

**التأثير:**
- لا تُولّد حصص في أيام العطل
- العطل الجارية تُلغى حصصها (إذا وُلّدت قبل إضافة العطلة)

---

## ويزارد الجدول المرئي (`/facilities/schedule-builder`)

**الوصف:** واجهة مرئية لبناء الجدول الأسبوعي — سحب وإفلات الحصص على شبكة الأيام/الأوقات.

**الميزات:**
- عرض أسبوعي بصري
- كشف التعارض الفوري (مدرب مشغول / ملعب محجوز)
- تلوين حسب المجموعة أو النشاط

---

## لماذا يحتاج عملك هذا

| الميزة | الفائدة |
|--------|---------|
| فصل البرنامج عن المجموعة | نفس البرنامج يمكن أن يعمل بعدة مجموعات بأيام مختلفة |
| توليد الحصص التلقائي | لا حاجة لإنشاء 100 حصة يدوياً — يكفي الجدول الأسبوعي |
| العطلات | لا حاجة لإلغاء حصص يدوياً كل عطلة |
| حدود العمر والمستوى | يمنع تسجيل مشترك في برنامج غير مناسب له |
| سياسة التجديد | يحدد ماذا يحدث عند انتهاء الاشتراك |
| الويزارد المرئي | بناء جدول بسهولة بدون أخطاء |
| تنبيه امتلاء المجموعة | الإدارة تعرف متى تحتاج فتح مجموعة جديدة |
| طباعة الجدول | يُعلّق في لوحة الإعلانات أو يُرسل لأولياء الأمور |

---

## التكاملات مع الوحدات الأخرى

| الوحدة | العلاقة |
|--------|---------|
| المشتركين | يُسجّلون في المجموعات عبر Enrollment |
| الحضور | لكل حصة سجلات حضور متوقعة |
| المنشآت | كل حصة مرتبطة بملعب/مساحة |
| التعيينات | المدرب مُعيّن للمجموعة أو لحصة محددة |
| التسعير | السعر مرتبط بالبرنامج |
| المالية | الفاتورة تُنشأ عند التسجيل في مجموعة |
