Control Panel Specifications
Status Workflow
draft → ready-for-review → under-review → published. Off-ramps and audit log per transition.
مكتمل
كل Founder File يمشي في دورة حياة من 6 حالات. الانتقالات مفروضة على السيرفر، مسجَّلة في التدقيق، وتظهر في الـ CP كشارات مرمَّزة بالألوان + أزرار إجراءات. Form preview أسفل الصفحة يعرض شريط الحالة + الإجراءات اللي يظهر على كل شاشة Edit.
الـ 6 حالات
draft (الافتراضي عند الإنشاء)
- الغرض — الحالة الأولية. المحرّر بيبني محتوى الملف عبر ساعات / أيام. لا يظهر علناً. لا قيود على الحقول الناقصة — الأدمن يقدر يحفظ صفوف نصّ مكتملة.
- نوع DB — `Status = 'draft'`. يُضبط بالـ INSERT default عند Create. يُعاد ضبطه بـ Restore-from-archive وبـ Withdraw-from-review.
- التحقّق — الإجراءات المسموحة: تعديل أي حقل، Archive (حذف ناعم)، Submit للمراجعة (فقط لمّا تمرّ بوّابة الاكتمال الثلاثية). اختبار QC: حاول Submit على ملف نصّ مكتمل → السيرفر يرجع HTTP 422 يدرج الحقول الناقصة لكل لغة.
ready-for-review (انتقالية)
- الغرض — علامة إن المحرّر خلّص والمراجِع لازم يلتقط الملف. تعيش بين Submit (من المحرّر) و Pickup (من المراجِع). عادة بضع دقائق فقط — ready-for-review طويلة المدى = مشكلة في process الفريق.
- نوع DB — `Status = 'ready-for-review'`. يُضبط لمّا البوّابة الثلاثية تنجح عند Submit. يُمسح لحظة فتح المراجِع للملف (يُضبط لـ `under-review`).
- التحقّق — الإجراءات المسموحة: تعديل (يعود تلقائياً لـ draft)، Pickup-for-review (يعمل تلقائياً عند فتح المراجِع الأول). اختبار QC: المحرّر يرسل → الحالة تظهر `ready-for-review`؛ محرّر تاني يفتحه ويعدّل → الحالة ترجع لـ `draft` والمرسِل الأصلي يشوف toast.
under-review (مقفول)
- الغرض — مراجِع عنده صلاحية `files.publish` ماسك الملف. الملف للقراءة فقط للجميع ما عدا هذا المراجِع (و Editorial Lead). المراجِع يقرأ المحتوى، يفحص الـ PDFs، يوافق أو يرفض.
- نوع DB — `Status = 'under-review'`. المراجِع يُتتبَّع منفصل في `FounderFileAuditLog` (eventType='review-picked-up', actorId=reviewer). لا عمود مراجِع على الملف نفسه — مراجِعون متعدّدون يقدروا يتبادلوا.
- التحقّق — إجراءات المراجِع: Approve (→ published)، Reject (→ needs-updates بتعليق إلزامي ≥ 20 حرف)، Withdraw (→ draft، بدون تعليق). اختبارات QC: حاول Approve بدون صلاحية `files.publish` → HTTP 403؛ حاول Reject بتعليق فاضي → HTTP 422؛ أثناء under-review، أي مستخدم غير المراجِع يحاول التعديل يحصل على HTTP 409 بـ "File is locked under review".
published (عام)
- الغرض — الملف حيّ على الموقع العام. أي حد يقدر يحمّله (مع مراعاة بوّابة الموافقة). دي الحالة الوحيدة الظاهرة على routes `/founder-files/*`.
- نوع DB — `Status = 'published'`. الـ UPDATE كمان يختم `PublishedAt = GETUTCDATE()` فقط لو ده أول نشر (PublishedAt السابق كان NULL).
- التحقّق — الإجراءات المسموحة: تعديل أي حقل قابل للتعديل (يبدّل تلقائياً لـ `needs-updates`، انظر Update)، Archive. لا يوجد مسار edit-and-stay-published. اختبار QC: غيّر Title على ملف منشور → شارة Status تعكس فوراً `needs-updates` والصفحة العامة ترجع 410 خلال 30 ثانية.
needs-updates (مرفوض أو مُبدَّل تلقائياً)
- الغرض — مساران يوصلان هنا: (1) المراجِع يرفض بتعليقات، (2) تبديل تلقائي من `published` لمّا حقل قابل للتعديل يتغيّر. المحرّر يقرأ التعليق (أو يعرف هو غيّر إيه)، يصلح، ويعيد الإرسال.
- نوع DB — `Status = 'needs-updates'`. PublishedAt يبقى كما هو. LastUpdatedAt يقفز للوقت الحالي UTC مع كل حفظ في هذه الحالة.
- التحقّق — مسموح: تعديل أي حقل، Archive، Submit للمراجعة (مع مراعاة البوّابة الثلاثية). اختبارات QC: تعليق رفض المراجِع لازم يظهر كبانر أصفر أعلى شاشة Edit؛ البانر يُغلق فقط بعد Submit، مش قبله.
archived (محذوف ناعم)
- الغرض — الحالة النهائية للحذف الناعم. الملف مخفي علناً، لا تعديلات، نافذة Restore لمدة 90 يوم. شوف Archive spec المخصّص للدورة الكاملة.
- نوع DB — `Status = 'archived'`، `ArchivedAt = GETUTCDATE()`، `ArchivedBy = @adminId`. لا DELETE.
- التحقّق — مسموح: Restore (فقط خلال 90 يوم). كل endpoints التعديل ترجع HTTP 410 Gone بـ `code: FILE_ARCHIVED`. اختبار QC: استعمل `PATCH /admin/founder-files/{slug}` على ملف مؤرشف → توقّع 410 + تاريخ آخر يوم للاستعادة.
مصفوفة الانتقالات
إلى الأمام (التدفّق الطبيعي)
- draft → ready-for-review (المحرّر يضغط Submit)
- ready-for-review → under-review (المراجِع يلتقط)
- under-review → published (المراجِع يوافق)
- needs-updates → ready-for-review (المحرّر يعيد الإرسال بعد الإصلاح)
للخلف / جانبي
- ready-for-review → draft (المحرّر يعدّل أو يسحب)
- under-review → draft (المراجِع يسحب)
- under-review → needs-updates (المراجِع يرفض)
- published → needs-updates (تلقائي عند تغيير أي حقل قابل للتعديل)
- draft / needs-updates / published → archived (الأدمن يضغط Archive)
- archived → draft (الأدمن يستعيد، فقط خلال 90 يوم)
معاينة الفورم — شريط الحالة + أزرار الإجراءات (تختلف لكل حالة)
شريط الحالة يعيش أعلى كل شاشة Edit. الأزرار تتغيّر حسب الـ Status الحالي. أدناه: الأربع حالات الأكثر شيوعاً اللي المراجِع يشوفها.
