# DATABASE_MIGRATION_STRATEGY.md
### استراتيجية ترحيل قاعدة البيانات — المنصة العالمية للتعريف بالإسلام والتعليم الإسلامي

**نوع الوثيقة:** تخطيط بحت (Migration Planning) — بلا ملفات Migration، بلا SQL، بلا `prisma migrate`، بلا Seed Scripts، بلا كود من أي نوع.
**المرجع الإلزامي:** كل الوثائق المعتمَدة سابقًا وصولاً إلى `prisma/schema.prisma` الفعلي (64 Model، 34 Enum، 75 علاقة) — هذه الوثيقة تخطط **كيفية تحويل ذلك Schema إلى قاعدة بيانات حقيقية بأمان**، دون تنفيذ تلك الخطوة بعد.

---

## 1. Migration Order — ترتيب إنشاء الجداول

### 1.1 المبدأ الحاكم

الترتيب أدناه **مبدئي وتخطيطي على مستوى الطبقات (Tiers)**، لا أمرًا تنفيذيًا حرفيًا سطرًا-بسطر. **Prisma Migrate يحسب الترتيب الدقيق فعليًا وتلقائيًا** عند توليد ملف الـMigration من `schema.prisma` (عبر ترتيب طوبولوجي داخلي حسب المفاتيح الأجنبية) — لا حاجة، ولا فائدة هندسية حقيقية، لكتابة ترتيب يدوي دقيق لكل جدول من الـ64 يدويًا هنا. الغرض من هذا القسم هو **الفهم المعماري والمراجعة والتخطيط للنشر التدريجي**، لا استبدال ما يفعله Prisma تلقائيًا.

### 1.2 قاعدة تبسيط جوهرية: تأجيل المفاتيح الأجنبية الاختيارية

معظم الروابط "العميقة" بين النطاقات في هذا التصميم **اختيارية (Nullable)** — مثل `Category.iconImageId → Image`، `Article.featuredImageId → Image`، `Book.digitalAttachmentId → Attachment`، `Course.coverImageId → Image`. هذه لا تحتاج انتظار اكتمال نطاق الوسائط (Media) بالكامل قبل إنشاء `categories`/`articles`/`books`؛ من الناحية العملية تُنشأ هذه الأعمدة والقيد المرجعي (Foreign Key) لها **في نفس دفعة الترحيل التي تُنشئ فيها الجدولين**، لأن Postgres يتطلب وجود الجدول الهدف وقت إنشاء القيد بغض النظر عن كون العمود اختياريًا — لكن هذا لا يفرض ترتيبًا معقَّدًا لأن Prisma يحسبه تلقائيًا كما في §1.1. **الأثر العملي الوحيد لهذه الملاحظة:** لا داعٍ للقلق بشأن "الاعتماد الدائري الظاهري" بين النطاقات — لا يوجد اعتماد دائري فعلي في التصميم (تم التحقق برمجيًا أثناء `Phase 4`)، فقط اعتماديات عميقة يحلّها Prisma تلقائيًا.

### 1.3 الطبقات الاثنتا عشرة (للفهم والمراجعة، لا للتنفيذ اليدوي)

| الطبقة | الجداول | لماذا هذا الترتيب |
|---|---|---|
| **0 — الهوية الأساسية** | `users`, `accounts`, `sessions`, `verification_tokens` | لا تعتمد على أي شيء؛ **موجودة بالفعل من مرحلة الأساس (Phase 1)** إن كان هذا ترحيلاً على قاعدة بيانات قائمة، أو أول ما يُنشأ إن كانت البداية من الصفر. كل شيء آخر تقريبًا يعتمد على `users` بشكل مباشر أو غير مباشر. |
| **1 — الجذور المستقلة** | `languages`, `locale_groups`, `countries`, `qurans`, `roots`, `images`, `attachments`, `system_settings`, `feature_flags`, `background_job_logs`, `search_index_queue`, `ai_citation_logs`, `security_event_logs` | لا تملك أي مفتاح أجنبي إلزامي على الإطلاق. تُنشأ مبكرًا لأن جداولاً كثيرة لاحقة (كل الجداول القابلة للترجمة) تعتمد على `languages`/`locale_groups` تحديدًا. |
| **2 — الاعتماد المباشر الأول** | `surahs`, `cities`, `topics`, `tags`, `narrators`, `authors`, `translators`, `reviewers`, `videos`, `audios` | تعتمد فقط على الطبقتين 0-1. `topics` تحديدًا حرِجة هنا لأن `scholars` (الطبقة التالية) يعتمد عليها إلزاميًا (`specializationTopicId`). |
| **3 — طبقة الأشخاص والأماكن الأساسية** | `verses`, `words`, `mosques`, `islamic_centers`, `translator_languages`, `categories`, `scholars` | `scholars` هنا تحديدًا لأنه يحتاج `topics` (الطبقة 2) موجودًا فعلاً؛ هذا هو **بالضبط سبب "أسلوب البناء التدريجي"** الموثَّق في `PRISMA_IMPLEMENTATION_REPORT.md §5` أثناء كتابة Schema — نفس منطق الاعتماد ينعكس هنا في ترتيب الترحيل الفعلي. |
| **4 — المحتوى المرجعي والمؤسسي** | `hadith_collections`, `books`, `courses`, `fatwas`, `event_scholars`... | `hadith_collections` يحتاج `scholars` (الطبقة 3)؛ `books`/`courses`/`fatwas` تحتاج `scholars`/`topics`/`users` الموجودين فعلاً بهذه المرحلة. |
| **5 — المحتوى التفصيلي طبقة أولى** | `hadiths`, `articles`, `tafsirs`, `recitations`, `mosque_center_affiliations`, `scholar_center_affiliations` | `hadiths` يحتاج `books`+`hadith_collections` (الطبقة 4)؛ `articles` يحتاج `categories`(3)+`books`ليس مطلوبًا لكن `authors/scholars`(2-3). |
| **6 — العلاقات التفصيلية والإسناد** | `hadith_narrators`, `tafsir_verses`, `quran_translations`, `scholar_commentaries`, `citations` | جداول ربط تحتاج الجداول الأساسية للحديث/التفسير/القرآن مكتملة أولاً. |
| **7 — التعليم التفصيلي** | `lessons`, `quizzes`, `lesson_content_items`, `questions`, `answers` | تحتاج `courses` (الطبقة 4) موجودًا. |
| **8 — تفاعل المستخدم** | `enrollments`, `quiz_attempts` | تحتاج `courses`/`quizzes` (الطبقة 7) و`users` (الطبقة 0). |
| **9 — الفعاليات والتصنيف الأفقي** | `events`, `topic_assignments`, `tag_assignments`, `media_usages` | `events` يحتاج `islamic_centers` (الطبقة 3)؛ جداول التصنيف الأفقي تحتاج `topics`/`tags` موجودين وأي محتوى أُنشئ للإشارة إليه (مرجع متعدد الأنواع بلا FK صارم فعليًا، لكن منطقيًا تُنشأ بعد وجود محتوى فعلي ليُصنَّف). |
| **10 — التدقيق والإصدارات** | `audit_log_entries`, `content_versions`, `draft_revisions` | تشير إلى `users` فقط بشكل صريح (Polymorphic لبقية الحقول)؛ تُنشأ متأخرة منطقيًا لأنها تُسجِّل أفعالاً على محتوى يجب أن يكون النظام قادرًا على إنتاجه أولاً، لكن تقنيًا يمكن إنشاؤها في أي وقت بعد الطبقة 0. |

**ملاحظة ختامية على هذا القسم:** نظرًا لأن Prisma يُنشئ عادة **ملف ترحيل واحدًا شاملاً** لكل الـSchema عند أول `prisma migrate dev` (لا ملفًا منفصلاً لكل طبقة، إلا إذا اختير عمدًا تقسيم الترحيل — انظر §4)، فإن هذا التقسيم الطبقي غرضه الأساسي هو **المراجعة الهندسية والتخطيط للنشر التدريجي عبر البيئات (§4)**، لا تحديد أوامر تنفيذ منفصلة بالضرورة.

---

## 2. Seed Data Strategy — استراتيجية البيانات الأولية

### 2.1 توضيح حدود النطاق أولاً

**البذر (Seeding) ≠ استيراد المحتوى المرجعي الضخم.** بيانات مثل نص القرآن الكامل (6236 آية) أو متون الأحاديث هي عملية **استيراد بيانات (Data Import / ETL)** منفصلة تمامًا، بحجم وتعقيد مختلفين جوهريًا، وتخرج عن نطاق "البذر" التقليدي (بيانات تشغيلية صغيرة وثابتة). هذا القسم يغطي **البذر التشغيلي فقط** — البيانات الصغيرة اللازمة لتشغيل النظام يوم واحد، لا محتواه الفعلي.

### 2.2 توضيح مهم: "حالات المحتوى" ليست بيانات تُبذَر

الأدوار (`Role`) وحالات دورة الحياة (`ContentStatus`, `ReferenceStatus`, `MediaStatus`, `OperationalStatus`, `VerificationStatus`, `TaxonomyStatus`) **مُنفَّذة كـPrisma Enums مضمَّنة في بنية Schema نفسها**، لا كجداول بيانات مرجعية (Lookup Tables) منفصلة — قرار مُتَّخذ في `Phase 4`. هذا يعني: **لا حاجة لبذر أي صف بيانات لها إطلاقًا** — قيمها متاحة فور تطبيق الـMigration لأنها جزء من نوع العمود نفسه على مستوى قاعدة البيانات، لا سجلات. الإشارة إليها في تعليمات هذه المرحلة كـ"بيانات يجب إنشاؤها" تُفهَم هنا كطلب **للتحقق من توفرها فور الترحيل**، لا بذرها فعليًا — وهي متوفرة تلقائيًا.

### 2.3 البيانات التي تحتاج بذرًا فعليًا

| البيانات | المصدر/القيمة | لماذا ضرورية فور أول Migration |
|---|---|---|
| **اللغتان الأساسيتان** (`languages`) | `ar` (العربية، RTL، نشطة) و`en` (الإنجليزية، LTR، نشطة) | مطابقة للغتين المفعَّلتين فعليًا في طبقة الأساس (`next-intl`، `locales/ar`, `locales/en`) — بدونهما، أي محتوى قابل للترجمة يفشل في إنشاء أول سجل (قيد `language` إلزامي مع FK حقيقي إلى `languages.isoCode`). |
| **رواية القرآن الافتراضية** (`qurans`) | سجل واحد: `riwayah = HAFS_ASIM`, `isDefault = true` | مطلوب كجذر قبل أي استيراد لاحق لسور/آيات (عملية استيراد منفصلة، §2.1) — بدونه لا يوجد أب لأي `Surah` مستقبلي. |
| **مستخدم إداري أولي** (`users`) | حساب `ADMIN` واحد (نفس النمط المُهيَّأ مسبقًا في `prisma/seed.ts` من طبقة الأساس) | ضروري كأول `createdBy`/`approvedBy` ممكن لأي بيانات بذر أخرى تتطلب هذه الأعمدة الإلزامية، ولإتاحة أول دخول إداري فعلي للنظام. |
| **إعدادات النظام الأساسية** (`system_settings`) | مفاتيح مثل اسم المنصة، البريد الإداري للتواصل، الحد الأقصى لحجم الرفع | قيم تشغيلية يحتاجها التطبيق فور الإقلاع، لا معنى لتركها فارغة حتى أول استخدام. |
| **أعلام الميزات الافتراضية** (`feature_flags`) | كل الأعلام المعروفة مسبقًا، معطَّلة (`isEnabled = false`) افتراضيًا | يضمن أن أي كود يتحقق من علم ميزة لاحقًا يجد سجلاً موجودًا (حتى لو معطَّلاً) بدل التعامل مع غياب السجل كحالة خاصة إضافية في الكود. |
| **تصنيف رئيسي جذري واحد على الأقل** (`categories`) | سجل مؤقت "غير مصنَّف" (Uncategorized) بلغتيه العربية والإنجليزية | شبكة أمان فقط — يضمن وجود قيمة `categoryId` صالحة قبل اكتمال تصميم شجرة التصنيف الكاملة الفعلية (التي هي قرار تحريري/محتوى، لا بذر تقني). |

### 2.4 ما لا يُبذَر عمدًا

- **شجرة `categories`/`topics`/`tags` الكاملة**: قرار تحريري يخص هيئة الإشراف الشرعي (`Content Models §3`)، لا بذرًا تقنيًا آليًا.
- **أي `Scholar`/`Author`/`Translator` فعلي**: بيانات محتوى حقيقية تُدخَل عبر واجهة الإدارة لاحقًا، لا بذرًا.
- **نص القرآن/الحديث**: عملية استيراد منفصلة (§2.1).

---

## 3. Rollback Strategy — استراتيجية التراجع

### 3.1 المبدأ الحاكم: لا تعديل على Migration مُطبَّق فعليًا

بمجرد تطبيق ملف Migration بنجاح على أي بيئة (خصوصًا Production)، **لا يُعدَّل ذلك الملف أبدًا** — أي تصحيح لاحق يكون عبر Migration **جديد** يُلغي أو يعدِّل التغيير السابق (Forward-Only Migration Philosophy)، لا عبر تحرير التاريخ. هذا يطابق مبدأ `Versioning`/`Audit Trail` المعتمَد في الطبقة التطبيقية نفسها — نفس الفلسفة تُطبَّق على مستوى بنية قاعدة البيانات ذاتها.

### 3.2 آليتان مختلفتان حسب مرحلة الاكتشاف

| الحالة | الآلية |
|---|---|
| **فشل الـMigration أثناء التطبيق نفسه** (قبل اكتماله) | `prisma migrate` يُنفَّذ داخل معاملة قاعدة بيانات (Transaction) حيثما يدعم المحرك ذلك في PostgreSQL — فشل أي جزء يعني تراجعًا تلقائيًا كاملاً (Automatic Rollback) لتلك المعاملة، فلا تُترَك قاعدة البيانات في حالة وسيطة فاسدة. |
| **اكتشاف مشكلة بعد نجاح التطبيق** (مثل خطأ منطقي في القيد أو الفهرس) | **Migration تصحيحي جديد** يُنشأ ويُطبَّق (`ALTER TABLE`/`DROP CONSTRAINT`/إلخ حسب الحاجة) — لا `prisma migrate reset` على بيئة تحتوي بيانات حقيقية أبدًا (يمحو البيانات بالكامل). `migrate reset` مقبول فقط في `Development` (§4). |

### 3.3 التعامل مع فشل الترحيل عند وجود بيانات

- **قبل أي Migration على بيئة فيها بيانات حقيقية (Staging/Production)**: نسخة احتياطية إلزامية أولاً (§5) — **هي آلية التراجع الحقيقية والوحيدة الموثوقة 100%** عند فشل جسيم، لا الاعتماد فقط على تراجع المعاملة.
- **Migrations التي تُغيِّر بنية عمود بطريقة "مدمِّرة" (Destructive)** — مثل حذف عمود، تضييق نوع بيانات، أو إضافة قيد `NOT NULL` على عمود له بيانات فارغة موجودة فعلاً — تخضع لقاعدة إضافية: **تُقسَّم دائمًا إلى مرحلتين منفصلتين** (Expand-and-Contract Pattern): مرحلة "توسيع" غير مدمِّرة أولاً (إضافة العمود الجديد بجانب القديم، أو جعله اختياريًا مؤقتًا)، ثم بعد تأكيد نجاح انتقال البيانات وتحديث كود التطبيق، مرحلة "تضييق" لاحقة (حذف العمود القديم فعليًا). هذا يمنح نافذة تراجع آمنة بين المرحلتين لا تتوفر في تغيير مدمِّر مباشر بخطوة واحدة.
- **عدم توفر Downtime مقبول لعملية تراجع طويلة**: يُخطَّط له مسبقًا ضمن نافذة الصيانة (§6)، لا يُكتشَف أثناء الحادثة.

---

## 4. Environment Strategy — استراتيجية البيئات

| البيئة | آلية التنفيذ | الخصائص |
|---|---|---|
| **Development** | `prisma migrate dev` مباشرة على قاعدة بيانات محلية لكل مطوِّر | يُسمح باستخدام `prisma migrate reset` بحرية (يمحو ويعيد البناء من الصفر) لأن البيانات محلية تجريبية بحتة؛ توليد ملفات Migration الفعلية يبدأ من هنا (أول من يُنشئ ملف `migration.sql` هو مطوِّر يعمل محليًا، لا بيئة مشتركة). |
| **Staging** | `prisma migrate deploy` (لا `dev`) — يطبِّق ملفات Migration الموجودة فعلاً دون توليد جديدة أو تفاعل يدوي | بيانات شبه واقعية (نسخة مُنقَّحة/مموَّهة من إنتاج سابق أو بيانات اختبار واقعية الحجم) — أول بيئة تُختبَر فيها كل استراتيجية هذه الوثيقة (البذر، التراجع، النسخ الاحتياطي) **قبل** الاقتراب من Production. أي Migration مرفوض إن فشل هنا. |
| **Production** | `prisma migrate deploy` حصرًا، **أبدًا `migrate dev`** | تُنفَّذ فقط بعد نجاح كامل في Staging + استيفاء `Deployment Checklist` (§6) بالكامل + نسخة احتياطية مؤكَّدة (§5). تُنفَّذ ضمن نافذة صيانة معلَنة عند وجود أي تغيير مصنَّف "مدمِّر" (§3.3)، ويُفضَّل التنفيذ في أوقات الحركة المنخفضة حتى للتغييرات غير المدمِّرة، تقليلاً للمخاطرة العامة. |

**قاعدة صارمة عابرة للبيئات الثلاث:** ملفات الـMigration **نفسها بالحرف الواحد** تنتقل من Development → Staging → Production دون أي تعديل يدوي بينها — أي تعديل يدوي على ملف Migration بعد توليده في Development يُبطل الغرض الكامل من اختباره في Staging أولاً.

---

## 5. Backup Strategy — استراتيجية النسخ الاحتياطي

### 5.1 التوقيت

نسخة احتياطية كاملة **إلزامية** فورًا **قبل** تنفيذ أي `prisma migrate deploy` على Staging أو Production — لا استثناء، حتى للتغييرات "البسيطة ظاهريًا" (إضافة عمود اختياري مثلاً)، لأن كلفة النسخة الاحتياطية دائمًا أقل بكثير من كلفة فقدان بيانات غير متوقَّع.

### 5.2 الآلية

يُعتمَد على قدرة الاستعادة إلى نقطة زمنية محدَّدة (Point-in-Time Recovery عبر أرشفة WAL) الموثَّقة مسبقًا كخط أساس في `ENTERPRISE_DATABASE_ARCHITECTURE.md §11` — **بالإضافة** إلى نسخة كاملة صريحة يدويًا/آليًا مباشرة قبل كل عملية Migration تحديدًا (لا الاعتماد فقط على النسخ الدورية المجدولة، التي قد يفصلها ساعات عن لحظة الترحيل الفعلية).

### 5.3 التحقق من نجاح النسخة الاحتياطية (خطوة لا تُختصَر أبدًا)

مجرد "اكتمال" أمر النسخ الاحتياطي بلا خطأ **لا يكفي دليلاً على صلاحيتها**. قبل المتابعة لتنفيذ أي Migration:

1. **التحقق من الحجم**: حجم ملف/لقطة النسخة الاحتياطية منطقي مقارنة بالحجم المتوقَّع لقاعدة البيانات (فرق كبير غير مفسَّر = إنذار).
2. **اختبار استعادة فعلي دوري** (لا فقط عند الحاجة): استعادة النسخة الاحتياطية إلى بيئة معزولة مؤقتة والتحقق من إمكانية الاتصال بها وقراءة عينة من الجداول الأساسية بنجاح — سياسة موصى بها بشكل صريح ومتكرر (لا لمرة واحدة).
3. **توثيق زمن الاستعادة الفعلي (RTO الفعلي المُقاس)**: قياس المدة الفعلية لاستعادة نسخة حقيقية، لا افتراضها نظريًا فقط — يُستخدَم لتخطيط طول نافذة الصيانة (§6).

---

## 6. Deployment Checklist — قائمة التحقق قبل أي Migration في الإنتاج

- [ ] الـMigration نجح بالكامل ومن أول محاولة على بيئة **Staging** مطابقة قدر الإمكان لبيانات وحجم Production.
- [ ] نسخة احتياطية كاملة لقاعدة بيانات Production أُخذت **والتُحقِّق من صلاحيتها فعليًا** (§5.3)، لا افتراض نجاحها فقط.
- [ ] تصنيف التغيير محدَّد بوضوح: **غير مدمِّر (Non-destructive)** أم **مدمِّر (Destructive)** — وإن كان مدمِّرًا، تم تطبيق نمط "التوسيع ثم التضييق" (§3.3) لا خطوة واحدة مباشرة.
- [ ] كود طبقة التطبيق (`services/`, `lib/`) المعتمِد على أي عمود/جدول جديد **مُنشور ومفعَّل بالفعل** أو **متوافق رجعيًا (Backward-Compatible)** مع البنية الجديدة والقديمة معًا خلال فترة الانتقال — لا نشر Migration يسبق نشر الكود المعتمِد عليه دون خطة توافق واضحة.
- [ ] نافذة صيانة معلَنة مسبقًا للمستخدمين إن كان التغيير مدمِّرًا أو متوقَّع أن يستغرق وقتًا يفوق العتبة المقبولة لقفل الجداول (Table Lock) في Postgres.
- [ ] خطة تراجع فورية موثَّقة وجاهزة **قبل** بدء التنفيذ، لا التفكير فيها بعد وقوع مشكلة.
- [ ] شخص مسؤول (أو أكثر) متابع فعليًا أثناء التنفيذ الفعلي (لا تنفيذ Migration مدمِّر ثم مغادرة الشاشة)، خصوصًا لأول تطبيق فعلي لهذه الاستراتيجية على بيانات حقيقية.
- [ ] مراقبة (Monitoring) الأداء والأخطاء مفعَّلة ومتابَعة لفترة كافية بعد التنفيذ مباشرة (ليس فقط لحظة اكتمال أمر الـMigration نفسه)، للكشف عن أي تدهور أداء غير متوقَّع ناتج عن فهرس جديد أو قيد إضافي.

---

## 7. Risk Assessment — تقييم المخاطر

| # | الخطر | الاحتمالية | التأثير | خطة التخفيف |
|---|---|---|---|---|
| 1 | فشل Migration جزئيًا في منتصف التنفيذ على Production | منخفضة (Postgres يدعم معاملات DDL) | مرتفع إن حدث | الاعتماد على التراجع التلقائي للمعاملة (§3.2) + نسخة احتياطية كخط دفاع ثانٍ مؤكَّد الصلاحية (§5.3). |
| 2 | Migration يقفل جدولاً كبيرًا لفترة طويلة (Table Lock) ويؤثر على توفّر الخدمة | متوسطة، خصوصًا لجداول لاحقًا كبيرة الحجم مثل `verses`/`audit_log_entries` | مرتفع (تعطيل مؤقت للمستخدمين) | تفضيل نمط "التوسيع ثم التضييق" (§3.3)، تنفيذ في أوقات حركة منخفضة، قياس زمن القفل المتوقَّع على نسخة بحجم واقعي في Staging أولاً. |
| 3 | نسخة احتياطية "تبدو" ناجحة لكنها فعليًا غير قابلة للاستعادة | منخفضة إن اتُّبعت §5.3 بانضباط، **مرتفعة** إن أُهمِل اختبار الاستعادة الدوري | كارثي (فقدان بيانات لا رجعة فيه) | تنفيذ صارم لسياسة اختبار الاستعادة الدوري الفعلي، لا مجرد التحقق من اكتمال أمر النسخ. |
| 4 | تعارض إصدار Prisma/محرك قاعدة البيانات بين بيئات مختلفة (Dev بإصدار، Production بآخر) | منخفضة إن التُزم بتثبيت الإصدار (`Prisma 6.19.3` موثَّق مسبقًا في `PROJECT_STATUS.md`) | متوسط إلى مرتفع (سلوك غير متسق أو فشل صامت) | تثبيت صارم لإصدار Prisma عبر `package.json`/`package-lock.json` في كل البيئات، والتحقق من تطابق إصدار PostgreSQL نفسه بين Staging وProduction. |
| 5 | نشر Migration يعتمد عليه كود تطبيق لم يُنشَر بعد (أو العكس) | متوسطة في أي نشر متعدد الخطوات | متوسط إلى مرتفع (أخطاء تشغيلية فورية بعد النشر) | ترتيب نشر صارم (Migration ثم الكود، أو كود متوافق مع كلا البنيتين مؤقتًا) — موثَّق كبند إلزامي في §6. |
| 6 | القيود التي لا يدعمها Prisma أصيلاً (CHECK، مراجع متعددة الأنواع — موثَّقة في `PRISMA_IMPLEMENTATION_REPORT.md §2`) تُنسى ولا تُضاف يدويًا لاحقًا | متوسطة (تعتمد على انضباط الفريق) | متوسط (بيانات غير متسقة تدريجيًا دون رفض فوري من قاعدة البيانات) | تتبّع صريح لكل قيد مؤجَّل (نفس القائمة الموثَّقة في التقرير) كبند مستقل في خطة تنفيذ الـMigration الأولى، لا تركه "للذاكرة". |
| 7 | بذر بيانات غير متسق أو مكرَّر عند إعادة تشغيل سكربت البذر بالخطأ أكثر من مرة | متوسطة | منخفض إلى متوسط (بيانات مكرَّرة، لا فقدان) | سكربت البذر (عند كتابته لاحقًا، خارج نطاق هذه الوثيقة) يجب أن يكون **مثاليًا للتكرار (Idempotent)** — يتحقق من عدم وجود السجل قبل إنشائه، لا إنشاء متكرر أعمى. مبدأ مُسجَّل هنا مسبقًا ليُطبَّق عند كتابة السكربت الفعلي. |

---

## 8. Success Criteria — شروط اعتماد أي Migration

Migration واحد لا يُعتبَر "مكتملاً وجاهزًا للاعتماد النهائي" إلا بتحقق كل الشروط التالية معًا:

1. **نجاح تقني كامل بلا أخطاء** على Development ثم Staging بالترتيب، بنفس ملف الـMigration الحرفي (§4).
2. **نسخة احتياطية مؤكَّدة الصلاحية** قبل أي تطبيق على بيانات حقيقية (§5.3) — لا نجاح الأمر وحده.
3. **تطابق 64/64 جدولاً** بين البنية الفعلية بعد الترحيل و`DATABASE_LOGICAL_DESIGN.md`/`prisma/schema.prisma` — أي فرق يعني فشل الترحيل بغض النظر عن غياب رسالة خطأ ظاهرة.
4. **صفر فقدان بيانات غير مقصود** — عبر مقارنة عدد الصفوف قبل/بعد لكل جدول موجود مسبقًا (ذو صلة خصوصًا لتغييرات "التضييق" في نمط §3.3).
5. **أداء الاستعلامات الحرِجة ضمن الحدود المقبولة** بعد الترحيل مباشرة (لا تدهور غير مفسَّر ناتج عن فهرس ناقص أو قيد جديد مكلف).
6. **البذر التشغيلي (§2.3) مكتمل ومتحقَّق منه** فور أول Migration تحديدًا (لا Migrations لاحقة) — النظام غير قابل للاستخدام الوظيفي الأساسي بدونه.
7. **قائمة التحقق الكاملة في §6 مُستوفاة وموثَّقة** (لا شفهيًا) قبل اعتبار أي Migration جاهزًا لبيئة Production تحديدًا.
8. **موافقة صريحة منفصلة من مالك المشروع** على تنفيذ الترحيل الفعلي على Production — بما يتفق تمامًا مع نمط الموافقات المرحلية المعتمَد طوال هذا المشروع.

---

## الخلاصة

هذه الوثيقة تخطيط بحت — **لم يُنشأ أي ملف Migration، لم يُشغَّل `prisma migrate`، لم يُكتب أي SQL، ولم يُنشأ أي Seed Script فعلي**، تمامًا كما طُلب. المرحلة التالية المُعلَنة (Database Migrations الفعلية → Seed Data → Repository Layer → Service Layer → Authentication & Authorization → REST/GraphQL APIs → Admin CMS → Frontend) **لن تبدأ إلا بموافقة صريحة منفصلة** على هذه الوثيقة تحديدًا.
