# نموذج التخطيط والجدولة

## حدود الإصدار

وحدة التخطيط في الإصدار 0.2.0 تدير القوالب، WBS، الأنشطة، العلاقات، CPM، Gantt، Baseline والإنجاز الموزون. تعتمد يوم العمل كوحدة احتساب؛ تبقى حقول المدد عشرية في قاعدة البيانات لكن محرك CPM يقربها إلى يوم كامل عند وضع التواريخ.

## سلسلة البيانات

```mermaid
flowchart TB
    Template["Project Template + Version"] --> WBS["WBS + Closure Tree"]
    WBS --> Activity["Activities & Milestones"]
    Activity --> Dependency["FS / SS / FF / SF"]
    Dependency --> CPM["CPM Calculation Run"]
    CPM --> Current["Current Dates + Float"]
    Current --> Baseline["Immutable Baseline Snapshots"]
    Baseline --> Progress["Planned vs Actual"]
```

## طبقات التاريخ

| القيمة | المصدر | متى تتغير |
|---|---|---|
| Original Duration | أول Baseline معتمد | لا تتغير بعد ضبطها |
| Baseline Start/Finish | لقطة Baseline محددة | لا تتغير داخل النسخة |
| Current Start/Finish | محرك CPM أو نشاط يدوي | مع إعادة الجدولة |
| Actual Start/Finish | تحديث التنفيذ | مع الوقوع الفعلي فقط |
| Remaining Duration | تحديث التنفيذ | عند كل Data Date |

اعتماد Baseline جديد يحول النشط السابق إلى `superseded` ولا يحذف لقطاته. `project_schedule_settings.active_baseline_id` هو مرجع المقارنة الحالي.

## WBS والأوزان

- `wbs_nodes` يحفظ الأب المباشر لسهولة التحرير.
- `wbs_node_closure` يحفظ كل علاقة سلف/تابع لطلبات الشجرة والتقارير المستقبلية.
- وزن النشاط نسبي داخل عنصر WBS.
- وزن كل عنصر WBS نسبي بين إخوته.
- التجميع يبدأ من الأنشطة ثم يصعد إلى الجذر.
- عند اعتماد Baseline يجب أن يساوي مجموع كل مجموعة إخوة 100%، وألا يكون مجموع أوزان أنشطة أي WBS صفرًا.

معادلة التجميع لكل مجموعة:

$$
Progress = \frac{\sum_{i=1}^{n}(Progress_i \times Weight_i)}{\sum_{i=1}^{n} Weight_i}
$$

## CPM والعلاقات

يدعم المحرك:

| الرمز | المعنى |
|---|---|
| FS | يبدأ اللاحق بعد انتهاء السابق |
| SS | يبدأ اللاحق نسبةً إلى بداية السابق |
| FF | ينتهي اللاحق نسبةً إلى نهاية السابق |
| SF | ينتهي اللاحق نسبةً إلى بداية السابق |

القيمة الموجبة في `lag_days` تأخير، والسالبة Lead. قبل حفظ العلاقة يُنفذ Topological Check، لذلك لا تدخل الدورة المغلقة إلى قاعدة البيانات. بعد ذلك يحسب المحرك Forward Pass وBackward Pass وTotal Float، ويعد النشاط حرجًا عندما يكون Float أقل من أو يساوي صفرًا.

## Planned وActual

- Planned Progress يحسب من تواريخ ومدة Baseline النشط، أو من الخطة الحالية قبل أول اعتماد.
- Actual Progress يأتي من `physical_progress` وليس من مرور الزمن.
- Duration Progress مؤشر منفصل مشتق من Current Duration وRemaining Duration.
- كل احتساب يحفظ Snapshot حسب `project_id + data_date` لعرض الاتجاهات والتقارير.
- كل تحديث إنجاز يحفظ القيمة السابقة والجديدة والتواريخ والملاحظة والمنفذ.

## ضوابط التشغيل

- النشاط اليدوي يحتاج تاريخ بداية، بينما النشاط التلقائي تحكمه العلاقات والقيود.
- النهاية الفعلية لا تقبل قبل وصول الإنجاز إلى 100%.
- خفض الإنجاز يحتاج ملاحظة تبريرية.
- Baseline لا ينشأ إذا كان نشاط فعال بلا بداية أو نهاية محسوبة.
- التقويم الافتراضي السعودي يعمل من الأحد إلى الخميس، ويمكن إضافة تقاويم واستثناءات من قاعدة البيانات دون تعديل المحرك.

## نقاط التوسع المحفوظة

- ربط تقدم المهام بالنشاط منفذ في الإصدار 0.3.0 عند تفعيل المزامنة على المهمة.
- ربط BOQ والتكاليف بأكواد WBS دون تكرار الهيكل.
- إضافة Resource Loading وEVM فوق نفس الأنشطة وProgress Snapshots.
- إضافة Import/Export لـPrimavera وMicrosoft Project عبر Public IDs وAPI/Outbox.
