# م7 (الطلبات والروشتة والنتايج) — عقد التنفيذ + ليدجر (2026-07-08)

> العقد المُلزِم. الخريطة `SCOUT.md`. عقود التصميم: `topics/gyna-reference.md` (§الروشتة ٨ بنود + §pick-first ١٠ بنود) · `topics/clinic-service-settings.md` §النوع2/3 (الأوضاع F1-F10). **اقرأ الليدجر أول حاجة عند العودة.** ⚠️ أداة Fable معطّلة هذه الجلسة → بديل: architect agent يراجع العقد + Codex كل WP.

## الهدف (المالك): «الدكتور مايكتبش — يختار» بالكامل، بالنموذجين (متكامل LIS / مستقل).
تست المالك: 5 تحاليل <8 نقرات · باقة بنقرة · روشتة 3 أدوية في ثواني واطبعها · اقلب lab_mode مستقل → نفس الشاشة تقرا من خدماتك وتُدخل نتيجة PDF بنفسك.

## القرارات (على أسئلة السكاوت التسعة)
1. **تعميم النية:** أضِف `clinic_service` لـ`StoreClinicalIntentRequest::CATALOG` (kind يفضل lab|rad — الـclinic_service يحمل service_type). `DecideClinicalIntent::executeHere` للـclinic_service = ينشئ `ServiceOrderLine` مباشرة (بلا LIS) على نفس ServiceOrder المفتوح.
2. **توصيل lab_mode/rad_mode:** الـpicker يبدّل المصدر: integrated→كتالوج LIS (investigations/procedures)؛ standalone→`clinic_services` (service_type lab/rad). دعم صغير `ClinicMode` يقرا المفتاحين.
3. **نتايج المستقل:** **إعادة استخدام L3** (ExternalResultDialog + ClinicalDocument) — تعميم حارس `SubmitExternalResult` ليقبل نية `clinic_service` مستقلة (value/صورة/PDF من الشيت). مفيش doc_type جديد (external_result كافٍ) — نحافظ على «مش gated على locked».
4. **كرر آخر روشتة داخل اللوحة:** NET-NEW (الموجود في previous-visits م6 على مستوى الزيارة). endpoint يرجّع بنود آخر روشتة للمريض كمسودّة قابلة للتعديل قبل الإصدار.
5. **Favorites:** **per-doctor (`user_id`)**، جدول polymorphic واحد `clinic_favorites` (company_id, user_id, favoritable_type, favoritable_id, unique) لكل الأنواع (lab/rad/drug + لاحقًا dx/complaint). toggle endpoint + `is_favorite` في ردود الكتالوج.
6. **presets الكاسكيد (MVP):** **مصدر الأدوية يفضل Core Products** + طبقة خفيفة `clinic_drug_presets` (company، product_id nullable أو drug_name حر، form، ready_sentence، sort) تغذّي الكاسكيد (دواء→شكل→جملة) + inline-add-persist. **كتالوج أدوية مستقل كامل (2000 صف) = مؤجّل.** most-used per-doctor = عدّاد استخدام + favorites (WP1).
7. **طباعة slip الأوامر:** FE-HTML (زي طباعة الروشتة: window.open+print) — ليترهيد + قايمة أسماء نقطية بلا أسعار/باركود (lab وrad).
8. **الشبكة القصوى مقابل pick-multiselect:** **مكوّن جديد `shared/catalog-grid-picker`** (أعمدة فئات + كل الكتالوج مرئي checkboxes + حدد-الفئة + حارة favorites أولى + inline-add + ميزانية N+2 نقرة). يحل محل typeahead per-row في lab/rad. الروشتة تفضل فورم cascade (UX مختلف) مش grid.
9. **lab tab-switch:** إصلاح = حفظ مسودّة الصفوف عبر التبديل (state في الأب/سيرفس صغير) — أولوية أقل، يُدمج في WP5.

## 📊 ليدجر
| WP | المحتوى | يعتمد | مراجعة | migration | الحالة |
|----|---------|-------|--------|-----------|--------|
| WP1 | **Favorites BE:** `clinic_favorites` polymorphic (company/user/type/id + unique) + Model + toggle `POST/DELETE clinic/favorites` + `favoriteIds(type)` + `is_favorite` في ردود كتالوج lab/rad/drug. Pest (عزل شركة+مستخدم، toggle idempotent). | — | native+Codex | ✅ `..._000010` | ✅ |
| WP2 | **Standalone orders BE (F2/F3/F4):** `clinic_service` في CATALOG whitelist + `ClinicMode` يقرا lab_mode/rad_mode + `DecideClinicalIntent` مسار standalone (clinic_service→ServiceOrderLine بلا LIS) + تعميم حارس `SubmitExternalResult` لنية clinic_service. Pest (standalone here-execute + external-result + عزل). | — | native+Codex | لا (لو مفيش عمود) | ✅ |
| WP3 | **Rx presets + repeat BE:** `clinic_drug_presets` (company, product_id?/drug_name, form, ready_sentence, sort) + search/inline-add-persist endpoints + repeat-last endpoint (بنود آخر روشتة للمريض) + usage_count per (doctor,drug). Pest. | WP1 | native+Codex | ✅ `..._000020` | ✅ |
| WP4 | **Catalog-grid-picker FE:** مكوّن مشترك max-visibility (أعمدة فئات + checkboxes كلها + حدد-الفئة + حارة favorites + inline-add + N+2). source-agnostic (يتغذّى items+fns). | — | single | — | ✅ |
| WP5 | **Wire grid → lab/rad + reception:** استبدال typeahead per-row بالشبكة + مبدّل المصدر بالوضع (WP2) + إنشاء طلب standalone + إصلاح lab tab-switch (حفظ المسودّة). | WP2·WP4 | native+Codex | — | ✅ |
| WP6 | **Fast prescription FE:** cascade دواء→شكل→جملة (WP3) + auto-new-row + autosave + كرر آخر روشتة (WP3) + favorites/most-used per-doctor (WP1) + inline-add-persist. ~2 نقرة/دواء. | WP1·WP3 | native+Codex | — | ✅ |
| WP7 | **Results in all modes FE:** إدخال نتيجة من الشيت لطلب clinic_service مستقل (ExternalResultDialog المعمّم WP2) + ظهورها في timeline/results. | WP2 | single | — | ✅ |
| WP8 | **Print + rad fixes:** slip أوامر lab/rad (FE-HTML ليترهيد+قايمة) + إصلاحات rad flow/صلاحية + polish طباعة الروشتة. | WP5 | single | — | ✅ |
| WP9 | **Polish+ship:** CHANGELOG + KB + نشر /app + push + السويت الكامل + sweep المتبقّي. | الكل | single | — | ✅ |

**DAG:** BE سلسلة migrations {WP1→WP3} (WP2 غالبًا بلا عمود) · WP4 مستقل (يبدأ فورًا مع BE) · WP5={WP2,WP4} · WP6={WP1,WP3} · WP7={WP2} · WP8={WP5} · WP9 آخرًا. ⚠️ **routes/api.php يُسلسل** (كل BE WP يلمسه). **migrations ≥ `2026_07_08_*` وتُسلسل على moonui_dev_be.**

**ترتيب التنفيذ:** جولة1: WP1(BE) ‖ WP4(FE). جولة2: WP2(BE) ‖ (WP6 مستنّي WP3). جولة3: WP3(BE). جولة4: WP5 ‖ WP6 ‖ WP7 (⚠️ تعديل C أدناه: ماحدّش منهم يعدّل consultation.component.ts متزامنًا). جولة5: WP8. جولة6: WP9.

## ⚖️ تعديلات مراجعة architect (بديل Fable) — مُلزِمة قبل WP2
- **A [BLOCKER · #3/WP2]:** حارس `SubmitExternalResult::canRecord` (`:125-133`) يقبل `status===External` فقط. لكن طلب clinic_service المستقل بيتنفّذ `executeHere` → status=**`Here`** (`DecideClinicalIntent.php:124`) → الحارس يرفضه → تست المالك «أدخل PDF بنفسك» يفشل. **الإصلاح:** اسمح `status===Here` **فقط لو `catalog_ref_type==='clinic_service'`** (مايتعمّمش على Here عمومًا — لاب LIS المتكامل Here لازم يفضل ياخد نتيجته من LIS مش يدوي). **Pest اتجاهين:** LIS-here **يرفض** external result · clinic_service-here **يقبل**.
- **B [#1/WP2]:** (أ) `executeHere` (`:93-111`) بيفرّع على kind بس والفرعين بينادوا orderLab/createRadOrder (بيستهلكوا catalog_ref_id كـLIS id). clinic_service محتاج **فرع جديد** عبر **`AddServiceOrderLine`** (مسار clinic_service_id) عشان لقطات الفوترة تشتغل (`ServiceLineAdded→SnapshotLinePricingAndSplit`: unit_price/coverage/split/claim) — **insert خام يتخطّاها بصمت.** Pest: السطر المستقل يحمل price_source/coverage/split. (ب) `StoreClinicalIntentRequest::CATALOG` بيثبّت kind لكل ref_type ويفرض `meta.kind===input.kind` (`:89`) — clinic_service = lab **أو** rad حسب `service_type`، فـWP2 **يشتقّ kind من `clinic_services.service_type`** (أو special-case). عرّف `executed_ref_type` للسطر المستقل (**الـ ServiceOrderLine نفسه هو الأثر** — WP7 يقرا النتيجة عليه).
- **C [collision · جولة4]:** `consultation.component.ts` host مشترك (يستورد LabOrders+RadOrders+Prescription، يملك tab state `:110`، وrepeat-rx refresh `:78,:370`). WP5(tab-switch draft) + WP6(repeat wiring) + WP7(results) كلهم ممكن يعدّلوه متزامنًا. **الحل:** مسودّة tab-switch في **سيرفس صغير** (لا الأب)؛ WP6/WP7 عبر child `@Input/@Output`. **ماحدّش من جولة4 يعدّل consultation.component.ts** (وإلا سلسِلهم).
- **D [#6/WP3+WP6]:** أضِف `is_default` لـ`clinic_drug_presets` (مش sort بس) = الشكل+الجملة المُعبّأة تلقائيًا. **Day-1:** presets فاضية → الدكتور يكتب أول مرة لكل دواء ثم **inline-add-persist** يخليها نقرة بعدين؛ **نقبل inline-add-persist كمسار day-1 + حقول الحر تفضل fallback** (مفيش seed 2000). 
- **E [naming · #2]:** «ClinicMode» يتصادم مع `Enums\ClinicMode` الموجود (single_clinic|center) → سمّي قارئ lab_mode/rad_mode **`ClinicCatalogMode`**. **lab_mode وrad_mode الاتنين مزروعين** (`ClinicSettingDefinitionSeeder.php:100,116`) — مفيش seed gap، WP2 بس يقرا.
- **F [Pest · WP3]:** repeat-last + preset search/inline-add يحتاجوا تست **عزل شركة صريح** (لا تسريب مريض/preset عبر التينانت) بنفس صرامة WP1.
- **اختياري:** (i) حقن `is_favorite` عبر قراءة كتالوج **clinic-owned** مش تعديل controllers الـLIS. (ii) toggle «للزوج/forhusband» في الروشتة → **مؤجّل صريح** (مضاف للمؤجّلات). (iii) slip الطباعة يعيد استخدام plumbing طباعة الروشتة RTL (`clinic-prescription.service.ts printPrescription`).

## المؤجّلات (م7)
- كتالوج أدوية مستقل كامل (2000 صف + drug_categories/dosage_forms) → مرحلة لاحقة (MVP=Products+presets).
- طباعة BE-PDF حقيقية (نستخدم FE-HTML الآن) → م8/م10 طباعة.
- favorites للتشخيص/الشكوى (الجدول polymorphic جاهز) → عند لمس تلك اللوحات.
- استبيان الشكوى المنظم بالشبكة (§gyna 3-أ) → م9 (خارج نطاق م7 الأساسي).
- toggle «للزوج/forhusband» في الروشتة (§gyna 8-بند) → مؤجّل صريح (تعديل architect optional-ii).
