# المعمارية المعتمدة

## نموذج النشر

- تثبيت مستقل لشركة واحدة على سيرفر وقاعدة بيانات مستقلين.
- جدول `companies` يمثل الشركة المالكة ويحتوي سجلًا تشغيليًا واحدًا.
- الفروع والإدارات والمشاريع تتبع الشركة الواحدة وظيفيًا، لذلك لا يتكرر `company_id` في كل جدول.
- عزل أي شركة مستقبلية يكون على مستوى **Deployment + Database**، وهو أقوى من العزل المنطقي داخل قاعدة مشتركة.

## نمط التطبيق

التطبيق Modular Monolith:

```mermaid
flowchart TB
    UI["Web / API"] --> Core["Security & Platform Core"]
    Core --> Modules["Business Modules"]
    Modules --> DB[("MySQL")]
    Modules --> Outbox["Transactional Outbox"]
    Outbox --> Integrations["Notifications & Integrations"]
```

النواة تحتوي المصادقة، الصلاحيات، Workflow، Approval، الملفات، الإشعارات، التدقيق والترقيم. الوحدات التشغيلية لا تعيد تنفيذ هذه الخدمات.

## حدود الوحدات

كل وحدة جديدة توضع داخل `app/Modules/<ModuleName>`، وتضيف Migration مستقلًا ولا تعدّل Migration نُشر مسبقًا. الاتصال بين الوحدات يكون عبر:

1. معرفات واضحة وForeign Keys للبيانات المتماسكة داخل قاعدة النظام.
2. خدمات تطبيقية للعمليات المتزامنة.
3. `outbox_events` للآثار الجانبية والتكاملات غير المتزامنة.

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

```mermaid
flowchart TB
    P["Project"] --> C["Contract"]
    P --> W["WBS & Schedule"]
    C --> B["BOQ"]
    W --> G["Progress"]
    B --> Cert["Certificate"]
    G --> Cert
    Cert --> Cost["Cost & Cash Flow"]
    P --> Docs["Documents & Approvals"]
    Cost --> Reports["Dashboards & Reports"]
    Docs --> Reports
```

لا تنشئ وحدة مالية قيمة مستقلة يمكن اشتقاقها من المصدر. مثلًا Revised Contract Value ينتج من Original Contract Value + Approved Variations، ويحتفظ النظام بكل مكوّن وسجل اعتماده.

## Original / Current / Actual

| المجال | Original | Current / Revised | Actual |
|---|---|---|---|
| الجدول | Baseline Start/Finish | Current Start/Finish | Actual Start/Finish |
| العقد | Original Value | Revised Value | Actual Revenue |
| الميزانية | Original Budget | Revised Budget | Actual Cost |
| الكميات | Contract Quantity | Revised Quantity | Executed/Certified Quantity |

القيم الأصلية تصبح غير قابلة للتحرير بعد الاعتماد. أي تعديل لاحق يمر عبر Version أو Change Order ويُحفظ أثره في Audit وWorkflow history.

في الجدول الزمني تحديدًا:

- لقطة Baseline تحفظ بنية WBS والأنشطة والعلاقات والتقويم والمدة والتواريخ كما كانت وقت الإنشاء.
- أول Baseline معتمد يثبت `original_duration_days` وتواريخ المشروع الأصلية من اللقطة نفسها.
- إعادة CPM تعدل `current_*` فقط، وتحديث الموقع يعدل `actual_*` و`remaining_duration_days`.
- Baseline السابق لا يُستبدل؛ يتحول إلى `superseded` عند تفعيل نسخة أحدث.
- تفاصيل النموذج والحساب موثقة في [نموذج التخطيط والجدولة](PLANNING.md).

## الصلاحيات

- الأدوار العامة تطبق على مستوى النظام.
- أدوار المشروع تطبق فقط على المشاريع التي يكون الموظف عضوًا فعالًا فيها.
- `project_member_permissions` يتيح Allow/Deny استثنائيًا داخل مشروع محدد.
- استعلامات قوائم المشاريع والأنشطة والروابط تطبق نطاق الوصول في قاعدة البيانات، وليس في الواجهة فقط.

## أمن الملفات

- مسار التخزين `storage/private/uploads` خارج Document Root.
- يمنع رفع الامتدادات التنفيذية.
- يسجل MIME، الحجم، SHA-256، الرافع وحالة الفحص لكل Version.
- لا تُستبدل نسخة قديمة؛ يشير `files.current_version_id` إلى أحدث نسخة فقط.
- تنزيل مرفقات المهام يمر عبر Controller يتحقق من صلاحية المهمة ويسجل `file_access_logs`، وتستخدم الوحدات التالية الآلية نفسها.

## التوسع

عند زيادة الحمل يمكن فصل Workers للإشعارات والتقارير والتكاملات مع إبقاء المعاملات الأساسية داخل MySQL. الـOutbox يمنع فقد الأحداث إذا نجحت المعاملة وفشل المزود الخارجي.
