Harden published curriculum and student flows

This commit is contained in:
Hamza-Ayed
2026-09-30 08:22:17 +03:00
parent e8163fe265
commit ce7b0fcf14
53 changed files with 4723 additions and 3317 deletions
+133 -20
View File
@@ -2,7 +2,7 @@
# 📋 دفتر متابعة وتنفيذ مهام منصة صَقِل — السجل المعماري الحي
تاريخ التحديث الأخير: **16 أيلول 2026**
تاريخ التحديث الأخير: **23 أيلول 2026**
المرجع الأساسي: `docs/NEXT_PHASE_MASTER_SPEC.md` و `docs/NEXT_PHASE_EXECUTION_BACKLOG.md` و `AGENTS.md`
الهدف: هذا الدفتر هو المرجع التوثيقي والتنفيذي المباشر لجميع محاور ومنعطفات منصة صَقِل، يوضح بدقة متناهية **ما تم إنجازه فعلياً في الكود**، و**شو تبقى من كل نقطة**، مع معايير القبول وشروط الانتقال للمرحلة التالية.
@@ -13,18 +13,18 @@
| المعرّف | المحور / المهمة | النطاق والمستوى | الحالة الحالية | ما تم إنجازه في الكود | شو تبقى لإتمامه بدقة |
|---|---|---|---|---|---|
| **NP-00** | بيئة الاختبار وخط الأساس الآمن | البنية التحتية / P0 | `implemented_unverified` | منع Runtime DDL، فحص syntax لكل PHP، سكربت `run_migrations.php` مع مطابقة Checksum | تجهيز بيئة staging معزولة، تشغيل suite تكامل متصل بـ MySQL و Redis |
| **NP-01** | إيقاف النجاح والمحتوى المصطنع | الأمان والمصداقية / P0 | `verified_in_code` | تعطيل الاعتماد التلقائي لكليك، تعطيل سحب الأرباح التقديري، إزالة التوليد في GET، رد صريح بـ `unavailable` | جرد تنظيف الجداول من أي بيانات demo قديمة بعد المطابقة اليدوية |
| **NP-02** | الهوية المنهجية وحزم الأصول | المناهج والمحتوى / P0 | `in_progress` | 13 مبحثاً (392 درس ماركداون + 371 مواصفة مختبر)، جداول `curriculum_lessons` و `content_assets` | مراجعة واعتماد أول حزمة نشر (Bundle) رسمية لـ 12 درساً نموذجياً وربط الـ PDF الرسمي |
| **NP-03** | حصة المعلم والاستبدال الذري | استوديو المعلم / P1 | `verified_in_code` | `TeacherSubmissionService` مع Preflight و Idempotency-Key وقفل المعاملات، وربط التحقق في `TeacherStudioCubit` وراية التنبيه بالنسخة المرشحة في الواجهة | اختبارات E2E لرفع الفيديو الفعلي ومطابقة الصوت |
| **NP-04** | تدقيق الفيديو والأسئلة السقراطية | الجودة الأكاديمية / P0 | `in_progress` | مشغل قراءة صارم، إيقاف التوليد في GET، فحص Checkpoints المنشورة فقط، عقد البرومبتات | ربط الـ Worker بتفريغ صوتي حقيقي وأدلة مرئية كاملة للحصص المنشورة |
| **NP-05** | اختيار المعلم (0 / 1 / متعدد) | تجربة الطالب / P1 | `implemented_unverified` | `TeacherSelectionSheet` بالفرز التنازلي للتقييم، تشغيل الـ UUID المختار، كشف المعلم المصرح فقط | ربط شجرة المنهج في التطبيق بهوية الدرس المنشور بعد تفعيل الـ Bundles |
| **NP-06** | دفتر الحسابات وحجز الرصيد | المحاسبة المالية / P0 | `implemented_unverified` | `TeacherLedgerService` بوحدة الفلس، قيود القيد المزدوج، حجز السحب الذري بـ Idempotency | تسوية الرصيد الافتتاحي وتدقيق الصلاحيات متعدية الحسابات لمنع IDOR |
| **NP-01** | إيقاف النجاح والمحتوى المصطنع | الأمان والمصداقية / P0 | `in_progress` | تعطيل الاعتماد التلقائي لكليك، تعطيل سحب الأرباح التقديري، إزالة التوليد في GET ومسار الدرس الخام | جرد بقايا الفروع وبيانات demo القديمة، واختبار فشل الخادم/المحتوى عبر التطبيقات |
| **NP-02** | الهوية المنهجية وحزم الأصول | المناهج والمحتوى / P0 | `in_progress` | ملفات المنهج وجداول الأصول؛ بوابة النشر تشترط مراجعة وحقوقاً؛ شجرة الطالب ترشح المنشور فقط وتفصل فهرس تحضير المعلم | مراجعة واعتماد 12 درساً فعلياً، رفع PDF، وتشغيل بوابة النشر على staging واختبار المسارين |
| **NP-03** | حصة المعلم والاستبدال الذري | استوديو المعلم / P1 | `implemented_unverified` | Preflight ونسخة مرشحة؛ أُصلح بقاء النسخة القديمة منشورة أثناء الرفع، وربط إنشاء job بمعاملة الرفع | اختبار تزامن ورفع/استبدال E2E، والتحقق من كل مسارات النشر |
| **NP-04** | تدقيق الفيديو والأسئلة السقراطية | الجودة الأكاديمية / P0 | `in_progress` | أُغلق النشر الإداري المباشر؛ فحص تغطية زمنية كاملة وربط hashes قبل الاعتماد والنشر | ربط Worker بتفريغ ودليل بصري فعليين، مراجعة بشرية، واختبارات تكامل وإصدارات متزامنة |
| **NP-05** | اختيار المعلم (0 / 1 / متعدد) | تجربة الطالب / P1 | `implemented_unverified` | ترتيب خادمي مستقر، عدّ مرشّح بالصلاحية، دفعات 20 مع «عرض المزيد»، وتشغيل UUID المختار | اختبار MySQL/HTTP بحالات 0/1/2/100+ ومدرستين ونسخ بديلة؛ قياس تكلفة التصفح |
| **NP-06** | دفتر الحسابات وحجز الرصيد | المحاسبة المالية / P0 | `implemented_unverified` | جداول قيد مزدوج بالفلس، حجز بمفتاح إعادة وقفل صف المعلم، وقراءة رصيد بلا كتابة | اختبار تزامن MySQL فعلي، تسوية افتتاحية، تدقيق IDOR وبناء دورة التحويل/العكس المثبتة |
| **NP-07** | قياس الدقائق المستحقة بالخادم | استحقاق المشاهدة / P1 | `implemented_unverified` | `WatchSessionService` مع فترات متصلة وحساب Server-side Delta ومقارنة زمن الخادم والعميل | اختبار الإجهاد وانقطاع الاتصال ومحاكاة التلاعب بسرعة المشغل |
| **NP-08** | توزيع الإيراد وكشف حساب المعلم | المالية والشفافية / P1 | `blocked_policy` | فصل أوعية الدخل (مدرسي / مستقل)، إيقاف افتراض أرباح من حجم المنصة ككل | **قرار تجاري معلق:** حسم سعر الدقيقة، ونسبة صندوق المعلمين، وفترة التسوية |
| **NP-09** | بوابة الدفع والبصمة والتحويل | الدفع المالي / P0 | `blocked_psp` | عزل مسارات كليك بوضع غير متاح بدلاً من المحاكاة الصورية والاحتيال | **تعاقد مصرفي معلق:** ربط PSP أردني معتمد، وبناء Webhooks موقعة، وبصمة الجهاز |
| **NP-10** | حزمة الإنجليزية والصوت الموحد | المناهج التفاعلية / P1 | `in_progress` | تطوير مختبر الإنجليزية، تنظيم ملفات الوحدات والقواعد، إزالة IPA التخميني | توفير ملفات الصوت البشري المعتمدة للمفردات والنصوص وربطها بروابط CDN |
| **NP-11** | إكمال حلقة التعلم ودفتر الأخطاء | التجربة التعليمية / P1 | `verified_in_code` | 18 مختبراً، نافذة التفكير، دورة التكرار المتباعد بمرحلتين (تثبيت + استرجاع 7 أيام) بالخادم والواجهة | ربط واجهات الواجبات المدرسية بنظام مهام وتكليفات المعلم |
| **NP-12** | المؤسسات والمديريات والإشراف | إدارة التعليم / P1 | `implemented_unverified` | لوحات SuperAdmin والمديريات بقراءة حقيقية، عزل أدوار الـ Middlewares، blind index | استيراد شعب المدارس الحكومية والخاصة واختبارات العزل التام بين المدارس |
| **NP-11** | إكمال حلقة التعلم ودفتر الأخطاء | التجربة التعليمية / P1 | `implemented_unverified` | 18 مختبراً وواجهة العلاج؛ أضيفت محاولة بأسئلة منشورة وتصحيح خادم وموعد استرجاع بعد 7 أيام | تطبيق migration واختبار تكامل وتزامن، مراجعة مصدر الأسئلة، ربط الواجبات والتذكير |
| **NP-12** | المؤسسات والمديريات والإشراف | إدارة التعليم / P1 | `in_progress` | لوحات تقرأ البيانات؛ أُزيل منح دورة مجانية لكل طالب مدرسي، وأضيف فحص مدرسة/كشف انتساب ودور تغيير الصف | استيراد كشوف مؤكدة، عقود صلاحية المباحث، اختبارات IDOR وMySQL/HTTP لمدرستين |
| **NP-13** | إثبات الصف العاشر والإطلاق | بوابة الإطلاق النهائي | `gate_pending` | جاهزية التطبيقات الأربعة، مسار التدريب المهني (VTC)، صفحة الهبوط الفاخرة | إجراء التجربة الحية على 12 درساً للصف العاشر مع عينة حقيقية من المعلمين والطلبة |
---
@@ -59,11 +59,14 @@
### [NP-02] الهوية المنهجية وحزم الملفات (Curriculum Identity & Bundles)
* **الهدف:** تمييز كل درس بهوية ثابتة (الصف، المبحث، الفصل، الوحدة، الدرس، النسخة)، وربط الأصول كحزم نشر موثوقة.
* **ما تم إنجازه في الكود:**
- 13 مبحثاً كاملاً للصف العاشر في `backend/storage/curriculum/grade_10` تضم 392 ملف ماركداون.
- 371 وثيقة مواصفات للمختبرات الافتراضية في `docs/virtual_labs/grade_10`.
- تطبيق جدول `curriculum_lessons` وجدول `content_assets` وجدول `publication_bundles`.
- فهرس الصف العاشر المحلي يحوي 392 ملف Markdown؛ العدد لا يثبت اكتمال المباحث أو صحة المحتوى أو الموافقة على نشره.
- يوجد 370 ملفاً في `docs/virtual_labs/grade_10` وفق جرد الملفات المحلي، ولا تعني مراجعة علمية.
- تعريف migrations لجداول `curriculum_lessons` و`content_assets` و`publication_bundles`؛ تطبيقها على staging/الإنتاج غير مثبت هنا.
- نقطة `GET /api/curriculum/assets/{assetId}` التي تخدم الأصول عبر UUID فقط دون تمرير مسارات ملفات من العميل.
- سكربت `publish_grade10_bundle.php` المخصص لنشر حزم الصف العاشر مع خيار `--pilot` للدروس الـ 12 النموذجية.
- بوابة `--pilot` تتحقق من 12 ملفات من نوع درس، وتمنع النشر عندما يغيب مراجع الدرس أو تاريخ مراجعته أو اعتماد الأصل أو تصفية حقوقه. السحب يحفظ قرار المراجعة وسجل الحقوق.
- الشجرة العامة للطالب لا تظهر إلا درساً له سجل منهجي معتمد وحزمة وأصل منشوران؛ فهرس تحضير المعلم منفصل خلف صلاحية الدور.
- الشجرة العامة ترسل UUID أصل Markdown الأساسي؛ قارئ الدرس يستعمله بدلاً من مسار ملف manifest أو UUID الدرس. مسارات `/api/curriculum/lesson` و`/api/curriculum/document` التي تقبل `file` صارت محصورة بأدوار إدارة المنهج.
* **شو تبقى منها بدقة:**
- [ ] مراجعة واعتماد الحزم المنشورة للدفعة الأولى ونقلها من حالة `draft` إلى `published`.
- [ ] رفع ملفات الـ PDF الرسمية للكتب وأوراق العمل وتخزينها في التخزين السيادي كأصول ذات Checksum.
@@ -80,6 +83,7 @@
- إضافة شريط التنبيه المرئي في واجهة الرفع `apps/teacher_app/lib/presentation/screens/tabs/teacher_studio_upload_tab.dart` لإعلام المعلم بصراحة: "نسخة مرشحة للاستبدال (إصدار X) — الحصة المنشورة الحالية تظل متاحة للطلاب حتى اجتياز الفحص".
* **شو تبقى منها بدقة:**
- [ ] اختبارات E2E لرفع الفيديو الفعلي ومطابقة الصوت الميداني.
- [ ] اختبار أن حصة المعلم القديمة تظل مرئية للطالب أثناء رفع ومراجعة البديلة، وأن فشل إنشاء job يرد الرفع إلى حالته السابقة ضمن المعاملة.
- [ ] إشعار المعلم اللحظي عند انتهاء التدقيق البشري للنسخة المرشحة.
---
@@ -99,10 +103,11 @@
### [NP-05] اختيار المعلم (0 / 1 / متعدد)
* **الهدف:** تطبيق منطق صَقِل: صفر حصص = إظهار الموارد المتاحة بصدق، حصة واحدة = تشغيل مباشر، أكثر من حصة = قائمة بالتقييم الموثق.
* **ما تم إنجازه في الكود:**
- واجهة `TeacherSelectionSheet` في تطبيق الطالب بفرز تنازلي للتقييم الحقيقي وعدد التقييمات وشارة التوثيق.
- نقطة `GET /api/curriculum/lessons/{lessonId}/videos` التي تعيد فقط النسخ المنشورة والمصرح بها للطالب.
- واجهة `TeacherSelectionSheet` تعرض ترتيب الخادم ولا تعيد فرزه، وتطلب صفحات إضافية عند الحاجة؛ أزيلت أوصاف أساليب المعلمين المختلقة. تعرض المدة وتاريخ النشر إن أرسلهما الخادم.
- نقطة `GET /api/curriculum/lessons/{lessonId}/videos` تمسح المرشحين على دفعات ثابتة بدلاً من قصّ أول 101 صف، وتعيد العدد والصفحة بعد فحص صلاحية الطالب؛ شرط `EXISTS` يمنع تكرار الحصة عند وجود عدة أصول/وظائف مراجعة.
* **شو تبقى منها بدقة:**
- [ ] ربط شجرة المنهج في واجهة الطالب (`subject_hub_screen.dart`) بالـ UUID المعتمد للحزم المنشورة عند توفرها.
- [ ] اختبار قائمة 0/1/2/100+، ترتيب التساوي، صلاحيات مدرستين، وتبدل التقييم أو سحب الحصة بين الصفحات على MySQL وواجهة حقيقية. العدّ صحيح داخل طلب واحد عند ثبات snapshot؛ لا يضمن offset ثبات الصفحات بين طلبين إذا تغير النشر أو التقييم.
---
@@ -110,11 +115,14 @@
* **الهدف:** نظام محاسبي صارم بوحدة الفلس (بدون فواصل عشرية عائمة)، وقيد مزدوج يمنع السحب المتجاوز للرصيد.
* **ما تم إنجازه في الكود:**
- خدمة `TeacherLedgerService` الداعمة لـ `balance` و `placeWithdrawalHold` و `releaseHold`.
- حجز السحب ذري (Atomic Transaction) يمنع طلبين متزامنين يتجاوزان الرصيد الفعلي.
- الحجز يقفل صف `teachers` للمعلم قبل قراءة الرصيد أو الحجز، ليُسلسل الطلبات المتزامنة لنفس المعلم؛ هذه آلية كود لم تُختبر بعد بتزامن MySQL فعلي. قراءة الرصيد لم تعد تنشئ حساباً عند غيابه، وحساب صافي القيود يستخدم أعداداً موقعة قبل الطرح.
- جداول `ledger_accounts` و `ledger_entries` و `teacher_withdrawal_holds`.
- migration `20260923_teacher_hold_release_reason.sql` تحفظ سبب تحرير الحجز في السجل، ولا تخترع سبباً لتحريرات سابقة.
* **شو تبقى منها بدقة:**
- [ ] تطبيق migration على staging قبل نشر الكاتب، ثم اختبار طلبَي حجز متزامنين وretry بمفتاح واحد وآخر مختلف، والتحرير المكرر، والرصيد السالب/الصفر، وفشل منتصف المعاملة.
- [ ] تسوية الأرصدة الافتتاحية السابقة ومطابقتها قبل تفعيل أي قيد حي.
- [ ] تدقيق أمان الـ IDOR للتأكد من عدم وصول أي معلم لدفتر معلم آخر.
- [ ] كل كاتب قيود/صرف مستقبلي يجب أن يلتزم بقفل صف المعلم ذاته قبل تغيير رصيده؛ الخدمة ليست موصولة بمسار دفع/سحب حي، ولا تثبت وحدها سلامة تحويل الأموال أو توازن كل قيد تاريخي.
---
@@ -169,12 +177,12 @@
* **ما تم إنجازه في الكود:**
- 18 مختبراً تفاعلياً مدمجاً ومفحوصاً باختبارات Smoke (12 لغة عربية + 6 فيزياء).
- نافذة التفكير الإلزامي `ScaffoldedThinkingPauseSheet` (60 ثانية) مع التدرج المعرفي خطوة بخطوة.
- تطبيق دورة التكرار المتباعد بمرحلتين (Two-Stage Spaced Repetition) في `ErrorNotebookController.php`:
- المرحلة الأولى (التدريب العلاجي الأولي): ينتقل الخطأ من `pending_remediation` إلى `in_remediation` وتتم جدولة اختبار الاسترجاع بعد 7 أيام (`retention_scheduled_at = NOW() + 7 DAYS`).
- المرحلة الثانية (تحدي الاسترجاع والتثبيت): عند اجتياز الطالب للاختبار بعد اكتمال الفترة ينتقل إلى `mastered` مع تسجيل تاريخ الإتقان الفعلي.
- أضيفت migration `20260923_error_notebook_verified_attempts.sql` لحفظ المحاولة وموعد `retention_due_at` وحقول مراجعة أسئلة العلاج. التصحيح يجري على الخادم بثلاثة أسئلة منشورة ومراجعة بشرياً من نفس الدرس والمفهوم، مع خيار صحيح واحد لكل سؤال، ومفتاح إجابة محفوظ للمحاولة لا يصل إلى التطبيق. اجتياز المرحلة الأولى يحدد موعد المراجعة بعد 7 أيام؛ اجتياز الثانية بعد الموعد ينقل الحالة إلى `mastered`.
- شاشة دفتر الأخطاء الذكي `SmartErrorNotebookScreen`: إضافة تبويبات التصفية بحسب الحالة (الكل، بانتظار المعالجة، قيد التثبيت 🌱، تم الإتقان ✨)، وصندوق إحصائي مستقل لقيد التثبيت، وزر خاص لبدء اختبار الاسترجاع والتثبيت المتباعد.
- منظومة ربط ولي الأمر المشروطة بموافقة صريحة من الطالب.
* **شو تبقى منها بدقة:**
- [ ] تطبيق migration على staging بعد نسخة احتياطية، واختبار المحاولة الصحيحة والخاطئة والمكررة والمتزامنة وانتهاء الصلاحية واختلاف الطالب، والتحقق من عدم رفع الإتقان قبل الموعد.
- [ ] مراجعة مصدر وحقوق وصحة أسئلة بنك الامتحان وتعبئة حقول `remediation_review_*` و`remediation_source_reference` لكل سؤال معتمد. الأسئلة القديمة تبدأ `draft` ولا تصلح تلقائياً لإثبات الإتقان.
- [ ] ربط واجهات الواجبات المدرسية بنظام مهام وتكليفات المعلم.
- [ ] دفع إشعارات تذكير للطالب عند استحقاق موعد اختبار التثبيت (اليوم السابع).
@@ -186,8 +194,10 @@
- لوحات الإدارة والسوبر أدمن تقرأ إحصاءات قاعدة البيانات الحقيقية.
- تشفير الرقم الوطني بـ AES-256-GCM مع فهرسة عمياء بـ HMAC.
- عزل الصلاحيات عبر الـ Middlewares لكل دور.
- فحص الحصة يرفض نقل صف الطالب أو إنشاء تصريح مدرسي أثناء القراءة؛ الدورة ذات `school_id` لا تُفتح إلا لطالب المدرسة نفسها مع `school_rosters.is_claimed=1`، ولا يجيز تصريح `school_included` قديم الوصول لدورة سوق عامة. مسارا حالة ملف الطالب وتغيير صفه يشترطان دور الطالب، ولا يغير طالب المدرسة صفه من الواجهة.
* **شو تبقى منها بدقة:**
- [ ] بناء آلية استيراد شعب المدارس وقوائم الطلبة من ملفات Excel/CSV.
- [ ] تدقيق مصدر كشوف الانتساب الحالية وربط حقوق الدورات بعقد مدرسي صريح؛ وجود `courses.school_id` وحده ليس دليلاً تعاقدياً شاملاً.
- [ ] اختبارات اختراق وعزل (IDOR multi-tenant isolation) لضمان عدم تسريب أي بيانات بين المدارس.
---
@@ -207,8 +217,111 @@
## 3. الخطوات المباشرة للتنفيذ الآن (Action Plan)
1. **الخطوة الأولى (تقني) — [تم الإنجاز]:** ربط خطوة التحقق المسبق (Preflight) وتنبيه النسخة المرشحة في استوديو المعلم داخل `apps/teacher_app`.
2. **الخطوة الثانية (تعليمي) — [تم الإنجاز]:** تطبيق خوارزمية التكرار المتباعد (المرحلتين: المعالجة الأولية + اختبار الاسترجاع والتثبيت بعد 7 أيام) في الخادم والواجهة.
1. **الخطوة الأولى (تقني) — [منفذة في الكود، غير متحققة E2E]:** ربط خطوة التحقق المسبق (Preflight) وتنبيه النسخة المرشحة في استوديو المعلم داخل `apps/teacher_app`.
2. **الخطوة الثانية (تعليمي) — [منفذة في الكود، غير متحققة تشغيلية]:** تطبيق خوارزمية التكرار المتباعد (المرحلتين: المعالجة الأولية + اختبار الاسترجاع والتثبيت بعد 7 أيام) في الخادم والواجهة، مع إعادة تحميل النتيجة من الخادم.
3. **الخطوة الثالثة (محتوى) — [التركيز الحالي]:** فحص واعتماد حزمة الـ 12 درساً النموذجية للصف العاشر (`publish_grade10_bundle.php --pilot`) والتحقق من سلامة الأصول والربط.
### 2026-09-20 — تحديث التطبيق والتحقق من مساري الاستبدال ودفتر الأخطاء
- **NP-03 / استوديو المعلم:** اكتمل ربط نتيجة `preflight` في `TeacherStudioCubit` مع حالة النسخة المرشحة ورقمها، وأضيف تنبيه صريح في `teacher_studio_upload_tab.dart` بأن الحصة المنشورة الحالية تبقى متاحة حتى اجتياز الفحص. هذا يثبت تكامل الواجهة مع مسار الاستبدال المرشح، ولا يثبت بعد رفع فيديو فعلي أو فحصه من البداية للنهاية.
- **NP-11 / دفتر الأخطاء:** أصبح نجاح المسار العلاجي يعيد تحميل البيانات من الخادم بدلاً من تعديل الحالة محلياً بشكل تفاؤلي، وأضيفت حالة `in_remediation` وعدادها ومرشحها ومسار اختبار الاسترجاع بعد 7 أيام في الواجهة، بما يتوافق مع انتقالات الخادم إلى `mastered`. لا يثبت ذلك بعد إرسال تذكير فعلي عند الاستحقاق أو ربط تكليفات المدرسة.
- **المرجع:** commit `e8163fe` بتاريخ 2026-09-20، وشمل `ErrorNotebookController.php` وتطبيق الطالب وتطبيق المعلم وملفات دفتر السجل.
- **فحوص هذه الدفعة:** لا يوجد في سجل commit دليل على تشغيل فحص جديد بعد التغييرات. تبقى آخر فحوص موثقة هي PHP lint و`git diff --check` وFlutter analyze المذكورة في إدخالات 9 و16 أيلول؛ لا نعدّ هذا التحديث متحققاً بتكامل قاعدة بيانات أو E2E.
- **الحالة بعد التحديث:** لم تتغير بوابة الإطلاق. ما زال نشر حزمة الـ12 درساً، تطبيق migrations على staging، اختبارات MySQL/Redis، التفريغ الصوتي والأدلة المرئية، الصوت الإنجليزي المعتمد، سياسة الدخل ومزود الدفع، وتجربة المستخدمين الفعلية غير مثبتة.
### 2026-09-23 — تصحيح صدق نتيجة دفتر الأخطاء (NP-11)
- كشف التدقيق أن طلب `resolve` السابق كان يقبل إثبات النجاح من الهاتف دون الإجابات، وأن أسئلة عامة مؤلفة كانت تظهر إذا نقص بنك الأسئلة؛ كما لم يكن حقل موعد الاسترجاع موجوداً في المخطط. لذلك أعيدت حالة NP-11 من `verified_in_code` إلى `implemented_unverified`.
- أضيفت migration لمحاولات العلاج وموعد الاسترجاع وحقول المراجعة الأكاديمية. بدء المحاولة أصبح POST؛ يسحب ثلاثة أسئلة منشورة ومراجعة مرتبطة بنفس `lesson_id` و`topic_tag` ويخزن مفتاح الإجابة في الخادم. إن لم تكفِ الأسئلة يعرض عدم التوفر. الإرسال يتضمن خيارات الإجابات، والتصحيح والانتقال بين الحالات يحدثان داخل transaction مع قفل صف الفجوة والمحاولة، وصلاحية 30 دقيقة ومحاولة استعمال واحدة، وإعادة نفس الإرسال تعيد النتيجة دون زيادة العدادات.
- تطبيق الطالب لم يعد يستقبل `correct_index` ولا يرفع إتقاناً بناءً على تصحيح محلي. عند تعذر تحميل الدفتر يعرض خطأ وإعادة محاولة بدلاً من نسبة إتقان 100% مصطنعة. نتيجة اختبار الاسترجاع لا تدّعي إثبات الذاكرة طويلة المدى.
- **فحوص:** `php -l` للمتحكم والراوتر، اختبار محلي خالص `test_remediation_attempt_grader.php` (9 حالات)، `dart analyze` للملفات الثلاثة المعدلة (صفر أخطاء، 14 ملاحظة `withOpacity` موجودة سابقاً)، و`git diff --check`. **غير منفذ:** migration واختبار MySQL/HTTP حقيقي لغياب بيئة staging معزولة مثبتة؛ لم تُعدّل بيانات تشغيلية.
- **التالي:** طبّق migration واختبر حالات الفشل والتزامن على staging، ثم راجع واعتمد مجموعة أسئلة الدرس التجريبي قبل قياس الإتقان في تجربة الصف العاشر.
### 2026-09-23 — إغلاق اختصار اعتماد حزمة الصف العاشر (NP-02)
- كشف التدقيق أن `publish_grade10_bundle.php --apply` كان يرفع `source_status` و`review_status` و`rights_status` آلياً دون دليل مراجعة أو حقوق. عُدّل السكربت ليعرض أسباب المنع في dry-run، ويقتصر التنفيذ على تحويل حزمة مراجعة مستوفية إلى منشورة. يتطلب مراجعاً وتاريخاً للدرس، وأصلاً رئيسياً، واعتماداً وحقوقاً مصفاة ومصدرًا لكل أصل. سحب الحزمة لا يمحو هذه القرارات.
- صحح اختيار الـpilot ليشمل 12 ملفات دروس فعلية بدلاً من إدراج `intro_and_project.md` ضمن عدد الدروس. بوابة الملفات المحلية `validate_grade10_candidate.php --json --manifest=manifest.accepted.json` أعادت `passed` مع 0 أخطاء و581 تحذيراً على 369 مدخلاً؛ هذا فحص بنيوي وليس موافقة أكاديمية.
- **فحوص:** PHP lint و`git diff --check` لملفات التغيير. **غير منفذ:** dry-run المعتمد على MySQL، تطبيق migration، مراجعة بشرية، أو نشر حي. تبقى حزمة الـ12 غير معتمدة في هذا السجل.
### 2026-09-23 — متابعة بوابات الصدق للمحتوى والعلاج
- أضيف `RemediationAttemptGrader` لاختبار ربط كل إجابة بسؤالها وخياراتها المخزنة؛ فحص محلي خالص نجح في 9 حالات صحيحة وخاطئة ومدخلات غير صالحة. أضيفت حقول مراجعة بشرية لأسئلة العلاج، وتبدأ الأسئلة القديمة `draft` فلا تُستخدم لإثبات الإتقان قبل مراجعتها.
- أزيل اختصار آخر في `publish_grade10_textbooks.php`: لم يعد ينشئ حزمة منشورة أو أصل PDF معتمداً أو يصفّي الحقوق تلقائياً، ولا ينقل كتاباً إلى فصل مختلف عند غياب المطابقة. يربط فقط PDF طالب له أصل محلي معتمد وحقوق مصفاة وبصمة ملف مطابقة وحزمة منشورة في المبحث والفصل الصحيحين؛ المعاينة تعرض العوائق وتمنع `--apply` عند وجودها.
- **الفحوص المحلية:** PHP lint للسكربت والخدمة والمتحكم، 9 حالات للمصحح، و`git diff --check`. **غير مختبر:** سلوك MySQL والتزامن وربط PDF على staging؛ ملفات PDF وموافقات حقوقها تحتاج فحصاً بشرياً.
### 2026-09-23 — إغلاق تجاوز النشر وحماية النسخة الحالية (NP-03/04)
- أُلغي مسار `SuperAdminController::reviewSubmission` القديم الذي كان يغيّر حالة الفيديو إلى `published` دون job فحص؛ يعيد الآن 410 ويوجه إلى مسار الأدلة والقرار والنشر المنفصل. صُحح استعلام قائمة الحزم لحقول مخطط المنهج الفعلية.
- أضيف `VideoCoverageValidator`: يرفض التغطية المقطوعة، والفجوات الزمنية، وتعارض بصمة الفيديو أو نقص مراجع التفريغ والصورة. تقيد `VideoReviewService` الأدلة ببصمة الفيديو وMarkdown والمدة الفعلية، ثم تعيد فحص المصدر والنسخة والحزمة المنشورة وقرار المراجع قبل تبديل النسخة الحالية.
- أبقيت `teacher_submissions.status='published'` عند رفع بديلة أو مراجعتها إذا كان لها فيديو حالي؛ ونُقل إنشاء job إلى معاملة إرفاق الفيديو بحيث يفشل معها الرفع كله بدلاً من ترك نسخة `review` بلا مهمة. الاستبدال يتطلب وجود نسخة منشورة حالية.
- **فحوص:** 8 حالات محلية خالصة للتحقق الزمني، وPHP lint و`git diff --check`. **غير منفذ:** اختبار MySQL/HTTP وتزامن فعلي، تفريغ فيديو حقيقي، مراجعة أكاديمية أو نشر.
### 2026-09-23 — مراجعة أعمق لمسارات الفيديو القديمة
- لم يعد `VideoController::getPlaybackData` يحذف امتحانات أثناء GET أو يرسل أسئلة قديمة مع `is_correct` قبل إجابة الطالب. تظل قائمة الأسئلة في المسار القديم فارغة إلى حين نشر أسئلة مربوطة بنسخة الفيديو ودليلها.
- حفظ سؤال المعلم عبر `saveCheckpoint` أصبح مسودة غير منشورة (`is_published=0`) مع تحقق من الخيارات وتوقيت الفيديو ومعاملة قاعدة بيانات. يحتاج السؤال مسار ربط أدلة ومراجعة قبل النشر.
- أضيف فحص تقرير المراجعة: يرفض أقساماً/أهدافاً ناقصة أو مشكلات حرجة/كبرى بلا حل موثق. نجحت 8 حالات محلية لهذا الفحص، إلى جانب 8 حالات تغطية الفيديو و9 حالات تصحيح العلاج. هذا لا يثبت صحة الفيديو علمياً أو تكامل قاعدة البيانات.
- **باقٍ في NP-04:** عامل تفريغ الصوت والصور، إثبات مراجع الأدلة مقابل الملفات الفعلية، مراجعة بشرية للدرس والأسئلة، اختبار تزامن النشر على MySQL، وواجهة تقرير المعلم.
### 2026-09-23 — ضبط تشغيل وبث النسخ المنشورة (NP-04/05/07)
- مسارا التشغيل القديمان المعتمدان على العنوان أو رقم `lessons` يعيدان 410؛ التشغيل المعتمد يبقى بمعرّف نسخة الفيديو المنشورة. أضيف تحقق صلاحية الطالب والنسخة المنشورة والمصدر المنهجي قبل إرسال الفيديو المحلي أو مقطع HLS، مع `Cache-Control: private, no-store` للملفات المحلية. يمكن للمعلم صاحب الدورة معاينة رفعه، وللسوبر أدمن صلاحية الإدارة.
- قائمة حصص الدرس وتشغيل النسخة وبدء جلسة المشاهدة تشترط job مراجعة معتمد وأصل Markdown مصرحاً بحقوقه داخل حزمة منشورة، وتغلق جلسة مشاهدة قائمة عند سحب الصلاحية قبل إضافة أي فترة جديدة.
- **لم يُتحقق تشغيلها بعد:** تشغيل HLS على جهاز حقيقي، صلاحيات المدرسة مقابل السوق، أحمال 100+ معلم، أو تزامن سحب أصل مع مشاهدة جارية. NP-05 لا تُعد مكتملة دون اختبار القائمة والصفحات على MySQL.
### 2026-09-23 — إصلاح صفحات قائمة المعلمين (NP-05)
- أزيل سقف 101 قبل فحص الوصول؛ استعلام المرشحين يعمل بدفعات 100 ضمن snapshot للطلب، ثم يعدّ الحصص المصرّح بها ويعيد الصفحة المطلوبة فقط. ترتيب التعادل يعتمد معرّف نسخة الفيديو، و`EXISTS` يحول دون تكرار الصف عند تعدد سجلات النشر أو المراجعة.
- تطبيق الطالب يطلب أول 20 حصة، يفتح الوحيدة مباشرة وفق `available_count`، ويتيح تحميل الدفعات التالية. أُزيل الفرز المحلي والوصف التعليمي المصطنع لأسلوب المعلم. لم يعد غياب علامة `hasVideo` القديمة يمنع الاستعلام عن درس له هوية منهجية.
- **فحوص منفذة:** PHP lint للمتحكم، `dart analyze` للملفات الثلاثة المعدلة (لا مشكلات)، و`git diff --check`. **غير منفذ:** اختبار قاعدة بيانات أو واجهة/شبكة فعلية؛ تبقى تكلفة المسح الكاملة لكل طلب بحاجة قياس عند كثافة المعلمين، وتبدل القائمة بين الطلبات يحتاج تحديثاً عند التفاعل.
### 2026-09-23 — تدقيق حجز رصيد المعلم (NP-06)
- كشف التدقيق أن معاملة `placeWithdrawalHold` القديمة لم تُسلسل الحجوزات لمعلم واحد: كان كل طلب يستطيع قراءة الرصيد قبل إدخال حجز الآخر. أضيف قفل `teachers ... FOR UPDATE` قبل أي قراءة ثابتة، مع إبقاء مفتاح الإعادة ضمن المعاملة نفسها. لا يُفتح مسار سحب حقيقي بهذا التعديل.
- `balance()` أصبحت قراءة صرفة ولا تنشئ حساباً؛ الحساب غير الموجود يساوي صفراً غير مستحق للسحب. أصلح طرح `BIGINT UNSIGNED` بصيغة `CAST(... AS SIGNED)`. سبب تحرير الحجز سيُحفظ بعد migration الجديدة؛ السجلات السابقة لا تُنسب لها أسباب مفترضة.
- **فحوص منفذة:** 9 حالات SQLite محلية معزولة لقراءة الرصيد الصرفة، صافي المدين/الدائن وخصم حجز موجود، حفظ سبب التحرير، منع التحرير لمعلم آخر، وتكراره؛ PHP lint و`git diff --check`. **غير منفذ:** إنشاء حجز موجب على MySQL staging واختبارات تزامن/فشل/استعادة؛ متغيرات قاعدة البيانات وأدوات MySQL/Docker غير متاحة في بيئة العمل الحالية. SQLite لا يثبت سلوك `FOR UPDATE`. لا تُعد NP-06 مقبولة قبل هذه الاختبارات وتسوية الأرصدة ودورة دفع مثبتة.
### 2026-09-23 — فصل شجرة التحضير عن فهرس الطالب المنشور (NP-01/02)
- أصبح `/api/curriculum/tree` عاماً للطالب لكنه يعيد فقط الدروس المطابقة بهويتها ومسارها إلى سجل منهجي معتمد وحزمة منشورة وأصل Markdown مراجع ومصرح بحقوقه. لا يمرر ملف manifest أو نتاجاته الأولية أو موارده غير المنشورة، ولا يعيد manifest عند خطأ قاعدة البيانات؛ يظهر `503` صريحاً. الفراغ المنشور يعود بكائن `{}`، لا مصفوفة ملتبسة.
- نُقل استعمال المعلم لفهرس التحضير إلى `/api/teacher/curriculum/intake-tree` خلف صلاحية المعلم، لتظل الدروس غير المنشورة قابلة للاختيار في سير التحضير دون إيهام الطالب بأنها جاهزة. مواد PDF وأوراق العمل في الشجرة العامة تأتي فقط من أصول ذات مراجعة وحقوق وحزمة منشورة، مع قيد الصف والمبحث معاً.
- لم تعد واجهة الطالب تعرض كل الصفوف K12 عند خلو النتيجة، ولا تحول الاستجابة المعطوبة إلى «لا محتوى». عُدلت حالة الفراغ والبحث لتصف ما ثبت فقط؛ قراءة فهرس التخزين لم تعد تنشئ ملف manifest أثناء GET.
- **فحوص منفذة:** 11 حالة خالصة لترشيح شجرة النشر (درسان بنفس المعرف/المسار بصفين، مورد غير منشور، درس غير منشور، تطابق هوية ونسخة المنهج وUUID الأصل)، PHP lint، `dart analyze` للملفات المعدلة، و`git diff --check`. **غير منفذ:** HTTP/MySQL على staging، فتح كتاب PDF فعلي، وحقوق/دقة المنهج الأكاديمية.
### 2026-09-23 — سد مسار ملف الدرس الخام وضبط خدمة الأصل (NP-01/02)
- قُصر `/api/curriculum/lesson` و`/api/curriculum/document` على إدارة المنهج؛ أزيلت محاولة الطالب جلب `file` الخام. ترسل شجرة النشر UUID أصل Markdown الأساسي، وتستخدمه واجهة «قراءة الدرس». غياب الملف لم يعد يعيد فقرة «محتوى معتمد» ثابتة.
- خدمة الأصل المنشور تتحقق من صف الطالب المسجل ومن أن الملف المحلّي هو التخزين المحدد ضمن جذر المنهج، وتطابق الحجم وSHA-256 قبل الإرسال، مع ترويسات منع التخزين المؤقت والـMIME sniffing. لم يعد البحث عن ملف بديل في مجلدات أخرى أو تحت جذر المشروع.
- حفظ مسودة Markdown يرفض المسار المتجاوز للجذر أو الكتابة على أصل مربوط بحزمة منشورة، ولم يعد يحدّث صفوف `lessons` ببحث `LIKE` قد يطال درساً آخر. رسالة الحفظ تصف «مسودة»، لا اعتماداً أكاديمياً.
- أُزيل JWT من رابط PDF الخارجي: بعد مصادقة الطالب يصدر الخادم تذكرة عشوائية محفوظة في Redis لمدة 120 ثانية، مقيدة بمعرّف أصل PDF والطالب. مسار التنزيل يعيد التحقق من نشر الأصل وسلامته وصف الطالب وحالة هويته عند كل طلب. التذكرة قابلة لإعادة الطلب أثناء عمرها القصير للسماح بطلبات قارئ PDF، وليست بديلاً عن جلسة عامة.
- **فحوص منفذة:** 10 حالات محلية معزولة للوصول/الملف والمسار، 11 حالة لترشيح الشجرة بعد إضافة UUID الأصل، PHP lint، `dart analyze`، و`git diff --check`. **غير منفذ:** اختبار HTTP/MySQL/Redis، انتهاء التذكرة أو محاولة استعمالها لأصل آخر على خادم فعلي، سحب أصل أثناء طلب جارٍ، واختبار PDF على جهاز.
- **فجوة أمن/تجربة مفتوحة:** رابط PDF يحمل الآن تذكرة قصيرة ومقيدة لا JWT، لكن نجاح عرض الصفحات المتعددة عبر المتصفح الخارجي لم يُختبر. لا يحمل مخطط الأصل نطاق مدرسة/tenant، لذلك تحقق الصف لا يثبت عزل أصول مدرسة عن أخرى. النسخة المحلية المحفوظة تحتاج سياسة انتهاء/سحب موثقة قبل اعتبارها cache إنتاجياً آمناً.
### 2026-09-23 — ضبط وصول المدرسة والسوق وملف الطالب (NP-05/12)
- أزيلت آلية `validateLessonAccess` التي كانت تحوّل صف الطالب المستقل تلقائياً عند قراءة حصة وتمنح الطالب المدرسي أي دورة مجاناً وتُنشئ `school_included` pass أثناء الطلب. صار الفحص قراءة صرفة: تطابق الصف، دورة منشورة، تطابق الدرس مع الدورة، وحجب الدورة المدرسية عن مدرسة أخرى أو مستقل. وصول طالب المدرسة لدورة مدرسته يتطلب انتساباً مؤكداً في `school_rosters`؛ الدورة العامة المدفوعة تتطلب تصريح سوق نشطاً، ولا يكفي `school_included` قديم.
- `POST /api/student/profile/update-grade` و`GET /api/student/profile/status` خلف دور الطالب. تغيير الصف يرفض طالب المدرسة والصف/المسار غير الصالح؛ قراءة الملف لا تكتب تصحيح صف تلقائي. أُغلق فرع تحديث ملف قديم كان يقبل JWT مباشرة لتغيير الرقم الوطني دون إثبات الهوية والجلسة النشطة؛ إكمال التسجيل الجديد يظل عبر `identity_token` المخصص.
- **فحوص منفذة:** 12 حالة SQLite محلية معزولة تشمل طالباً مستقلاً، مدرستين، كشفاً غير مؤكد، دورة عامة مجانية ومدفوعة، تصريحاً مدرسياً قديماً، صفاً خاطئاً، ودورة غير منشورة، مع التحقق من عدم تغير الصف أو عدد التصاريح. PHP lint و`git diff --check`.
- **غير منفذ:** MySQL/HTTP مع مدرستين وعقود حقيقية، تسوية التصاريح القديمة، تدقيق منافذ المعاينة، وإثبات أن كل دورة `school_id` مصرح بها تعاقدياً لتلك المدرسة. نتيجة الفحص المحلي لا تُعد إثبات عزل شامل للمنصة.
### 2026-09-29 — تجربة الطالب على الخادم المباشر (NP-01/02/04)
- شُغّل تطبيق الطالب على macOS واتصل بـ`saqel.intaleqapp.com`؛ أعاد API للمناهج 13 مبحثاً منشوراً. السبب الجذري لرابط التشغيل الخاطئ كان سكربت `link_legacy_math_videos.php`: يحقن مضيف `b-cdn.net` ويعلّم نسخاً منشورة من دون مهام مراجعة. السجلان الحاليان للدرس 1 و2 من هذا المصدر أعادا HTTP 403. ملفات HLS المقابلة على Cloudflare R2 تعيد HTTP 200، ومددها 778 و930 ثانية، ومفتاحا المنهج وعناوين الدرسين متطابقان مع الملفين المحليين على الخادم. لا توجد لهما مهام/أدلة مراجعة معتمدة.
- أُصلح إصدار تذاكر تنزيل PDF في الخادم: أضيف مسار POST لإصدار ticket وGET لتنزيل الأصل، خدمة Redis قصيرة العمر ومقيدة بالأصل والطالب، وتحقق صلاحية الصف وبصمة الملف في خدمة المحتوى. عولجت فجوة التوافق مع نسخة `PublishedContentService` المنشورة، ثم تحققت مسارات HTTP كـ401/403 دون تسجيل دخول ونجح إصدار تذكرة من التطبيق. عناوين الكتب أصبحت تميز الملفات المعروفة وتصرح بالفصل/الوحدة عند نقص اسم المصدر.
- أُنشئت نسختان بديلتان عبر `TeacherSubmissionService` الرسمي، ببصمة MP4 المطابقة للملفين على الخادم، وحُفظت حالتهما `review` مع `needs_evidence`. بقيت النسختان الحاليتان كما هما إلى أن تجتاز البدائل المراجعة. المدخلات الناقصة لكل مرشح: تفريغ مؤقت كامل، دليل بصري، وبيان تغطية. أُوقفت أداة الربط القديمة محلياً وعلى الخادم، كي لا تعيد نشر روابط Bunny أو تتجاوز الفحص.
- شُددت API الإنتاج: الشجرة وقائمة الحصص وendpoint التشغيل لا تعتبر الفيديو منشوراً إلا بعد موافقة مراجعة الفيديو وربطه بحزمة Markdown المنشورة وبصمتها. فذلك يحجب الإصدارات القديمة التي لا تملك أي سجل مراجعة، ويمنع اعتبار المرشحين الجدد منشورين قبل اكتمال الدليل. إعداد R2 يُحمّل من ملف البيئة الخارجي `/home/intaleqapp-saqel/.env` عبر bootstrap الإنتاج؛ فحص آمن للتهيئة أكد وجود account/access/secret/endpoint/bucket/public URL من دون طباعة قيمها. ملف `backend/.env` المحلي ليس مصدر إعداد الإنتاج.
- **الفحوص المنفذة:** بناء وتشغيل macOS debug، تحقق واجهة فشل التشغيل عبر CUA، `flutter analyze` للملفات السبعة (صفر errors؛ 20 info style diagnostics)، PHP lint لملفات التغيير، `git diff --check`، طلبات HTTP لقوائم HLS R2، وتسجيل المرشحين من خلال الخدمة الرسمية والتحقق من SHA256 وحالة مهمة الفحص.
- **المتبقي:** لا يمكن نشر المرشحين من دون الأدلة الزمنية والبصرية ومراجع أكاديمية بشرية؛ لم تُختلق هذه الأدلة. بعد مراجعتها، يلزم قرار اعتماد ثم نشر النسخة البديلة، وبعدها اختبار تشغيلها على الماك. اختبار فتح صفحات PDF متعددة وتدفق انتهاء تذكرة التنزيل يحتاجان تحققاً إضافياً على جهاز الطالب. تغييرات Flutter محلية ولم تُوزع كتطبيق إنتاج؛ تغييرات API وإيقاف السكربت نُشرت على الخادم.
### 2026-09-30 — استكمال فحص الطالب على macOS (NP-01/02/04/05/11)
- **بيئة الفحص:** macOS 26.0 على Apple Silicon، تشغيل `flutter run -d macos --no-pub` بالنسخة المحلية على API الإنتاج، بحساب طالب صف عاشر موجود مسبقاً على الجهاز. لا توجد كتابة في قاعدة الإنتاج أثناء هذا الفحص.
- **نتائج مرئية:** `/api/auth/me` أعاد 200؛ `/api/student/lessons` أعاد 200 وقائمة فارغة؛ `/api/curriculum/tree` أعاد 13 مبحثاً. واجهة الرياضيات تعرض دروس manifest إضافية لا تتوفر لها حصص، وبعض صفوف الدرس بلا `primary_lesson_asset_id`. فتح قارئ PDF لهذه الحالة أظهر «المورد لا يحمل معرّف أصل منشوراً صالحاً» وصفحة فارغة. هذا خلل عقد API/بيانات منشورة، وليس عطلاً في R2 أو عارض PDF نفسه.
- **نزاهة المختبرات:** الفحص وجد `previewModeEnabled=true` افتراضياً ومسار ربط بالعنوان/مفتاح الدرس، وأدى فعلياً إلى اقتراح مختبر «أوتار الدائرة والقطاعات» لدرس «حل معادلات خاصة». أُغلقت المعاينة في تطبيق الطالب؛ صار فتح مختبر الدرس يتطلب UUID منهجي مطابقاً ومختبراً يحمل إصدار حزمة منشورة، واختفى fallback الذي كان يفتح الأداة التخصصية عند خلو قائمة المختبرات.
- **إصلاح محلي غير منشور:** عقد `GET /api/curriculum/tree` المحلي صار يربط صفوف intake بمخرجات حزم منشورة وأصل Markdown معتمد ومصفّى الحقوق ويعيد `primary_lesson_asset_id`. استعلام `has_video` يطلب مراجعة معتمدة وبصمة Markdown مطابقة. الإنتاج ما زال على نسخة controller أقدم لا ترسل معرّف الأصل، وملف `PublishedCurriculumTreeFilter.php` غير موجود فيه؛ لا يجوز تبديل route إلى service الجديدة وحدها. هذا التعديل لم يُنشر بعد، ولا تعني بيانات الدرس المحلية أنها اجتازت المراجعة أو أن PDF كتاباً متاحاً.
- **الفحوص المنفذة:** `flutter run` macOS ناجح؛ مشي UI حتى رياضيات/درس/PDF وملاحظة الخطأ؛ `dart analyze` للملفات الأربع (صفر errors، ملاحظة lint قديمة واحدة)؛ PHP lint؛ `php backend/scripts/test_published_curriculum_tree_filter.php` نجح بـ11 check؛ `git diff --check`.
- **ترتيب المتابعة:** (1) تصحيح عقد `/api/curriculum/tree` على staging ثم نشره بعد التحقق، كي لا يعرض إلا دروس الحزم المنشورة ويرسل UUID الأصل. (2) نشر أو ربط مصادر PDF حقيقية بمراجعة وحقوق موثقتين ثم اختبار تذكرة التنزيل وفتح صفحات متعددة على macOS. (3) توفير أدلة مراجعة الفيديو للمرشحين R2 ثم مراجعة بشرية ونشر إصدار؛ بعده اختبار اختيار معلم واحد/متعدد وتشغيل/استئناف المشاهدة. (4) معالجة `/api/student/lessons` الفارغ: تقرير سليم بعد إزالة legacy بلا حصص معتمدة، لكنه يجعل لوحة اليوم خالية؛ يجب ربط كتالوج المنهج الجديد بالتطبيق أو تقديم تجربة واضحة للفهرس المنشور. (5) مراجعة مسارات الاختبار وبنك الأسئلة ودفتر الأخطاء والتحميل دون ادعاء إتقان أو نجاح عند غياب مصادر معتمدة.
- **غير مفحوص في هذه الجولة:** PDF قابل للتنزيل/متعدد الصفحات (الأصل غير متوفر في الاستجابة)، قائمة فيديو بعد المصادقة، تشغيل HLS داخل التطبيق بعد اعتماد نسخة، الاختبارات والدفتر والتقدم، قارئ الشاشة/VoiceOver، بناء release موقّع، تطبيق المعلم/الإدارة على macOS.
- **مسار Git والنشر:** فُحص مستودع الماك والسيرفر؛ كلاهما `main` عند `e8163fe`. نُفذ `git pull --ff-only origin main` على السيرفر بحساب مالك المستودع بعد رفض الكتابة بحساب SSH على `.git/FETCH_HEAD`؛ النتيجة `Already up to date`. لم يكن على origin commit أحدث كي يصلح الفهرس أو التطبيق. بقيت تعديلات وملفات تشغيل غير متتبعة موجودة على السيرفر، ولم تُمسح أو تُستبدل. تغييرات الماك الحالية غير مرفوعة؛ لذلك build الماك لا يحدّث الإنتاج وحده.
</div>