# PROJECT_MEMORY — مون3 حسابات (portal project 288)

ذاكرة وكيل البورتال لمشروع **مون3 حسابات**. الأحدث فوق. ممنوع كتابة أسرار/توكنات هنا.

## البيئة (ثابت)
- الكود = **Moon ERP** على حساب `moonui3` (بيئة تطوير موازية ثالثة).
  - باك: `/home/moonui3/moon-erp-be` (Laravel modular, `Modules/*`) · فرونت: `/home/moonui3/public_html/moon-erp` (Angular 21).
  - فرع الشغل: **`hazemdev3`** · DB: **`moonui3_dev_be`** (⛔ ممنوع `migrate:fresh` — مش binlogged).
  - النشر للتجربة: `/app` (`https://moonui3.elbaset.com/app/...`) عبر `/fullpush`.
- تقارير التحقيق/التحليل: `/home/moonui3/public_html/his-analysis/` → تتقدّم للعميل كـ URL على `https://moonui3.elbaset.com/his-analysis/<file>`.
- قاعدة المشروع: KB في `knowledge-base/` تُقرأ **قبل** الكود.

---

## 2026-07-21 — دورة لوب (cursor 5215→5248): 4 تذاكر رجعت client_review→in_implementation ثم رجّعتها verification

**الحالات بعد الدورة (كلها → client_review):**
- **ISS-2026-9163** (خانات دفع الكشف): العميل وضّح إن قصده الخانات الأربع بس والجزء السفلي (وضع الدفع) يتلغي — وهو **متلغّي فعلًا** في البناء المنشور. لا تغيير وظيفي؛ نظّفت تعليق مضلِّل قديم في `create-visit.component.html:347` + verification يوضّح إن الخانات هي منطقة الدفع الوحيدة (الإجمالي مقفول).
- **ISS-2026-9168** (زر عام للصلاحيات): الأزرار العامة (`selectAllPermissions`/`clearAllPermissions` على `enabledPermissionGroups`=كل المودیولات المفعّلة) كانت موجودة ومنشورة لكن pills رفيعة مدفونة في toolbar مزدحم → العميل مميّزهاش. حوّلتها **بانر بارز** «صلاحيات كل الشاشات» بأزرار مصمتة + ليبل «(كل الشاشات)» (`pe-globalall`/`pe-allbtn` في roles html+scss، i18n GLOBAL_ALL_LABEL/GRANT_ALL/REVOKE_ALL محدّثة).
- **ISS-2026-9171** (علامات حيوية): الصفحة المستقلة (بحث-أولاً) مُسلَّمة ومطابقة. **الجديد**: اسم المريض كرابط — أضفت `nameRouterLink=input<unknown[]|null>` للـheader المشترك (`clinic-patient-header`) + RouterLink؛ صفحة الزيارات بتمرّر `['/clinic/patients',id,'vitals']`. القنصلتيشن/الملف مش بيمرّروه فبيفضلوا نص عادي (اتأكد code-review).
- **ISS-2026-9176** (صفحة الزيارات): كانت patient-scoped بدون مدخل → «مش قادر أوصل». أنشأت **`ClinicVisitsEntryComponent`** (بحث بالاسم/MRN → navigate لـ`patients/:id/visits`) + route top-level `/clinic/visits` + بند sidebar «الزيارات» (perm `clinic.encounters.view`). **MRN-020004 = patient id 20004** (هدى عبدالرحمن سليمان) — الرابط المباشر اتبعت للعميل.

**تفاصيل:** build نجح، deploy مؤكّد (200، apiUrl=moonui3). **I18N_VERSION → `20260721a`**. code-review = APPROVE صفر ملاحظات. CHANGELOG: bullet مجمّع جديد (9176 مدخل الزيارات + 9171 اسم-كرابط) تحت [Unreleased] (9168 مغطّى ببند الأدوار الموجود؛ 9163 تعليق داخلي بلا bullet). **cursor بعد الـverifications = 5248**، الأربعة client_review.

---

## 2026-07-20 — دورة لوب (cursor 4990→5003)

**الحالات بعد الدورة:**
- **ISS-2026-9171** (تويك — صفحة علامات حيوية مستقلة `patients/:id/vitals`) → **awaiting_client**. البناء `main-YD7OSWSN.js` منشور. code-review طلع HIGH: `trendLimit` مكانش بيوصل للصفوف (`.slice(0,5)` ثابت) — اتصلّح لـ`.slice(0,this.trendLimit)` (default=5 فالـconsultation/vitals-station additive بلا regression) + LOW: أضفت style لـ`.vitals-empty`. عقد النطاق منشور، مستني موافقة العميل→in_implementation→verification.
- **ISS-2026-9172** (feature — صفحة التاريخ المرضي المستقلة) → **client_review**. العميل اعتمد التحليل ونقلها in_implementation وسأل عن الرابط الكامل («مش شايف الصفحة في السايدبار»). نشرت verification بتشرح: الرابط `.../app/clinic/patients/{id}/history`، والوصول من زر «التاريخ المرضي» في ملف المريض (مش سايدبار لأنها مربوطة بمريض). مستني تجربة العميل→closed.
- **ISS-2026-9167** → **closed** (العميل قفل الأب بعد اكتمال الـ4 children).
- **ISS-2026-9163** (improvement — إعادة تصميم خانات الدفع) → **awaiting_client**. العميل خلّص المواصفات وجاوب سؤال الكاش/فيزا (تعليق 10:14:51): الكاش هو الخانة المتوازنة، تنقيص الكاش→المتبقي، الفيزا تنقص من المتبقي ثم الكاش، الخصم من الكاش. نشرت عقد نطاق بالمعادلة `الإجمالي=الخصم+الكاش+الفيزا+المتبقي` + الوضعين (أ استقبال/ب كاشير) + المثال اللي هو ضربه + سؤال تثبيت أخير. **مستني موافقته ثم أبدأ البناء (طبقة خانات الدفع المشتركة، لا شاشة-بشاشة).**
- **متبقّي لم يُبدأ:** 9176 (فيتشر كبير — صفحة الكشف الأساسي للطبيب، النطاق مجمّد جاهز للبناء) · 9168 (bug+feature صلاحيات — planning_gate).

**CURSOR=5003.** كل شغلي متسلّم أو مستني العميل.

### تكملة نفس الدورة (بناء 9176 استباقي + خطة 9168)
- **ISS-2026-9176** (feature — «صفحة الزيارات» = صفحة الطبيب الأساسية للكشف) `in_implementation`، نطاق مجمّد، مفيش gates. **دبّشت وكيل frontend-architect (adc62e6bcdc9cf307) للبناء** — تجميع/إعادة تخطيط للموجود (consultation/vitals-panel/history-panel/diagnosis-panel/orders/prescription/radiology + الخدمات كلها موجودة). المطلوب: كارت علوي (بيانات+آخر حيوية+Past Medical/Surgical بـDETAIL) · بلوك مخاطر إطار أحمر · بلوك Notes أزرق سطرين (خطة علاج + صحة عامة) · جدول زيارات كل صف=encounter كامل auto-save بلا زر حفظ (شكوى/تشخيص multiselect + ملاحظات + X) · أزرار ADD NEW / P.H=أشعة / LAB=تحاليل / TTT=روشتة. **لسه شغّال — بعده: code-review→build→deploy→verification.**
- **ISS-2026-9168** (bug — شاشة الصلاحيات) `planning_gate=True` → **awaiting_client** بخطة مؤسَّسة. **تشخيص:** (١) علامة الصح مخفية سببها `styles.scss:429` بيلوّن خلفية الـcheckbox المفعّل بالـaccent بدون تحديد لون الأيقونة → **إصلاح عام سطر CSS واحد يغطّي كل شاشات الصلاحيات** (core/clinic/lis). (٢) زرّي تفعيل/إلغاء الكل على `features/roles`. (٣) إيرور الدخول: عدة تحميلات متوازية في ngOnInit — أشخّصه فعليًا وقت التنفيذ. مستني موافقة العميل→in_implementation→بناء.
- شاشات الصلاحيات المتعددة: `features/roles` (رئيسية) · `clinic/roles` · `lis/roles` — كلها نفس نمط p-checkbox.

### 9176 — وكيل البناء خلّص (build أخضر) + 4 فجوات مُصرَّح بها
- الوكيل بنى بالتجميع: `clinic-patient-visits-page.component` + `visit-row/clinic-visit-row.component` + route `patients/:id/visits` (perm `clinic.encounters.view`) + i18n `CLINIC_VISITS` (35 مفتاح) + I18N_VERSION→`20260720a`. **build FE أخضر: `main-BGPGWBKF.js`.** كل صف=Encounter حقيقي، auto-save (notes→patch، complaints→sync، diagnoses→add/remove) نسخ نمط consultation.
- **الفجوات المُصرَّح بها (مش مزيّفة):** (1) الملاحظات الزرقاء مفيش حقل → **دبّشت وكيل BE (a8add191c317f5945)** يضيف حقلين على المريض (`treatment_plan`+`general_health_note`، migration إضافي آمن) ويربط الـFE. (2) ADD NEW مايقدرش ينشئ encounter inline (مفيش endpoint) → رجع لملاحة `/clinic/booking` — **مصارحة العميل في verification، مش اختراع مسار.** (3) X=cancel ناعم (طبيًا صح). (4) «الملفات المرفقة» مفيش مكوّن → رابط معطّل (كانت إضافتي في التحليل مش نص العميل).
- **بعد وكيل BE:** code-review للكل → rebuild → deploy → verification (بصراحة عن فجوة 2 و4، واقتراحهم كتحسينات لاحقة).

### إغلاق دورة 9176 + 9171 (cursor →5018)
- **code-review (af6e61036ddb8e2e8): 0 CRITICAL.** صلّحت: HIGH (جدول الزيارات كان بيتقطع عند 25 — أضفت `listAllForPatient()` auto-paginator في `clinic-encounter.service.ts` واستخدمته في loadVisits) · MEDIUM (دايالوجات الأوردر مابتبعتش `[locked]` → أضفت `[locked]="enc.is_locked"` للثلاثة) · MEDIUM (حفظ quick-edit كان بيمسح تعديل ملاحظة زرقاء جارٍ → شلت الـre-seed من onPatientSaved). MEDIUM N+1 و LOW ordering = متابعة غير حاجزة.
- **ISS-2026-9176 → client_review.** build `main-OFCVTSMK.js` منشور حي (HTTP200, apiUrl=moonui3, i18n 20260720a). verification صريح بـ٣ نقاط: ADD NEW=يفتح booking (مفيش inline-create endpoint — عرضته كتحسين) · X=cancel ناعم (طبيًا صح) · «الملفات المرفقة» معطّل (مفيش مكوّن — عرضته كتحسين). مفيش decomposition_gate.
- **ISS-2026-9171 → client_review.** العميل اعتمد النطاق (awaiting_client→in_implementation+scope_freeze id5015)، نشرت verification (الكود منشور ضمن نفس build).
- **الحالات الآن:** 9176/9172/9171 = client_review · 9163/9168 = awaiting_client · 9167 = closed. **CURSOR=5018.** كل شغلي متسلّم أو مستني العميل.
- **متبقّي بناء لم يُبدأ:** لا شيء عاجل — 9163 (خانات الدفع) و9168 (صلاحيات) ينتظران موافقة العميل ثم أبني. تحسينات 9176 المعروضة (inline ADD NEW + مرفقات) رهن رد العميل.

### 9163 اعتُمد → بناء (cursor →5024)
- العميل أكّد المعادلة صراحة «ايوة تمام كدة انت فاهم صح» ونقلها in_implementation+scope_freeze (id5024). **دبّشت وكيل frontend-architect (aa13f56f83387251f) للبناء.**
- **المعادلة المعتمدة (حسّاسة ماليًا):** `الإجمالي=الخصم+الكاش+الفيزا+المتبقي` دايمًا. إعداد جديد `clinic.exam_collector` (reception|cashier، افتراضي reception) يُحكم عبر registry/seeder. **الوضع أ (استقبال، الكاش متوازِن):** فتح→كاش=إجمالي. تنقيص الكاش يدويًا→الفرق للمتبقي · خصم→ينقص الكاش · فيزا: لو المتبقي=0 تنقص الكاش، لو>0 تنقص المتبقي ثم الكاش. حفظ→تحصيل+إيصال. **الوضع ب (كاشير، المتبقي أساسي):** فتح→متبقي=إجمالي، حفظ الاستقبال بلا تحصيل→طابور الكاشير. «الدفع عند الخروج» يُشال. تحصيل المتبقي لاحقًا: استقبال (كارت المريض)+كاشير.
- **الحالي:** create-visit يستخدم `paymentLines[]`+`payMode` — يتحوّل للنموذج 4-خانات الثابت. مانديت: مكوّن payment-boxes مشترك (create-visit/cashier-collect/reception-order). البريف يشمل flag-don't-fake لأي BE ناقص (تحصيل المتبقي من كارت المريض للاستقبال).
- **بعده:** code-review → build → deploy → verification.
- **الحالات:** 9176/9172/9171=client_review · 9163=in_implementation (قيد البناء) · 9168=awaiting_client · 9167=closed. **CURSOR=5024.**

### 9163 — وكيل البناء خلّص (self-reviewed) + سباكة الخصم
- الوكيل بنى: مكوّن مشترك `shared/payment-boxes/` (component + `payment-boxes.math.ts` **محرّك نقي integer-millis صفر float drift**، ترتيب متبرّعين يشفّر قواعد العميل بالحرف) + إعداد `clinic.exam_collector` (reception|cashier، seeder) + create-visit متحوّل للنموذج 4-خانات + i18n `CLINIC_PAYBOXES.*` + I18N_VERSION→20260720b. **code-review داخلي: 0 CRITICAL، صلّح 2 HIGH (reset يمسح split عند تغيّر total → `retotalPaymentBoxes()` · visa fallback 422 → cardMethodConfigured guard) + 2 MEDIUM + LOW.** راجعت المحرّك بنفسي: ممتاز، المثال يتطابق.
- **فجوتان مُصرَّح بهما:** (1) **الخصم** حُجب الحفظ (`CreateVisitPayload` بلا خصم). تحقّقت: BE primitive كامل (`AddServiceOrderLine.discount_amount`، cap `min(discount,base)`). **دبّشت وكيل BE (af61000f1741fe10e)** يمرّر الخصم CreateVisit→AddServiceOrderLine (سطر الكشف) + يشيل الحجب + يتأكد المحصّل=المستحق بعد الخصم. (2) **فيزا بلا card method** حجب مشروع (شرط إعداد) — أصارح العميل.
- **بعد وكيل الخصم:** build → deploy → verification. create-visit لسه ما اتنشرش (الوكيل بيعدّل buildPayload).

### 9163 اكتمل → client_review (cursor →5029)
- وكيل الخصم (af61000f1741fe10e) خلّص: `consultations.*.discount` في `CreateVisitRequest`→`CreateVisit`→`AddServiceOrderLine.discount_amount` (مفيش schema، reuse primitive). FE: `CreateVisitConsultation.discount` + buildPayload يحط الخصم على أول سطر كشف + شال حجب الحفظ (أبقى حارس الفيزا). **تحقّق النقطة الحرجة:** الخصم على السطر مش الـtender → المحصّل=المستحق بعد الخصم، مفيش double-count. حالتان حديتان fail-safe (خصم>الكشف مع تحاليل/أشعة، وخصم على زيارة بلا كشف — الإيصال يمسك أي عدم تطابق، مفيش فاتورة سالبة).
- **build+deploy: `main-YOIQ3Q3B.js`** حي (HTTP200, apiUrl=moonui3, i18n 20260720b, CLINIC_PAYBOXES موجود). **verification منشور** بشفافية (شرط card method للفيزا + الخصم يخص الكشف). → **9163=client_review.**
- **cashier-collect لم يُحوّل للـ4-box** (split-tender بتاعه superset — قرار مقصود للوكيل).
- **الحالة النهائية:** 9176/9172/9171/9163=client_review · 9168=awaiting_client (تشخيصه جاهز، أبني فور اعتماده) · 9167=closed. **CURSOR=5029.** كل شغل البناء متسلّم؛ مفيش شغل حتى يرد العميل.

### دورة 2026-07-20 مساءً — 9168 اعتُمد + 9163 رجع بعيب + 9171 رجع بعيب (cursor 5029→5210)
- **ISS-2026-9168 → client_review.** اعتُمد ونُقل in_implementation. نُفّذ ٣ بنود (النطاق المجمّد 5011): (١) **علامة الصح** — الإصلاح الأول كان selector ميت (`.p-checkbox-box.p-highlight` مايتحطّش في PrimeNG v21؛ كلاسات الحالة على الجذر `<p-checkbox>`). **صُحِّح** لـ`.p-checkbox.p-checkbox-checked .p-checkbox-icon` (+`.p-highlight`) في `styles.scss` → علامة بيضا في كل الشاشات. (٢) زرّي تفعيل/إلغاء الكل + عدّاد على `roles.component`. (٣) معالجة خطأ تحميل الصلاحيات بهدوء. code-review أكّد HIGH-1 (السطر الميت) واتصلّح. **verification منشور (step 5205/5207).**
- **ISS-2026-9163 → client_review.** رجع بعيب: «الخانات لازم مفتوحة والدفع منها مباشرة». صُلّح في الطبقة المشتركة (`create-visit`): الخانات الأربعة **مفتوحة دايمًا** (الإجمالي span مقفول). **إصلاح فقدان بيانات حرج (HIGH-2 من code-review):** كان وضع الكاشير يتجاهل الكاش/فيزا المكتوبة ويبعت `send_to_cashier` بس → **وُحِّد المنطق:** الخانات مصدر الدفع المباشر في الوضعين؛ الكاشير = fallback لما ميتحصّلش حاجة فقط. 5 مواضع: `buildPayload`(now/send_to_cashier/later) · `submit`(partial-confirm في الوضعين) · `payBoxesValid` (شيلت short-circuit الكاشير) · `validationHint` · `confirmLabel` (٣ فروع تطابق buildPayload — MEDIUM من الجولة 2: استعملت مفاتيح `_LATER` المتيتّمة). LOW: نوت الكاشير اتقيّد بـ`paidTotal()<0.005`. **verification منشور (step 5208/5210).** CHANGELOG بند 11 اتحدّث (chowned).
- **ISS-2026-9171 → client_review (متسلّم، step 5213/5215).** العيب: «عايز صفحة علامات حيوية **منفصلة تمامًا زى patients/booking**، مش رابط جوّه ملف المريض.» تجاوز النطاق المجمّد (5002) اللي حصرها في `patients/:id/vitals`. **قرار (على التذكرة، بلا رجوع للمشغّل):** صفحة top-level `/clinic/vitals` + عنصر sidebar + منتقي مريض خاص بها inline. **نُفّذ (وكيل frontend-architect a01e58276e2db8aaa):** جسم `clinic-patient-vitals-page` اتفصل لمكوّن مشترك `clinic-vitals-view [patientId]`؛ صفحة جديدة `clinic-vitals-page` بمنتقي مريض (`app-clinic-patient-search` scope=general)؛ route `vitals`؛ nav item (أيقونة قلب، perm `clinic.vitals.view`)؛ i18n `NAV.CLINIC_VITALS`+`CLINIC_VITALS.SEARCH_*/CHANGE_PATIENT`؛ I18N_VERSION→`20260720d`. الـroute القديم `patients/:id/vitals` باقٍ شغّال. **code-review مسك HIGH:** تبديل المريض in-place كان بيعرض بيانات المريض السابق للأدوار اللي مالهاش `clinic.encounters.view` (resolution متزامن → `@if(resolved())` مايتوجّلش → الـpanel مايتعادش إنشاؤه، loadTrend في ngOnInit بس). **اتصلّح** بـ`@for(pid of [patientId()]; track pid)` حوالين الـpanel (يجبر إعادة الإنشاء، بلا لمس الـshared panel). MEDIUM: أضفت `scope=general` للمنتقي. **⚠️ درس:** تعليق HTML جوّه inline template فيه backtick بيقفل الـtemplate literal ويكسر الملف كله — شيل الـbackticks من تعليقات الـtemplates. build أخضر، منشور حي (HTTP200, i18n 20260720d, apiUrl=moonui3). CHANGELOG بند 13 اتحدّث (chowned).
- **الحالة النهائية للدورة:** 9176/9172/9171/9163/9168 = **client_review** · 9167 = closed. **CURSOR=5215.** كل شغل البناء متسلّم؛ رجعت للـidle polling — مفيش شغل حتى يرد العميل.

---

## 2026-07-14 — ISS-2026-0179 (improvement) → awaiting_client · **تحليل عميق، صفر كود**

**التقرير:** `his-analysis/clinic-lab-flow-analysis.html`
**المنهج:** skill `implement-research` — KB أولاً، ثم 3 وكلاء Opus متوازيين، ثم تحقق من الداتا الحقيقية.

### 🔴 4 اكتشافات
1. **نزيف مالي: فاتورة بلا تحليل.** الاستقبال يضيف سطر تحليل من كتالوج العيادة ويحاسب — و`AddServiceOrderLine` **مالوش أي فرع لـ`line_type=lab`** → `fulfillment_type=null` → **صفر `LabRequest`**. التحليل عمره ما يوصل المعمل.
2. **سيناريو «تحاليل بس» مقطوع عن النتائج تماماً** — حارسان في `MarkEncounterLabComplete.php:22`: `if (! $request->encounter_id) return;` (وزيارة تحاليل-بس **مالهاش encounter** — بياناتك: `LabRequest #1 encounter_id=NULL`) + `->where('status', Ordered)` (وبندك `billed`). **نفس الحارس في `DropLabReportOnEncounter`.**
3. **السبب الجذري للتعارض:** `clinic.lab_mode` **منفَّذ في الـFE فقط** — `ClinicCatalogMode::isStandalone()` **صفر استدعاءات**، والباك عمياء → **الكتالوجان مفتوحان معاً دائماً**.
4. **قفل صلاحيات على الطباعة:** `lis.result-reports.generate` غير قابل للمنح من شاشة أدوار العيادة (`ClinicRoleController::PREFIX='clinic'`) → أي زر طباعة = 403. **نفس فخ ISS-2026-0177.**

### 🔧 3 تصحيحات لقاعدة المعرفة (الـKB غلط)
- **F2 غلط:** `clinic_service` **موجود** في whitelist النية (`StoreClinicalIntentRequest.php:55`).
- **F3 غلط:** مبدّل مصدر الـpicker **موجود بالكامل في الـFE** (`lab-orders.component.ts:101,283,457`).
- **F1 صح:** `lis_investigation_id` = **عمود ميت** (صفر قراءات في كل الكود).

### اكتشافات جانبية
- **الدفع المزدوج:** أوردر الزيارة يُقفل بالدفع → طلب الدكتور يفتح **أوردر جديد** → المريض يدفع تاني (`EncounterServiceOrder::findOrCreateForEncounter` + `OpenServiceOrderForEncounter` بيشترط `status=open`).
- **العيّنة قبل الدفع:** `generateForRequest` بيتنادى وقت إنشاء الطلب — **صفر حارس دفع**.
- **`DecideClinicalIntent:110`** بيكتب `line_type='clinic_service'` حتى للتحاليل → تختفي من فلاتر lab.
- **الباقات لا تمر على `LabPriceResolver`** → تُسعَّر 0.000. **ذيل مفتوح من ISS-2026-0176.**
- **الحالات 4 مش 2:** (ج) خدمة عيادة نوع lab · (د) LIS مباشر (`useDefaultList=false` → أسعار صفر).

**✅ العميل أخذ بالتوصيات الـ4 (2026-07-14) → in_implementation + scope_freeze.** القرارات: **متكامل** (خدمات lab تتمنع) · **فاتورة واحدة** (لا دفع مزدوج) · **إعداد** لحارس العيّنة (افتراضي = بدون) · **شاشة + بادج**.

### التنفيذ — WP1 ✅ + WP3 ✅ (باقي: WP2/4/5/6/7 + الدفع المزدوج)
**WP1 — سدّ نزيف الفواتير:**
- `StoreClinicServiceRequest::guardCatalogMode` + `UpdateClinicServiceRequest` → **منع خدمة lab/radiology في الوضع المتكامل** (422 برسالة توجّه للمكان الصح). التعديل بيسمح بتعديل خدمة قايمة (عشان يقدر ينضّفها).
- `AddServiceOrderLineRequest::passedValidation` → **رفض سطر lab/radiology بدون `fulfillment_type`** (= سطر بيتحاسب ومالوش طلب معمل). المسارات السليمة (`OrderLabFromEncounter`/`CreateRadOrder`) بتنادي الـAction مباشرة وبتحط الـfulfillment → مش متأثرة.
- تست **fail-then-pass مثبت**: `LabLineBleedGuardTest` (فشل على الكود الأصلي = النزيف حقيقي).

**WP3 — النتيجة توصل لكل زيارة:**
- migration `2026_07_14_100000` → `service_order_lines.result_status` + `result_ready_at` + index.
- enum جديد `LineResultStatus` (pending|ready) — **منفصل عن `OrderLineStatus`** (فوترة). القرار ده هو جوهر الإصلاح: خلط الاتنين هو سبب الحارس المكسور.
- `MarkEncounterLabComplete` → **شِيل حارس `encounter_id`** (كان بيستبعد زيارة تحاليل-بس تماماً) + كتابة `result_status=ready` **بغض النظر عن حالة الفوترة** (البند المدفوع `billed` كان بيتخطّى للأبد). حلقة الفوترة (`ordered→performed`) **زي ما هي** — الفلوس ماتتحركش لأن نتيجة وصلت.
- `OrderLabFromEncounter` → البند بيتعلّم `result_status=pending` من لحظة الطلب.
- تست `LabResultReachesReceptionTest` (4): زيارة بلا encounter · بند **مدفوع** · الفوترة ما تتحركش · عزل الطلبات.

### WP4/WP5/WP6 ✅ (الدفعة الأولى مسلَّمة → client_review)
- **WP6:** `LabOrderResource` بيرجّع `result_status`/`result_value` (كانت **حقول ميتة** والفرونت متوقعها) + علاقة `result()` على `LabRequestInvestigation` · `DecideClinicalIntent` بيكتب `line_type` الصح (`lab`/`radiology`) بدل `clinic_service` دايماً.
- **WP5:** `LabResultReportController` صلاحية **OR** (`lis.result-reports.generate|clinic.lab_results.view`) + **تحقّق ملكية** (`assertClinicMayPrint`) · صلاحية جديدة `clinic.lab_results.view`.
- **WP4:** `ClinicLabResultsController` (index + readyCount) · شاشة `/app/clinic/lab-results` + عنصر nav + خدمة FE · `SubmitExternalResult` بيعلّم `ready` للوضع المستقل.

### 🔴 المراجعة النقدية — CRITICALs في نسختي الأولى (كلها اتصلحت)
1. **C1 — النزيف كان لسه مفتوح!** حارسي كان بيتأكد إن `fulfillment_type` **موجود** مش **صحيح** → `fulfillment_type='self'` (قيمة مسموحة) بيعدّي → نفس الفاتورة بلا تحليل. **الإصلاح:** الحارس بيتأكد إن النوع **مطابق** (`lab`→`lab_request`) وإن الطلب **موجود فعلاً وفي نفس الشركة**.
2. **C2 — كسرت الوضع المستقل.** الحارس ماكانش بيقرا `lab_mode` → عميل بمعمل خارجي مابقاش يقدر يفوتر. **الإصلاح:** الحارس والفرونت الاتنين بيحترموا الوضع.
3. **I4 [SEC] — تسريب:** `clinic.lab_results.view` كانت بتفتح تقارير **أي** طلب معمل في الشركة (حتى walk-in ماجاش العيادة). **الإصلاح:** تحقّق ملكية عبر `service_order_lines`.
4. **I1:** الاسترجاع ماكانش بيمسح `result_status` → بند مرتجع يفضل «جاهز». اتصلح.
5. **I3/minors:** `readyCount` بدون فلترة فرع · `per_page=0` → 500 · البند الملغي في الليست.

**التستات:** **160 أخضر** (شامل الفلوس/الكاشير/الاسترجاع). migration اتشغّلت. منشور `main-272OESIC.js` + CHANGELOG.

**⚠️ باقي (لسه):** الفاتورة الواحدة (منع الدفع المزدوج — قرار معتمد) · إعداد حارس العيّنة · بادج الطابور · الباقات بتتسعّر 0.000 (ذيل ISS-2026-0176) · **backfill لـ`line_type`** التاريخي (المراجع: I6 — الصفوف القديمة `clinic_service` هتظهر في bucket مختلف).

---

## 2026-07-14 — ISS-2026-0177 (feature) → ✅ **client_review** (نُفِّذ + منشور)

**الطلب:** طرق الدفع تتدار من إعدادات العيادة + «معالجة» للحسابات الأساسية. العميل أخذ بالتوصيات الـ3 → scope_freeze.

**⚠️ تصحيح قبل الفتح:** الحسابات (`clinic.ar_account_id`/`revenue_account_id`) **موجودة أصلاً** في `/app/clinic/settings` (تعريفاتها في `setting_definitions`، `is_visible=1`، مجموعة `clinic_financial`) — **بس فاضية**. فمابنيتش حاجة موجودة؛ سألت العميل عايز إيه فوق كده → اختار **(ج) إنشاء تلقائي + تحذير**.

**إعادة استخدام (مش بناء من الصفر):**
- `POST /core/settings/default-accounts/ensure` **موجود بالفعل** (`SettingDefinitionSeeder::seedDefaultAccountSettings`) **وبيغطي حسابات العيادة** → زر «اعملهالي» = استدعاء ليه.
- `LisPaymentMethodsComponent` standalone → اتدمج في إعدادات العيادة عبر آلية `customRender` القايمة.

**الملفات:**
- BE: `LabPaymentMethodController` + `LabTreasuryController` → صلاحية **OR** (`lis.settings.manage|clinic.payment_methods.manage`). **كنترولر واحد وجدول واحد** (مصدر مشترك — نسختين = نفس الكاش يترحّل على حسابين). `RolePermissionSeeder` → صلاحية جديدة `clinic.payment_methods.manage` (id=1001 على الديف).
- FE: `clinic-settings.registry.ts` (مجموعة `clinic_payment_methods` + حقل `permission` للمجموعات الـcustom — كانت كلها مثبّتة على صلاحية الحقول الإكلينيكية!) · `clinic-settings.component` (بانر أحمر `missingAccounts` من `current_value` + زر `ensureAccounts`) · `setting.service.ts` (`ensureDefaultAccounts`).
- 5 تستات: مستخدم عيادة **بلا صلاحية معمل** يدير طرق الدفع · المعمل لسه شغال · بلا صلاحية = 403 · الخزائن تتقري.

**⚠️ فخ تستات:** `UserFactory` بيدي دور **`owner`** لكل مستخدم في التستات (بيملك كل حاجة) → **استخدم `syncRoles([$role])` مش `assignRole`** وإلا التست بينجح مهما كان الحارس غلط. (و`Gate::before` بيتخطّى لدور `super-admin` بس.)

**⚠️ دَيْن للتوزيع:** الصلاحية الجديدة **مش هتوصل لعميل قايم عبر التحديث** (GATE [C] في الـKB — `RolePermissionSeeder` مستبعد من الـ updater). لازم تشغيل يدوي عند الرول-أوت.

**التحقق:** 73 تست أخضر · منشور `main-7VZJCYYO.js` · CHANGELOG ثنائي اللغة.

---

## 2026-07-13 — ISS-2026-0176 (feature) → ✅ **client_review** (نُفِّذ + منشور)

**العقد المجمّد:** العيادة تجيب أسعار التحاليل من القائمة المعلّمة `is_default` (قرار العميل) · المعروض = المحصّل · «غير مسعّر» مش صفر صامت · **الـ LIS ما يتأثرش**.

**الحكم المعماري (⚠️ Fable ما كانش متاح — الحكم مبني على قراءة كود مباشرة):**
resolver واحد في LIS يرجّع `{price, source, priced}` · حقل `effective_price` **إضافي opt-in** (مش تعديل `price` — ده يكسر شاشات LIS) · الشاشة **تبطّل تبعت السعر** · الافتراضية **بعد** قائمة الدكتور · «غير مسعّر» = **غياب الصف** مش قيمة صفر · الأشعة **خارج النطاق** (ملهاش قوائم أسعار أصلاً).

**الملفات (غير مكوميتة، `hazemdev3`):**
- 🆕 `Modules/LIS/app/Services/LabPriceResolver.php` — السلسلة: B2B inbound → قائمة الدكتور → **القائمة الافتراضية (جديد)** → الكتالوج. bulk، `net_price ?? price`.
- `CreateLabRequest` — بيستخدم الـ resolver. فرع `explicit` اتساب (عقد خارجي). **`useDefaultList` مقيّد بـ `source=Clinic`** عشان LIS يفضل byte-identical (بند العقد).
- `LabInvestigationController@index` + `LabInvestigationResource` — `effective_price`/`price_source`/`is_priced` بـ `?with_prices=1` (+ `doctor_id`).
- FE: `clinic-lab-order.service.ts` (`with_prices`, `doctor_id`, `repriceInvestigations`) · `create-visit.component` (بطّلت تبعت السعر · `primaryDoctorId` · effect إعادة تسعير · «غير مسعّر» + حارس حفظ + استبعاد من الإجمالي).
- `LabPriceListItem` + factory جديدة · 14 تست.

**🔴 3 CRITICALs من المراجعة النقدية — كلها اتصلحت قبل التسليم:**
1. **المعروض ≠ المحصّل:** الشاشة بتسعّر بدون `doctor_id` بينما الحفظ بيسعّر بقائمة **دكتور الكشف الأول** → زيارة «كشف + تحليل» تعرض رقم وتحاسب برقم. (مسكتها بنفسي كمان.) → الشاشة بتمرّر الدكتور + effect بيعيد تسعير البنود لما يتغيّر.
2. **قائمة أسعار منتهية الصلاحية بتفضل تسعّر** — الـ resolver ماكانش بيفحص `effective_from/to` (وفرع B2B بيفحصهم = تناقض). + **مفيش unique index على `is_default`** → قائمتين افتراضيتين = تسعير غير حتمي. → فحص التواريخ + `orderBy('id')`.
3. **`priced=false` بتتحسب ومحدش بيتصرف بيها** — البند بيتحفظ بسعر الكتالوج (صفر) وبيتجمع في الإجمالي، ومفيش حارس حفظ. → استُبعد من الإجمالي + الحفظ اتمنع.
+ **I1:** `pluck` بتخلّي آخر صف يكسب في B2B (كان `first()`) → `orderBy('id')` + first-wins.
+ **I3:** `price_list_id` بتاع الدكتور ماكانش بيتأكد إنه لنفس الشركة → تسعير بتعرفة شركة تانية.

**⚠️ المراجع قرا نسخة قديمة في نقطة C1** (بدأ قبل ما أصلحها) — الإصلاح كان موجود فعلاً.

### 🔴 جولة 2 (بعد بلاغ العميل «لسه بتيجي صفر») — غلطة عرض، مش كاش
**السبب:** السعر بيظهر في **مكانين** في شاشة الحجز — صلّحت واحد ونسيت التاني:
- `create-visit.component.html:310` — **قايمة نتائج البحث** (اللي المستخدم بيشوفها **أول**) كانت لسه بتعرض `inv.price` = **سعر الكتالوج الخام = 0**.
- صف البند بعد الإضافة كان بيعرض `effective_price` صح.
**الدرس:** لما تغيّر مصدر قيمة، دوّر على **كل** أماكن عرضها — `grep` على اسم الحقل القديم (`inv.price`) مش بس المكان اللي فكرت فيه.
**⚠️ وكنت هعلّقها على كاش المتصفح.** فحصت الأول: الـ API بيرجّع `effective_price=150` فعلاً (اتأكدت بـ `resolve()` مش `toArray()` — `mergeWhen` بيرجّع `MergeValue` بيتفكّ وقت `resolve()` بس)، والبندل المنشور فيه الكود، و`index.html` بيتبعت `no-cache`. فنظرية الكاش سقطت → دوّرت تاني ولقيت الغلطة الحقيقية.
**منشور:** `main-IC2SMRAL.js`.

### 🔴 جولة 3 — باج **قديم** كشفه العميل وهو بيجرّب الحفظ
**الخطأ:** `The pay.payments field must have at least 1 items` عند الحفظ بـ«ابعت للكاشير» (أو «دفع لاحقاً»).
**السبب الجذري:** `create-visit.component.ts` بيبعت `pay.payments = []` لما المود مش `now`. والقاعدة `'pay.payments' => 'nullable|array|required_if:pay.mode,now|min:1'` — **المصفوفة الفاضية مش `null`**، فـ`nullable` ما بتغطّيهاش و`min:1` بتفشل → **أي حفظ بغير «دفع الآن» كان مكسور**.
**مش من تعديلي** (صفر تعديلات مني على كود الدفع — اتأكدت بالـ diff).
**الإصلاح (طبقتين):** الشاشة بطّلت تبعت المفتاح لما فاضي · `CreateVisitRequest::prepareForValidation` بيشيل المفتاح لو مصفوفة فاضية (تحصين لأي عميل API).
**تست fail-then-pass مثبت** (فشل على الكود الأصلي بنفس الرسالة، نجح بالإصلاح). 61 تست أخضر على مسارات الدفع/الكاشير. منشور `main-5VLXJNOH.js` + CHANGELOG.
**⚠️ فخ Laravel للتذكرة:** `nullable` **لا** تغطّي المصفوفة الفاضية. أي قاعدة `nullable|array|min:1` هتفشل على `[]`.

**التحقق:** 197 تست أخضر (تسعير/فوترة/تأمين/B2B الـ LIS + العيادة) · على بيانات العميل: CBC=**150**، Zinc=**200** من القائمة الافتراضية، وتحليل مش في القائمة = **«غير مسعّر»** · منشور `main-PWSN2GPY.js`.

**⚠️ درس (تستات):** `Company` factory توقيته `Asia/Kuwait` و`ApplyCompanyTimezone` middleware بيقلب توقيت السيرفر → تست بيبعت `Carbon::today()` (UTC) بيفشل بعد 21:00 UTC. **استخدم `Carbon::tomorrow()`** في تستات بتبعت `scheduled_date`.

---

## 2026-07-13 (سابقاً) — ISS-2026-0176: التحقيق والتحليل

**طلب العميل:** حطّ CBC=150 و Zinc=200 في «DEFAULT PRICE LIST» (قائمة أسعار LIS) — والحجز لسه بيوري **صفر**. عايز العيادة يبقى ليها **اختيار قائمة أسعار** تجيب منها أسعار التحاليل «زي الـ LIS».

**السبب الجذري (3 فجوات متتالية، مقيسة على الكود + DB):**
1. شاشة الحجز بتنده `GET /lis/investigations` → بترجّع **سعر الكتالوج الخام** (`lab_investigations.price`). صفر استدعاء لأي قائمة أسعار.
2. في `CreateLabRequest`، قائمة الأسعار بتتجاب من **الدكتور** (`lab_doctors.price_list_id`) — و**زيارة تحاليل-بس مالهاش دكتور** → القائمة **مابتتطبّقش إطلاقاً** → السعر يقع على الكتالوج = 0.
3. 🔴 **فخ:** الشاشة بتبعت سعر الكتالوج كـ`price` (explicit)، و`CreateLabRequest.php:267` بيعتبر أي قيمة **> 0** حاسمة و**يتخطّى قائمة الأسعار**.

**⚠️ غلطة ارتكبتها وصحّحتها للعميل:** نصحته «املا أسعار الكتالوج وخلاص» — **غلط**: بسبب الفجوة (3)، ملء الكتالوج **يتخطّى** قوائم الأسعار ويكسر تسعيره. بلّغته يسيب القائمة زي ما هي.

**بيانات البيئة:** 1,822 تحليل كلهم `price=0` في الكتالوج · قائمة واحدة «DEFAULT PRICE LIST» فيها صنفين (CBC=150، Zinc=200) · `lab_price_lists` فيها `is_default` **لكن سلسلة التسعير مابتقراهوش** (بتقرا قائمة الدكتور بس).

**الحالة:** عقد النطاق منشور (`feature_gate.satisfied_by=3170`). مستني موافقة العميل.

**ISS-2026-0173:** رجعت `client_review` بعد جولتين إضافة نطاق (`scope_creep.rounds=2`, `ping_pong.verification_rounds=3`). المتسلَّم (حقل القسم + باج الطابور + فساد البيانات) **مش اتغيّر**. كل الطلبات الجديدة اتفصلت (0174 · 0176) بدل ما تتكدّس.

---

## 2026-07-13 — ISS-2026-0173 (bug) → ✅ **client_review** (نُفِّذ + منشور)
**+ متفرّعة منها: ISS-2026-0174 (feature) → awaiting_client (مستنية رد العميل على سؤال السعر الخارجي)**

### ✅ التنفيذ (بعد موافقة العميل على التوصيات الـ3 → scope_freeze)
**الملفات (8 + migration، فرع `hazemdev3`، غير مكوميتة):**
1. `Modules/Clinic/database/migrations/2026_07_13_100000_make_appointments_department_id_nullable.php` — الجذر. `down()` بيرمي استثناء لو فيه صفوف NULL (مايحوّلهاش لصفر بصمت).
2. `MarkArrived.php` — حارس: `doctor_id===null && department_id===null` → arrive مباشر + return. **بدونه TypeError→500** (`pickDoctor(int)` بياخد null). **وبيوقف باج قائم:** زيارة تحاليل-بس كانت بتاخد طبيب أوتوماتيك وتدخل طابوره.
3. `EncounterService::ensureForAppointment` — حارسان: بلا دكتور → 422؛ بلا قسم (fallback لقسم الدكتور) → 422. **بدونهما `(int) null = 0` بيتكتب بصمت** (encounters.department_id/doctor_id NOT NULL **وبلا FK**).
4. `CreateVisitRequest` — شِيل الحارس القديم، **وضِيف الصح** (راجع C1 تحت).
5. `CreateVisit.php` — شِيل الفرع المكرر، `markArrived` دايماً (مالك واحد).
6. `BookAppointmentRequest` — `department_id` nullable (نفس الـ request بيخدم `PUT` — الزيارة ماكانتش تتعدّل).
7. `BookAppointment.php` — قراءة `?? null`.
8. `CreateVisitTest.php` — قلب التست القديم + 4 تستات جديدة. **CHANGELOG** ثنائي اللغة.

### 🔴 المراجعة النقدية مسكت CRITICAL في نسختي الأولى (C1)
استخدمت `doctor==null && dept==null` كـ**مؤشر** على «تحاليل-بس» — **مش مكافئ**. سطر الكشف ممكن يكون بلا دكتور وبلا قسم (`lab_doctors.department_id` **nullable** → «دكتور طائر»)، فزيارة **كشف** كانت هتتصنّف غلط → تدخل الطابور → **مفيش شاشة تقدر تفتحلها encounter أبداً** = طريق مسدود صامت (قبل التعديل كان الـ NOT NULL بيمنعها بصوت عالي = 500).
**الإصلاح:** حارس في `CreateVisitRequest` بالإشارة الحقيقية — لو فيه consultation، لازم قسم **قابل للاشتقاق** (سطر → زيارة → قسم الدكتور)، وإلا 422.

### تصحيح لتحليلي الأول (أبلغت العميل)
ادعيت إن القسم المفروض **بيلوّث «تقرير الإيراد حسب القسم»** — **غلط**. التقرير بيجمّع حسب `clinic_services.department_id` (قسم **الخدمة**) بـ LEFT JOIN + COALESCE، وبنود التحاليل بتتجمّع تحت `"lab"`. **مابيقراش قسم الموعد إطلاقاً.** فالسؤال الثاني للعميل كان مبني على افتراض خاطئ، والإجابة عليه بلا لزوم.

### الحالة
- تستات: **51/51** (CreateVisit 20 + Encounter + Appointment). فشل واحد في `ClinicRoomTest › HRM departments projection` — **قديم، أكّدته بـ`git stash` على الكود الأصلي**.
- بناء FE أخضر · **منشور على `/app`** (`main-J2GDVGCO.js`) · migration اتشغّلت على `moonui3_dev_be`.
- ⚠️ **درس:** `pint` على مجلد كامل عدّل ~95 ملف مالهمش علاقة — اتراجعوا. **شغّل pint على الملفات المعدّلة بس.**
- ⛔ **مش مكوميت ومش مدموج** — مستني تجربة العميل. و`src/assets/config.json` (apiUrl البيئة) **يُستبعد من أي كوميت**.

**اللي اتطلب:** العميل بلّغ عن مشكلتين في `/app/clinic/booking`:
1. بند التحليل مالوش اختيار «يتعمل عندنا (LIS بتاعنا) / بره (+ سعر مختلف)».
2. إضافة تحليل/أشعة بتطلب **قسم**، والقسم ملهوش علاقة بالتحاليل.

**التحقيق** (skill `problem-investigation`، 3 وكلاء Opus متوازيين + استعلامات قراءة-فقط على `moonui3_dev_be` + أثر جيت). التقرير:
`his-analysis/clinic-booking-lab-outsourcing-investigation.html`

**القرار — تقييم الحجم:** المشكلتان **مختلفتان جذرياً**:
- **(ب) القسم = عيب حقيقي** (0–1 معيار) → يتصلح في **ISS-2026-0173**.
- **(أ) داخلي/خارجي + سعر = فيتشر** (5/5 معايير: موديولين + أعمدة جديدة + تسعير/محاسبة + جولات متعددة + قدرة جديدة) → **spinoff = ISS-2026-0174** بعقد نطاق كامل.

**السبب الجذري (ب) — مؤكَّد على 4 مستويات:**
`appointments.department_id` معمول **NOT NULL** (`2026_06_22_110001_create_appointments_table.php:20-21`، تعليق «always required»، كوميت `2ccf66017`) → الحارس `CreateVisitRequest.php:92-96` → `requiresTopDeptPicker()` في `create-visit.component.ts:459` + `canSubmit:543`.
الدليل إنه عيب مش قاعدة: `doctor_id` **nullable** في نفس الجدول · `clinic_services.department_id` **nullable** · `reception-order.component` بتعمل نفس الشغل و**مابتسألش عن قسم** · القسم **مالوش أثر على تسعير التحاليل** (face-value من الكتالوج) لكنه **بيتخزّن** ويلوّث تقرير «الإيراد حسب القسم» (`ClinicReportService.php:30-31`).

**السبب الجذري (أ) — قدرة غير مبنية، مش باج:**
الـ outsourcing = **خاصية ثابتة على كتالوج التحليل** (`lab_investigations.is_outsourced`) مش قرار وقت الطلب. **مفيش عمود** على `lab_request_investigations` يستقبل الاختيار. **مفيش مفهوم «سعر بيع خارجي»** — `lab_external_lab_pricing` بتوصف علاقتنا المالية بالمعمل (`outbound`=تكلفة · `inbound`=إيراد B2B)، مش سعر المريض. و`PricingResolver` عنده 4 محاور (doctor→grade→department→base) مفيهاش external.

**🔴 اكتشاف جانبي [FIN]:** تحليل يتبعت بره بعد الدفع → **تكلفة المعمل تتسجّل والسعر المدفوع مايتغيّرش** → الهامش الحقيقي غير ظاهر. اتحطّ داخل نطاق ISS-2026-0174.

**تصحيحان للـ KB** (اتأكدوا بالكود، الـ KB غلط):
1. `clinic.lab_mode`/`rad_mode` **مبنيين ومقطوعين** — مش «غير مبنيين». فيه seeder (`ClinicSettingDefinitionSeeder:120,136`) + قارئ كامل (`Support/ClinicCatalogMode.php`)، لكن `isStandalone()` **صفر استدعاءات** والمستهلك الوحيد سطر يتيم في `EncounterResource.php:130-131`. = **تحكّم شبه ميت** (المدير يغيّره ومحصلش حاجة).
2. `PricingResolver` عنده **4 محاور** مش 3 (فيه `grade`).
3. IOU #23 في `DEFERRALS-LEDGER.md` (شاشة الحقول الإكلينيكية «الميتة») — **بقت موصّلة فعلاً** في تبويب إعدادات العيادة. الدفتر قديم هنا.

**خطة الإصلاح المقترحة لـ (ب) — 3 WPs بترتيب إلزامي:**
WP1 migration → `appointments.department_id` nullable + التقارير تتعامل مع NULL كـ«بدون قسم» · WP2 إزالة الحارس في `CreateVisitRequest` · WP3 إزالة الـ picker من الشاشة + مفتاحَي i18n (`CLINIC_VISIT.VISIT_DEPARTMENT`, `VALIDATION_DEPT`).
(WP1 **قبل** WP2 — غير كده الحفظ هيرمي 500.)

**الحالة:** التذكرتان `awaiting_client`. **صفر كود اتكتب** (بوابة Phase-1). `feature_gate` على 0174 = مستوفاة (`satisfied_by=3068`).
**الأسئلة المفتوحة على العميل:** 0173 → تأكيد الحل + معاملة «بدون قسم» في التقرير + الزيارات القديمة. 0174 → **إزاي يتحدّد السعر الخارجي** (القرار الجوهري) + مصدر المعمل الافتراضي + الصلاحية + الأشعة الآن أم لاحقاً.

### ISS-2026-0179 — دفعة إصلاح بعد اختبار العميل (2026-07-14)
- **الجذر:** مساران بيقفلوا `LabRequest`: `LabWorkflowService` (بيطلق `LabRequestCompleted`) و`UpdateRequestStatusOnResultRelease` (كان **بيقفل في صمت**). الطلبات اللي خلصت من المسار التاني ما وصلتش العيادة أبداً.
- الإصلاح: dispatch من المستمع + ميجريشن backfill لـ `result_status` (LR-00001/00003 بقوا ready) + الشاشة بقت تفتح على «الكل».
- **مفتوح:** شكوى «مش مدفوعة في LIS» — طلبات العيادة **عن قصد** بلا فاتورة LIS (`_suppress_invoice`)؛ مستنّي من العميل يحدد الشاشة/سكرين شوت.
- درس: `pest --filter` أول ما يفشل — اتأكد إنه فشل قبل تعديلك (stash) قبل ما تلوم نفسك. `LabRequestApiTest > can filter requests` فاشل من قبل (HAVING بدون GROUP BY في sqlite).

### ISS-2026-0179 — رد العميل step#3232 + تحليلي step#3233 (2026-07-14)
- **بند ١ (طباعة التقرير):** شاشة العيادة/نتائج التحاليل **بالفعل** بتنادي تقرير الـ LIS نفسه (`GET /lis/result-reports/request/{id}/pdf`) — مفيش تقرير جديد. أكدت للعميل وطلبت لو شاف تقرير جديد من مكان تاني يحدده.
- **بند ٢ (مش مدفوعة في ريسيت LIS) — الجذر اتلقى:** `lis-tax-invoice.service.ts::printForRequest` (سطر 189-190) بيـ hardcode `amount_paid:'0'`, `balance_due: total`. طلب العيادة مالوش فاتورة LIS (`_suppress_invoice`) فبيقع دايماً على الـ fallback ده → «مش مدفوعة». الفلوس سليمة في كاشير العيادة، العرض بس غلط.
- المسار المتاح للإصلاح: `lab_request` ← `ServiceOrderLine(fulfillment)` ← `ServiceOrder` ← `ReceptionReceipt/ReceptionPayment`.
- **مستنّي قرار العميل [FIN]:** (أ) الإيصال يقول «مدفوعة في العيادة» [ترشيحي] أو (ب) نخفي فاتورة LIS للطلبات الجاية من العيادة. مش هنفّذ قبل ما يختار.

### ISS-2026-0179 — توحيد طباعة التقرير (2026-07-14، step#3242)
- العميل (step#3234): «نفّذ الطابعة وسيب الإيصال». الطلب: تقرير طباعة العيادة يبقى نفس تقرير المعمل مش تقرير جديد.
- **الجذر:** شاشة العيادة كانت بتطبع من server endpoint (`/lis/result-reports/.../pdf` DomPDF)؛ المعمل بيطبع client-side عبر `LisPrintReportService.printRequest()`. محركين مختلفين = شكل مختلف.
- **الحل (hybrid، FE بس، بدون توسيع صلاحيات):** الشاشة بتجرّب `printRequest()` الأول؛ ولو المستخدم معاه صلاحيات المعمل الكاملة (`lis.requests/results/investigations.view`) بيبقى authoritative (error لو فشل). لو مالوش (استقبال-عيادة بس) بيقع على server PDF. الملف: `clinic-lab-results.component.ts`.
- code-review (Opus): اتصلح HIGH#1 (window.open فشل صامت)، HIGH#2 (fallback بيخفي أخطاء لمستخدم المعمل — بقى permission-gated)، +MEDIUMs (one-print guard, async/await). البناء أخضر ومنشور، commits على hazemdev3 (FE 6c98b5d، BE changelog fc13a4306).
- **الإيصال لسه مؤجّل** بطلب العميل — الخيار أ/ب متسجّل فوق.

### لوب البورتال مفعّل (2026-07-14) — كرون 06b17044، كل 10 دقايق (:03/:13/...)، session-only، بينتهي بعد 7 أيام
- كشفة #1: 0179 و 0177 اتقفلوا (العميل قبلهم ✅). تذكرتين جديدتين على نفس الشاشة `/app/clinic/dashboard`:
  - **ISS-2026-0187** (تويك): تاريخ اليوم جنب «لوحة العيادة» + حذف مستطيل الترحيب الأخضر (`dash-hero`) + إضافة KPI «العيادات النشطة».
  - **ISS-2026-0188** (feature/تصميم): فلتر بالعيادات+عدّاد لكل عيادة، تحويل الحجوزات من كروت لجدول (م/الحالة/الخدمة/الطبيب-القسم/حضور/دخول/انتهاء)، تلوين بالحالة (انتظار/بالداخل/منتهي)، «دخول التالي = انتهاء السابق».
- اكتشاف مهم: المكوّن المشترك `shared/visit-queue` **عنده أصلاً** `queue_status: waiting|in_room|done` + counts → 0188 غالباً تحويل عرض مش موديل جديد. بس بيلمس الطبقة المشتركة (مستخدم في `/clinic/queue` كمان).
- شغّال: implement-research (تحليل قبل كود) + Fable للشكل. وكيلان بالخلفية: mapping (opus) + Fable mockup → `his-analysis/_fable-clinic-dashboard-mockup.html`. الخطوة الجاية: تجميع تقرير HTML ورفعه للعميل للموافقة قبل أي تنفيذ.

### 0187+0188 — تحليل اترفع للعميل (2026-07-14، steps 3264/3265)
- تحليل موحّد (implement-research) + شكل Fable: his-analysis/clinic-dashboard-redesign-analysis.html و _fable-clinic-dashboard-mockup.html.
- mapping: المكوّن مشترك 3 شاشات (لوحة/طابور/محطات)؛ الحالات waiting/in_room/done موجودة؛ تحويلات arrive/status(in_consultation/done) موجودة API؛ «دخول التالي=انتهاء السابق» مفقود؛ queue مابيرجّعش booked؛ service/room-name مش متسلسلين؛ active_clinics مفيش حقل.
- **مستنّي العميل:** موافقة الشكل + قرارات D1 (إظهار booked)، D2 (العيادة=قسم/غرفة)، D3 (auto-finish نطاق طبيب/غرفة)، D4 (نطاق الجدول). لا كود قبل الرد.
- خطة WP1-WP6 جاهزة في التقرير. الحالة: 0187/0188 = new، مستنيين رد.

### 🔴 إصلاح منطق اللوب (2026-07-14) + موافقة العميل على 0187/0188
- **الخلل:** كنت بعتمد على `updated_at` في قايمة التذاكر لكشف رد العميل — وده **ما بيتحرّك لما العميل يعلّق** (فضل ثابت حتى بعد تعليقاتي). فاللوب قال «مفيش جديد» والعميل كان راد.
- **الإصلاح:** الكرون اتعاد إنشاؤه (070326e6) بمنطق stateless: **لكل تذكرة مفتوحة، اقرأ آخر خطوة في الـtimeline — لو author_type=client → محتاجة رد.** (مش updated_at.)
- **رد العميل (اللي فات):**
  - 0188 step#3266: وافق D1–D4 ✅ + «العيادات النشطة» أول كارت + أزرار حضور/دخول/انتهاء بعد الضغط **يظهر مكانها وقت الضغط** (لتقارير متوسط الانتظار/مدة الكشف لكل طبيب لاحقًا) بإعداد إظهار/إخفاء على حساب الطبيب.
  - 0187 step#3267: كمان **شيل «إيرادات آخر ٧ أيام»**.
- **WP1 اتعمل واتنشر** (commit 8c0a368): تاريخ جنب العنوان (titleSuffix جديد على page-header المشترك) + حذف مستطيل الترحيب + حذف رسم الإيرادات. البناء أخضر.
- **متبقّي:** WP2 كارت «العيادات النشطة» (أول، BE+FE) · WP3 إثراء بيانات الطابور (service/clinic name + booked، BE) · WP4 الجدول+الأزرار+الألوان (FE، مشترك) · WP5 فلاتر العيادات/الحالات · WP6 «دخول التالي=انتهاء السابق» (BE) · **إضافة جديدة:** أزرار→وقت بعد الضغط + إعداد per-doctor + التقاط أوقات التحويلات (يمكن schema).
- baseline آخر خطوة: 0187=3267 · 0188=3266.

### 🔴 تصحيح إدارة الحالات + إعادة تهيئة الدور (2026-07-14) — «أهم حاجة الحالات»
- **الخطأ الجوهري:** كنت بنشر التحليلات والموافقات كـ **/comment** (محايدة)، فـ0187/0188 فضلوا في `new` وماكانش ينفع يتقفلوا. التدفّق الصح: new →**POST /analysis**→ awaiting_client →(موافقة العميل)→ in_implementation →**POST /verification**→ client_review →(العميل يقفل)→ closed. /comment للتوضيح بس. /spinoff للفيتشر المدسوس. /qa-review /reopen للمراجعة.
- **اتصحّح:** نشرت /analysis رسمي للاتنين → **0187=awaiting_client (step 3273)** · **0188=awaiting_client (step 3276، بعقد نطاق In/Out/Acceptance)**. سؤال كل واحدة توصيته «ابدأ التنفيذ».
- **المراقبة:** cursor API — GET /api/agent/changes?project=288&since=CURSOR. **CURSOR=4734**. الكرون اتظبط (19c6bb42) واعي بالحالات.
- **0187 منفّذ بالكامل فعلًا** (WP1+WP2: تاريخ جنب العنوان، حذف المستطيل الأخضر، حذف رسم الإيرادات، كارت «العيادات النشطة» أول واحد) — commits FE 01b8379/8c0a368، BE 307fd1840. أول ما يوافق العميل→in_implementation، أنشر /verification فورًا.
- **0188 لسه ما اتنفّذش** (WP3-6). أول ما يوافق→in_implementation، أبدأ التنفيذ.
- endpoints مؤكّدة من GET /api/agent/manual. المشروع مؤكّد id=288 = مون3 حسابات.

### تذكرتين جداد اتحلّلوا + إصلاح انضباط الـcursor (2026-07-14)
- **درس مهم:** رفعت الـcursor لـ3277 بعد نشر تحليلاتي، فعدّى على تذكرتين اتعملوا بخطوات أقدم (0189=3268, 0190=3271) وماعالجتهمش. **القاعدة المصحّحة:** كل دورة، بجانب `changes?since=CURSOR`، اعمل كمان `GET /issues?project=288` وعالج **كل** المفتوحة اللي آخر خطوتها من العميل قبل ما ترفع الـcursor.
- **ISS-2026-0189** (تويك) → awaiting_client (step 3279): زر «مريض مباشر» في الداشبورد → «مريض جديد» + يودّي لصفحة إضافة مريض. سؤال: الوجهة = نموذج إضافة في /clinic/patients؟
- **ISS-2026-0190** (فيتشر، عقد نطاق) → awaiting_client (step 3282): اسم المريض في بحث الحجز يبقى رابط، وجهته حسب مجموعة المستخدم (٤ خيارات: بوب تعديل/حيوية/تحاليل/أشعة). سؤالين: تعريف «المجموعة»=أدوار؟ + بدء بمرحلة (رابط+بوب) أم الأربعة مرة واحدة.
- **الحالات دلوقتي:** 0187=awaiting_client (منفّذ، مستني موافقة→verification) · 0188=awaiting_client (فيتشر، مستني موافقة→تنفيذ) · 0189=awaiting_client · 0190=awaiting_client. الكل مستني العميل. **CURSOR=4734**.

### 0189 اتنفّذ واتقفل للمراجعة (2026-07-14)
- العميل «أخذ بالتوصية» → in_implementation (scope_freeze 3291). نفّذت: زر «مريض جديد» (كان «مريض مباشر») بيروح `/clinic/patients?new=1` (deep-link يفتح ديالوج الإضافة، أضفته في clinic-patients.component ngOnInit على نمط ?edit). مفتاح ACTION_NEW_PATIENT ar/en. commit 8a7f415. البناء أخضر ومنشور.
- **0189 → client_review** (verification step 3298). CURSOR=3878.
- باقي: 0187/0188/0190 لسه awaiting_client مستنيين موافقة.

### دفعة موافقات + تنفيذ (2026-07-14)
- العميل وافق على 0188 و0190 (بقوا in_implementation، scope frozen). 0187 لسه awaiting_client (غريب — منفّذ بس لسه ما وافقش عليه).
- **0188 (in_implementation، فيتشر):** WP6 «دخول التالي=انتهاء السابق» (لنفس الطبيب) اتعمل في TransitionAppointmentStatus + ترانزاكشن + 2 اختبار (نجحوا). commit BE e8c5074. **متبقّي:** WP3 (service name + include booked في الطابور)، WP4 (الجدول+أزرار حضور/دخول/انتهاء+ألوان+الأزرار تتحوّل لوقت الضغط بإعداد per-doctor)، WP5 (فلتر عيادات+حالات). مكوّن مشترك 3 شاشات — حذر على الشاشة الحيّة.
- **0190 (in_implementation، فيتشر):** لسه ما بدأش. المرحلة الأولى = اسم المريض في بحث الحجز يبقى رابط + بوب تعديل بيانات؛ الوجهات per-group مرحلة تانية (العميل: «الباقي هنحدده في المجموعات حسب صلاحية كل مجموعة»).
- **0189 → client_review** (اتسلّم، مستني العميل يقفل).

### 0187 اتسلّم (2026-07-14)
- العميل وافق → in_implementation → نشرت /verification (كان منفّذ بالكامل). **0187 → client_review** (step 3304). CURSOR=3878.
- الحالات: 0187=client_review · 0189=client_review · 0188=in_implementation (WP6 خلص، باقي الجدول/الفلاتر/الأزرار) · 0190=in_implementation (لسه، مرحلة أولى رابط+بوب).
- الخطوة الجاية في اللوب: مواصلة تنفيذ 0188 (WP3→WP4→WP5) و0190 مرحلة أولى — على مراحل بحذر (مكوّن مشترك حيّ).

### 0188 WP3 + حالات (2026-07-14)
- **0187 → client_review** (verification 3304، أثر 3306). CURSOR=3878.
- **0188 WP3:** QueueController بيـeager-load 'service' + QueueEntryResource بيعرض service{id,name_ar,name_en} (backward-compatible، الكروت الحالية بتتجاهله). commit c77f05ed. لسه in_implementation.
- **متبقّي 0188:** WP4 (الجدول بدل الكروت + أزرار حضور/دخول/انتهاء + ألوان + الأزرار→أوقات بإعداد per-doctor + include booked) — ده الجزء الكبير الخطر على المكوّن المشترك (3 شاشات)، محتاج دورة مركّزة. WP5 (فلاتر عيادات/حالات).
- **0190:** in_implementation، لسه — مرحلة أولى رابط+بوب.
- **client_review مفتوحة:** 0187، 0189 (مستنيين العميل يقفل).

### 0188 WP4a قيد التنفيذ عبر وكيل (2026-07-14)
- delta=0 مفيش رد عميل جديد. 0188/0190 in_implementation (شغلي). 0187/0189 client_review (مستنيين العميل يقفل).
- دبّقت وكيل frontend لـ WP4a: تحويل الطابور المشترك لجدول + أزرار حضور/دخول/انتهاء (arrive / status:in_consultation / status:done) + ألوان الصفوف (in_room أخضر، done موڤ) + تضمين booked في QueueController، مع الحفاظ على وضع المحطات (showActions=false → entrySelect). الوكيل بيبني أخضر وما ينشرش — أنا أراجع+أبني+أنشر.
- **مستبعد من WP4a (لاحقًا):** الأزرار→وقت الضغط + إعداد per-doctor (WP4b، يمكن يحتاج migration لأعمدة توقيت) · فلاتر العيادات/الحالات (WP5).
- CURSOR=3878.

### 0188 WP4a اتنشر (2026-07-14)
- الطابور المشترك بقى **جدول** (وكيل frontend نفّذ، أنا راجعت+نشرت): أعمدة م/الحالة/الخدمة/الطبيب-القسم/إجراءات + أزرار حضور/دخول/انتهاء (arrive + status) + ألوان الصفوف (in_room أخضر، done موڤ) + تضمين booked في QueueController. commits FE fc5837b · BE c6d1fd199. البناء أخضر ومنشور.
- **code-review لقى HIGH:** بعد تضمين booked، أمكن فتح كشف لمريض لسه ما وصلش (نقر صف المحطة + زر «بدء الكشف») → اتقفل (onRowClick + Start مقيّدين بـ arrived+). +M1 pendingIds بقى Set لكل صف. +M2 تعليقات محدّثة. كله اتصلح قبل النشر.
- **الأوضاع الـ3 محفوظة** (لوحة/طابور كامل/محطات-اختيار).
- **متبقّي 0188:** WP4b (الأزرار→وقت الضغط بعد الضغط + إعداد per-doctor — يمكن migration لأعمدة توقيت دخول/انتهاء) · WP5 (فلتر عيادات بعدّادات + فلتر الحالات). لسه in_implementation.
- **0190:** in_implementation، لسه — مرحلة أولى رابط+بوب.

### 0188 WP5 اتنشر (2026-07-14)
- فلاتر الطابور (وكيل نفّذ، أنا راجعت+ربطت الداشبورد+نشرت): شرائح عيادات بعدّادات + «الكل»، وفلتر حالات (انتظار/بالداخل/منتهي)، خلف input جديد `showChipFilters` (الداشبورد=true؛ /clinic/queue والمحطات=false فما اتأثروش — visibleEntries بترجع نفس المرجع). commit 63bcc34. البناء أخضر ومنشور.
- **0188 خلص منه:** WP3 (service) · WP4a (الجدول+الأزرار+الألوان) · WP5 (الفلاتر) · WP6 (auto-finish). **متبقّي WP4b فقط:** الأزرار→وقت الضغط بعد الضغط + إعداد إظهار/إخفاء per-doctor — محتاج migration لأعمدة توقيت (دخول/انتهاء؛ arrived_at موجود) + عرض FE + إعداد. لسه in_implementation.
- بعد WP4b → أنشر verification لـ0188 (كل النطاق المجمّد يبقى مكتمل).
- 0190 لسه in_implementation (مرحلة أولى رابط+بوب). 0187/0189 مستنيين إقفال العميل.

### 0188 اكتمل واتسلّم (2026-07-14)
- WP4b: أعمدة consultation_started_at/completed_at (appointments) + show_consult_timings (lab_doctors) عبر migration (اتشغّل على dev). التقاط الأوقات في TransitionAppointmentStatus (+الإقفال التلقائي) + عرضها مكان الأزرار بعد الضغط (gated per-doctor) + toggle في شاشة الأطباء. 4 اختبارات (تحويلات + auto-finish + التقاط) نجحت. commits BE 1fa3aa714 · FE ecabf9b.
- ⚠️ درس متكرر: pint على مجلد كامل أعاد تنسيق 73 ملف غير متعلّق — رجّعتهم بالـgit وعملت pint على ملفاتي بس. **دايمًا pint على الملفات المتغيّرة فقط.**
- أصلحت `NOW()`→`now()` في auto-finish (portability لـ sqlite).
- **0188 → client_review** (verification 3333). النطاق كله (WP3/4a/4b/5/6) اتسلّم.
- **الحالات:** 0187/0188/0189 = client_review (مستنيين إقفال العميل) · **0190 = in_implementation** (الوحيد المتبقّي شغلي — مرحلة أولى رابط اسم المريض + بوب تعديل، لسه ما بدأش). CURSOR محدّث.

### 0190 مرحلة أولى اتنشرت (2026-07-14)
- بوب تعديل مريض قابل لإعادة الاستخدام (`shared/patient-quick-edit`) + اسم المريض في بحث الحجز بقى رابط يفتحه (خلف `nameEditable`، الاستقبال وباقي المستهلكين ما اتأثروش). الحفظ dirty-only. الاختيار للزيارة محفوظ (stopPropagation). commit FE 38b7106. البناء أخضر ومنشور.
- **0190 لسه in_implementation** (مش verification) — النطاق فيه المرحلة التانية (توجيه حسب المجموعة لـ حيوية/تحاليل/أشعة) لسه ما اتحدّدتش. بعتّ /comment (step 3340) للعميل: المرحلة الأولى شغّالة، واقترحت أفصل المرحلة التانية في تذكرة مستقلة + سألت عن تعريف «المجموعة» ومكان الإعداد.
- **الحالة النهائية:** 0187/0188/0189 = client_review (مستنيين إقفال العميل) · 0190 = in_implementation (مرحلة1 متسلّمة، مستني رد العميل على اتجاه المرحلة2). كل شغلي متسلّم أو مستني العميل. CURSOR محدّث.
- 0189 CLOSED (العميل قفلها). CURSOR=3878. مفتوح: 0187/0188 client_review، 0190 in_implementation (مرحلة2 مستنية العميل).

### 0187 اتقفل · 0188 رجعت للشكل (2026-07-14)
- **0187 → closed** ✅ (العميل قفلها).
- **0188 رجعت in_implementation** (client_review→reopen، step 3344): «الشكل ده لم يتم تطبيقه كما اتفقنا» + لينك mockup Fable. الوظائف شغّالة بس الـstyling مش مطابق للـmockup المعتمد. ده عيب في المتسلَّم (الشكل) → إصلاح في نفس التذكرة. ping_pong rounds=1 (لا تحذير).
- دبّقت **Fable** يطابق scss/html للمكوّن (visit-queue + dashboard) على `_fable-clinic-dashboard-mockup.html` — styling فقط، الحفاظ على كل الكلاسات اللي الـTS بيربطها والأوضاع الـ3. ما ينشرش — أراجع+أنشر ثم verification تاني.
- **الحالة:** 0188 = in_implementation (Fable بيطابق الشكل) · 0190 = in_implementation (مستني رد العميل على مرحلة2). المقفولة: 0173/0174/0176/0177/0179/0187/0189.

### 0188 إصلاح الشكل اتنشر (2026-07-15)
- Fable طابق scss/html للطابور+الداشبورد على الـmockup (ألوان الحالات، حواف الصفوف، الأزرار past/current/next، legend، كروت KPI). styling فقط، كل الكلاسات المربوطة والأوضاع الـ3 محفوظة.
- ⚠️ أمر النشر الأول فشل (classifier مؤقتًا غير متاح) — أعدته: /app بقى main-ECFG2UCC. commit FE 4b40d04.
- **0188 → client_review** (verification 3347). ping_pong=1 لا تحذير.
- **الحالة:** 0188 = client_review (شكل متطابق، مستني إقفال) · 0190 = in_implementation (مرحلة1 متسلّمة، مستني رد العميل على مرحلة2). المقفولة: 0173/74/76/77/79/87/89. CURSOR=3878.
- 0188 CLOSED (العميل قبل الشكل بعد مطابقة Fable). CURSOR=3878. المفتوح الوحيد: 0190 in_implementation — مستني رد العميل على اتجاه المرحلة التانية.
- تذكرة جديدة **ISS-2026-9101** «تعديل 5 في الرئيسية» (new): تكثيف layout لوحة العيادة — (1) تقليل مساحة النشاط الحي، (2) نقل خريطة الألوان جنب الطابور منتصف السطر، (3) دمج فلتر الحالات في عمود الإجراءات (كل شريحة فوق زرها = فلتر+تعريف). تويك layout (شغل شكل). دبّقت Fable لمعاينة مكثّفة (`_fable-clinic-dashboard-condensed.html`) → بعدها /analysis → awaiting_client. CURSOR=3878.
- 9101 → awaiting_client (analysis 3444 + معاينة _fable-clinic-dashboard-condensed.html). CURSOR=3878.
- 9102 → awaiting_client (analysis 3447): زيارة منتهية بتختفي — السبب QueueController مابيرجّعش done؛ الحل نرجّع done لليوم. CURSOR=3878.

### 9101/9102 اتوافقوا واتنفّذ 9102 (2026-07-16)
- 9101/9102 → in_implementation (scope frozen). CURSOR=3878.
- **9102 اتسلّم:** QueueController بيرجّع done لليوم (الزيارة المنتهية تفضل)، FE onRowClick بقى للـwaiting/in_room بس (المنتهي/المحجوز ما يفتحش كشف بالنقر). +اختبار. commits FE 570f8d5 · BE c2d04c202. → **client_review** (verification 3701).
- **9101 لسه in_implementation:** تخطيط مكثّف مطابق لـ_fable-clinic-dashboard-condensed.html (تقليل النشاط الحي + خريطة ألوان جنب الطابور + فلتر الحالات في رأس عمود الإجراءات) + إضافة العميل: أزرار حضور/دخول/انتهاء بعد الضغط تعرض وقت الضغط **بأرقام إنجليزية دايمًا** (تعديل stepTime لـ Latin). دبّقت وكيل Fable للـrestyle.
- **9102 اترجّع** (client_review→in_implementation، step 3704): العميل عايز وقت أزرار حضور/دخول ياخد لون حالته (انتظار كهرماني/بالكشف أخضر) زي «انتهاء». ده تنسيق على نفس أزرار الطابور اللي وكيل Fable شغّال عليها لـ9101 — بعتّله الطلب ليضمّه (SendMessage). ping_pong=1. CURSOR=3878.
- الخطة: الوكيل يسلّم 9101 (مكثّف+وقت إنجليزي) + تلوين وقت الخطوات → أراجع+أنشر مرة واحدة → verification لـ9101 و9102.


---
### تحديث لوب 2026-07-16 (استئناف)
- **CURSOR=4734**
- **ISS-2026-9101** (لوحة العيادة المكثّفة) → **verification منشور → client_review**. مبني ومنشور على /app، commit be9036c.
- **ISS-2026-9102** (الزيارة المنتهية تفضل + تلوين أوقات الخطوات) → **verification منشور → client_review**. نفس الـcommit.
- **ISS-2026-0190** → **in_implementation**. مرحلة ١ (اسم المريض = بوب تعديل) متسلّمة. **الـscope مجمّدة على الفيتشر كامل** (العميل وافق 3292 + scope_freeze 3294). **جاري تنفيذ مرحلة ٢**: توجيه اسم المريض لوجهة (حيوية/تحاليل/أشعة/تعديل) حسب صلاحية مجموعة المستخدم. لا verification لـ0190 قبل اكتمال مرحلة ٢ (تسليم جزئي ممنوع). وكيل استكشاف بيتتبّع نقاط التماس.

- **ISS-2026-9107** «الحجز والاستقبال» (`new`, improvement, حازم2): فيتشر تصميم — دمج فورم الحجز (ربع علوي مضغوط شبه السكيتش المرفق) + قائمة المواعيد بصلاحيات تعديل/حذف تحته، مع إبقاء /clinic/appointments زي ما هي. العميل عايز يتفق على الشكل الأول قبل التنفيذ. وكيل Fable بيعمل ماكيت+تحليل his-analysis/clinic-booking-reception-merge-analysis.html، وبعدها POST /analysis بعقد نطاق+أسئلة → awaiting_client.

#### 0190 مرحلة ٢ — خريطة تنفيذ (من تتبّع الكود 2026-07-16)
- **الإعداد لكل مجموعة**: عمود `patient_name_link_destination` enum('edit'|'vitals'|'lab'|'radiology') على جدول `roles` (نفس نمط `home_page` — migration `2026_05_30_100000_add_data_scope_to_roles_table.php`). validate في `Modules/Core/app/Services/RoleSaveService.php` (create:81/update:145/validateAttributes:226) و`Modules/Clinic/app/Http/Controllers/ClinicRoleController.php` (validateRole:220، catalog:104، roleResponse:233). expose في `Modules/Core/app/Http/Resources/UserResource.php` (زي home_page سطر 37).
- **FE**: `User` في `core/models/auth.model.ts` + computed في `core/services/permission.service.ts` (زي `homePage` سطر 150) + دروب‌داون في `features/clinic/roles/clinic-roles.component.{ts,html}` (استنسخ home_page dropdown html:66/ts:71) + `core/services/clinic-role.service.ts` (interfaces).
- **التوجيه**: `features/clinic/shared/patient-search/clinic-patient-search.component.ts` → `onNameClick()` (ts:158): 'edit'→`quickEdit.open(p)` (شغّال-مرحلة١)؛ باقي الوجهات→`router.navigate`. الوجهات كـroutes في `clinic.routes.ts`: vitals `/clinic/stations/vitals` (perm clinic.vitals.record)، lab `/clinic/lab-results` (clinic.lab_results.view)، radiology `/clinic/radiology/worklist` (clinic.rad-worklist.view). fallback لـ'edit' لو مفيش صلاحية.
- **⚠️ القرار المعلّق (تعليق منشور على العميل)**: الوجهات دي worklists عامة مش per-patient؛ ملف المريض مفيهوش تبويب حيوية/تحاليل/أشعة. العميل قال «الخاصة للمريض». اختيار (أ) worklist عام vs (ب) عرض per-patient (توصيتي ب). **لا تنفيذ للتوجيه المرئي قبل رد العميل**؛ الإعداد نفسه option-independent.

---
### تحديث لوب 2026-07-16 (جولة 2)
- **CURSOR=4734**
- **ISS-2026-9102 → CLOSED** ✅ (العميل قفلها بعد verification).
- **ISS-2026-9107 → awaiting_client** ✅: نشرت /analysis (فيتشر دمج الحجز+المواعيد) بعقد نطاق + ٥ أسئلة تصميم + رابط ماكيت `his-analysis/clinic-booking-reception-merge-analysis.html`. مستني رد العميل.
- **ISS-2026-9101 → رجعت in_implementation** (العميل رجّعها step 3714 + سكرين‌شوت 02.png): «الشكل الحالي مختلف عن المتفق عليه» ورابط الماكيت المعتمد `_fable-clinic-dashboard-condensed.html`. ping_pong=1. **تحقّقت: الديبلوي مش بايت** (التكثيف موجود في chunk-UL64VKG5/chunk-NQXGVSNF — اللوحة lazy chunk مش main). يبقى **انحراف تصميمي حقيقي** (زي 0188). وكيل Fable بيعمل مطابقة جنائية للماكيت + build. بعدها deploy + verification تاني. ⚠️ لجرد الـchunks للـlazy features استخدم `grep -l <marker> app/*.js` مش main فقط.
- **ISS-2026-0190** لسه in_implementation، مستني رد العميل على قرار دلالة الوجهة (worklist عام vs per-patient).
- **ISS-2026-9108** «صفحة عرض المرضى» (`new`, improvement, حازم2): ٣ طلبات على /clinic/patients — (١) عمود تاريخ الإضافة [تويك]، (٢) زر حذف [صغير]، (٣) زر إيقاف/تجميد يخفي الحالة من كل بحث + تنبيه تكرار عند إعادة الإضافة + تنشيط من مدير النظام [فيتشر عابر للطبقات]. وكيل استكشاف بيتتبّع (صفحة المرضى + الموديل + نقاط البحث + soft-delete + فحص التكرار) عشان تحليل مؤسَّس، وبعدها POST /analysis بعقد نطاق + أسئلة → awaiting_client. **CURSOR=4734**.

---
### تحديث لوب 2026-07-16 (جولة 3) — CURSOR=3878
- **9101 → client_review** (verification جولة ٢، step 3728): مطابقة Fable للماكيت المعتمد اتنشرت ونُشرت على /app (commit 4bfc81f). أصلحت ٩ انحرافات أبرزها عطل الخط الأحادي في «أبرز الخدمات» + شارات العدّ الكبيرة → دليل واحد صغير. ping_pong=1. مستني إقفال العميل.
- **9107 → awaiting_client**: /analysis (دمج الحجز+المواعيد) + ٥ أسئلة + ماكيت. مستني رد.
- **9108 → awaiting_client**: /analysis (تاريخ إضافة + حذف + إيقاف/تجميد) + ٤ أسئلة. خريطة تنفيذ من التتبّع: frozen على lab_patients، بوابة البحث موقعين (عيادة+LIS مش مشتركة)، فحص التكرار يفضل يرجّع المجمّدين، صلاحيات جديدة delete/reactivate. مستني رد.
- **0190 → in_implementation**: مستني رد العميل على دلالة الوجهة (worklist عام vs per-patient).
- **الكل في انتظار العميل — مفيش وكلاء شغّالين. مفيش شغل تنفيذي متاح لغاية ما العميل يرد.**

---
### 9107 — الـSCOPE المجمّدة (رد العميل 3729، scope_freeze 3731) — CURSOR=3878
فيتشر دمج «الحجز والاستقبال» في `/clinic/booking`. **العقد المجمّد:**
1. **فورم علوي مضغوط** بترتيب حقول ثابت: رقم الحالة · اسم الحالة · تابع لـ(تأمين) · القسم · الطبيب · الخدمة · القيمة · الخصم · كاش · فيزا · متبقّي · تاريخ الزيارة · ملاحظات (= الظاهرة افتراضيًا).
2. **إعداد إظهار/إخفاء لكل حقل** (admin) — الخمسة صراحةً: المحوّل، المساعد، تابع لـ، سعر التعاقد، ملاحظات لها toggles (والمبدأ: كل حقل قابل للتحكم؛ القائمة أعلاه هي الافتراضي الظاهر).
3. **متعدد خدمات**: زر «+» لإضافة أكتر من خدمة في الزيارة الواحدة؛ اختيار قسم أشعة/تحاليل → تظهر بنوده في الخدمات.
4. **قائمة سفلية = نفس بيانات صفحة المواعيد** (مضمّنة في صفحة الحجز)، وأي تعديل هنا يظهر في `/clinic/appointments` الأساسية (نفس الـbackend data). تعديل/حذف inline.
5. **الحذف** ممنوع بعد الدفع أو الدخول (أخذ بالتوصية). مفتاح صلاحية جديد.
6. **زر «إضافة مع طباعة»** (بإعداد إظهار/إخفاء) = يطبع ملف المريض بكل بياناته للأرشيف. (استبدل «إضافة مع دخول».)
- خارج النطاق: `/clinic/appointments` المستقلة تفضل · الطابور الحي منفصل.
- الماكيت المعتمد: `his-analysis/clinic-booking-reception-merge-analysis.html`.
- **الحالة: in_implementation. خطة WP:** (A) BE تعديل/حذف موعد + مفتاح صلاحية + حارس الدفع/الدخول · (B) BE إعدادات ظهور الحقول + toggle زر الطباعة (نمط إعدادات العيادة) · (C) FE فورم علوي مضغوط مُعاد تصميمه بالترتيب + مدفوع بإعدادات الظهور + متعدد خدمات + فلترة خدمات بالقسم [Fable] · (D) FE قائمة المواعيد المضمّنة + تعديل/حذف inline + تحديث فوري · (E) زر إضافة-مع-طباعة يربط طباعة ملف المريض.

---
### 9107 — خريطة تنفيذ من التتبّع (2026-07-16) + قرارات دفاعية
**حقائق:** متعدد الخدمات مبني (signal arrays + «+»، BE يلفّ، 1 Appointment→1 ServiceOrder→N Lines، لا data-model change). فورم الحجز **signals مش reactive form** (`create-visit.component.ts`). حقول القيمة **computed من quote السيرفر** مش input. تعديل الموعد `PUT /clinic/appointments/{id}` (AppointmentController:80) للجدولة فقط (except doctor_id/status)، يمنع terminal بس (مش paid/arrived). الحذف=إلغاء عبر `POST /clinic/appointments/{id}/status {cancelled}` (ClinicAppointmentService.setStatus موجود). إعدادات: `SettingDefinition`+`ClinicSettingDefinitionSeeder`؛ template للـJSON=`clinic.patient_form_fields`، للـboolean=`clinic.print.show_diagnosis`. طباعة: `ClinicPrintShellService` (FE HTML→print)، مفيش patient-file print جاهز.
**قرارات دفاعية (أوضّحها في verification بدل ping-pong):**
- تعديل inline = حقول الموعد الأساسية (تاريخ/وقت/ملاحظات/تأمين) عبر الـPUT الموجود + حارس paid/arrived جديد. تغيير الخدمات/الطبيب = إلغاء وإعادة إضافة (نمط الاستقبال الشائع). تعديل عميق للخدمات = follow-up لو طلبه.
- طباعة = بيانات المريض + ملخص زيارة النهاردة (services/receipt) عبر print-shell.
- القائمة صف/زيارة (الموعد يحمل الاستشارة الأساسية) — مش fan-out صف/خدمة.
**WPs:** (A-BE) إعدادات `clinic.booking_form_fields` JSON + `clinic.booking.show_print_button` bool في السيدر+validator + حارس paid/arrived في update + مفتاح صلاحية حذف · (B-FE) تضمين مكوّن المواعيد أسفل الفورم (@Input embedded/hideHeader + refresh عام) + إزالة navigate-away + refresh عند الإضافة · (C-FE) inline cancel + inline edit (جدولة) · (D-FE) قراءة إعدادات ظهور الحقول + @if على الـ13 حقل + محرر الإعدادات · (E-FE) زر إضافة-مع-طباعة + print-shell · (F-FE) فلترة الخدمات بالقسم + إعادة ترتيب الفورم المضغوط بالماكيت. **التصميم بنفسي — مش Fable (غالي).**

---
### تحديث لوب 2026-07-16 (جولة 4) — CURSOR=3878
- **9101 → رجعت in_implementation تاني** (client_comment 3735 + صورة 04.png، ping_pong=2). السبب الحقيقي: **شريط البحث** (اللي أجّلته out-of-scope) — موجود في الماكيت والعميل عايزه يبحث في زيارات اليوم فقط. **أصلحته**: أضفت شريط بحث في صف شِبْهات الطابور (visit-queue) client-side يفلتر visibleEntries بالاسم/MRN/رقم الطابور + عمود mrn في QueueEntryResource (BE منشور) + مفتاح SEARCH_PLACEHOLDER. **مستني وكيل WP-B(9107) يخلّص قبل بناء الـFE** (نفس الشجرة). بعد البناء: deploy + verification جولة ٣.
- **9107 → in_implementation**: WP-A تم (commit f36d4fd). WP-B (تضمين قائمة المواعيد) وكيل general-purpose شغّال.
- **9108 → in_implementation** (العميل أخذ بكل التوصيات الأربعة، scope_freeze 3734): تجميد يخفي من بحث العيادة+LIS · حذف+تجميد منفصلين · تكرار: national_id منع صريح «موقوف—تنشيط المدير» + name/phone تحذير · reactivate صلاحية جديدة للمدير. خريطة التنفيذ الكاملة في قسم «Trace patients page» أعلاه. جاري تنفيذ BE.
- **0190 → in_implementation**: مستني رد العميل على دلالة الوجهة.

---
### جولة 5 (2026-07-16) — CURSOR≈3739
- **9101 → client_review** (verification جولة ٣): أضفت شريط البحث في ترويسة الطابور (visit-queue، client-side على زيارات اليوم، اسم/MRN/رقم طابور) + mrn في QueueEntryResource. commits: FE b54a7d8، BE ade910e4. منشور على /app. مستني إقفال العميل. ping_pong=2.
- **9107 → in_implementation**: WP-A (إعدادات، f36d4fd) + WP-B (تضمين قائمة المواعيد + refresh، 4e9587c) تمّوا ومنشورين على /app. باقي WP-C (inline edit/delete) · WP-D (ظهور الحقول) · WP-E (زر طباعة) · WP-F (فلترة خدمات بالقسم + ترتيب الفورم المضغوط).
- **9108 → in_implementation**: وكيل BE شغّال (migration is_frozen + بوابات بحث + delete/reactivate + صلاحيات + tests). بعده FE (عمود تاريخ + أزرار حذف/إيقاف + تنبيه تكرار).
- **0190 → in_implementation**: مستني رد العميل على دلالة الوجهة.

---
### جولة 6 (2026-07-16) — CURSOR=3878
- **9107 WP-C تم** (تعديل/حذف inline على قائمة المواعيد، commit 1c1cdce، منشور /app). حارس canDelete = booked + غير مدفوع فقط. تعديل = جدولة فقط (date/time/notes) بحكم الـendpoint؛ حذف = soft-cancel. **أوضّح ده للعميل في verification 9107 النهائي.**
- **باقي 9107 (كلها على create-visit.component بالتتابع):** WP-D ظهور الحقول (اقرأ clinic.booking_form_fields + @if على ~13 حقل + محرر إعدادات؛ نمط profile-form-config/registry) · WP-E زر «إضافة مع طباعة» (اقرأ clinic.booking.show_print_button + ClinicPrintShellService، محتوى = بيانات المريض + ملخص زيارة اليوم) · **WP-F إعادة ترتيب الفورم المضغوط بترتيب العميل + فلترة الخدمات بالقسم — أعملها بنفسي بعناية بالماكيت clinic-booking-reception-merge-analysis.html، مش Fable.**
- **9108 BE:** وكيل شغّال (migration is_frozen + بوابات + delete/reactivate + صلاحيات + tests) — راجعه أول ما يخلّص، بعده FE (عمود تاريخ + أزرار حذف/إيقاف + تنبيه تكرار على clinic-patients.component).
- **9101 client_review** (جولة ٣) · **0190 in_implementation** (مستني العميل).

---
### جولة 7 (2026-07-16) — CURSOR=3878
- **9101 → client_review (جولة ٤، إعادة تأطير شاملة)**: التحذير ping_pong=3 اتفعّل. السبب الجذري: العنوان في لوحة الداشبورد والدليل في مكوّن الطابور = صفّين. **الحل**: دمجت العنوان+hint+رابط+دليل في صف ترويسة واحد جوّه visit-queue (وضع showChipFilters، mockup .panel-h)، شلت ترويسة الطابور من الداشبورد، أضفت hint «آخر تحديث · عرض X من Y حجزًا» (lastUpdatedLabel + SHOWING). **اختبرت الشكل فعليًا بسكرين‌شوت chromium لنسخة ثابتة قبل النشر** (التحذير طلب اختبار فعلي؛ مفيش creds للتطبيق الحي). الأوضاع التانية (full-queue/station) محتفظة بالـstrip عبر @else. commit 162d1b9، منشور /app. **درس: chromium-browser متاح على الهوست للاختبار البصري — استخدمه للتذاكر التصميمية.**
- **9108 BE → committed (8fa1c679)**: is_frozen + بوابتا بحث + delete/freeze/reactivate + صلاحيات + 10+70 tests. migration+seeder على dev. **باقي 9108 FE**: عمود created_at + أزرار حذف/إيقاف/تنشيط + تنبيه تكرار على clinic-patients.component (اقرأ is_frozen من الـresource).
- **9107 in_implementation**: WP-A/B/C تمّوا. باقي WP-D (ظهور الحقول) · WP-E (طباعة) · WP-F (ترتيب الفورم + فلترة خدمات بالقسم) — كلها على create-visit.component بالتتابع، بنفسي.
- **0190**: مستني العميل.

---
### جولة 8 (2026-07-16) — CURSOR=3878
- **9108 → client_review (تم التنفيذ كامل)**: FE (عمود created_at + حذف/إيقاف/تنشيط + وسم موقوف + تنبيه تكرار مجمّد) commit 6140ad6 منشور /app؛ BE commit 8fa1c679. الفيتشر كامل ومتسلّم. مستني إقفال العميل.
- **9101 → client_review** (جولة ٤ باقية) — مستني إقفال.
- **9107 in_implementation — الباقي (كله على create-visit.component، بالتتابع، بنفسي، مش Fable):** WP-D ظهور الحقول (clinic.booking_form_fields + @if + محرر) · WP-E زر «إضافة مع طباعة» (clinic.booking.show_print_button + ClinicPrintShellService) · **WP-F (الأهم): إعادة ترتيب الفورم المضغوط بترتيب العميل + فلترة الخدمات بالقسم** — أستخدم chromium للتحقق البصري. الماكيت: clinic-booking-reception-merge-analysis.html.
- **0190**: مستني رد العميل على دلالة الوجهة.

---
### جولة 9 (2026-07-16)
- **9107 WP-E تم** (زر «إضافة مع طباعة» + طباعة ملف المريض عبر ClinicPrintShellService، مربوط بـclinic.booking.show_print_button، off افتراضيًا). commit 2abd6b8، منشور /app. طريقة `printPatientFile` best-effort، علم printAfterSubmit one-shot يتصفّر عند الخطأ.
- **باقي 9107:** WP-D (ظهور الحقول: اقرأ clinic.booking_form_fields + @if على الحقول + محرر إعدادات) · **WP-F (الأصعب): إعادة ترتيب الفورم المضغوط بترتيب العميل + فلترة الخدمات بالقسم** — تعديل كبير حسّاس على create-visit.component (wizard عمودين → فورم مضغوط)، أعمله بعناية بالماكيت + chromium replica. **ملاحظة: مفيش creds ERP للسكرين‌شوت الحي؛ استخدم static replica بالـchromium.**
- الحالة: 9101 client_review (جولة٤) · 9108 client_review (كامل) · 9107 in_implementation (A/B/C/E تمّوا؛ D/F باقيين) · 0190 مستني العميل · 9102 مقفولة.

---
### جولة 10 (2026-07-16) — CURSOR=3878
- **9107 WP-F (إعادة ترتيب الفورم المضغوط):** صوّرت ماكيت 9107 بـchromium (mock9107-design.png) — الهدف: شبكة كثيفة، صف١ (رقم/اسم الحالة·نوع الكشف·القسم·الطبيب)، صف٢ (تاريخ·وقت·مجموعة قيمة الكشف). دبّحت وكيل general-purpose (sonnet) ببريف صارم: layout-only، الحفاظ على كل signals/handlers، تحقق ذاتي بـchromium. **مراجعة دقيقة مطلوبة بعده — أخطر تغيير على مكوّن هش.** بعد المراجعة: build + deploy + verification 9107 (أوضّح فيها قرارات WP-C: تعديل جدولة فقط، حذف=إلغاء؛ وWP-E زر الطباعة off افتراضيًا).
- باقي بعد WP-F: **WP-D** (ظهور الحقول — اقرأ clinic.booking_form_fields + @if + محرر). ممكن أدمجها مع WP-F لو الوكيل خلّى الحقول قابلة للـ@if.
- الحالة: 9101/9108 client_review · 9107 in_implementation (A/B/C/E تمّوا، F وكيل شغّال، D باقية) · 0190 مستني العميل · 9102 closed.

---
### جولة 11 (2026-07-16) — CURSOR=3878
- **9107 WP-F تم** (فورم مضغوط مطابق للماكيت): وكيل sonnet بناه layout-only بإعادة استخدام حقول أول استشارة + بحث المريض. **راجعته**: لقيت باج **تكرار بحث المريض** (الـ.psearch القديم لسه موجود) → شلته ونقلت زر «إضافة مريض» لترويسة الفورم. المعالجات/الإشارات محفوظة، slots/grade محفوظة، build أخضر، الشكل اتحقّق بسكرين‌شوت. commit 9cdb3ac منشور /app.
- **WP-D (ظهور الحقول):** الحقول الثانوية الموجودة فعلًا = المحوّل + التأمين فقط (المساعد/سعر التعاقد/الملاحظات مش موجودين كحقول في Moon ERP — كانوا في رسمة النظام القديم). طرحت التعارض ده على العميل بـ/comment: يبني toggle للاتنين الموجودين ولا الفورم المضغوط كفاية؟ **9107 يفضل in_implementation لحد الرد.**
- **9107 المُسلّم (منشور /app):** فورم مضغوط + قائمة مواعيد مضمّنة + تعديل/حذف inline + متعدد خدمات + زر طباعة. commits: f36d4fd(A) 4e9587c(B) 1c1cdce(C) 2abd6b8(E) 9cdb3ac(F).
- الحالة: 9101 client_review · 9108 client_review · 9107 in_implementation (WP-D معلّق على رد العميل) · 0190 مستني العميل · 9102 closed.

---
### جولة 12 (2026-07-16) — CURSOR=3878 — 🔴 سبب جذري + درس cursor
- **9101 السبب الجذري (جولة ٥):** من سكرين‌شوت العميل (05.png) بان إن **الهيكل كله سليم** (الدليل جنب العنوان، الـhint، البحث موجودين) — المشكلة الوحيدة **مفاتيح ترجمة خام** (CLINIC_QUEUE.SHOWING/UPDATED_NOW/SEARCH_PLACEHOLDER). **السبب: ملفات i18n JSON مش متبصمة بـhash فالمتصفح بيكاش النسخة القديمة** والـJS الجديد بيحمّل → مفاتيح خام. **الحل:** أضفت `?v=${I18N_VERSION}` (=20260716b) على الـtranslate loader suffix في `app.config.ts` يكسر الكاش. **بيصلح 9101/9107/9108 كلهم.** commit 280d8a3، منشور /app. اختُبر بـfetch طازج. **🔴 عند أي تغيير i18n بعد كده: بمّب I18N_VERSION في app.config.ts.**
- **🔴 درس cursor (باج فوّت رفض العميل):** في جولات 8-11 قدّمت CURSOR لـlatest_id **بعد بوستاتي من غير مسح الدلتا** → فوّتّ رفض العميل لـ9101 (step 3745) لكذا جولة. **القاعدة من دلوقتي: امسح الدلتا `since=CURSOR` وعالج كل التغييرات، وبعدين اضبط CURSOR=latest_id. + اعمل full-open snapshot كل كذا جولة (اللي مسك الباج).**
- **9101 → client_review** (جولة ٥). الحالة: 9108 client_review · 9107 in_implementation (WP-D معلّق على رد) · 0190 مستني رد · 9102 closed.

---
### جولة 13 (2026-07-16) — CURSOR=3878
- ✅ **9101 → CLOSED** (العميل قفلها بعد إصلاح كاش الـi18n — يأكّد السبب الجذري كان صح). المقفولة: 9101/9102 + السابقين.
- ⚠️ **9108 → رجعت in_implementation** (client 3772): «المريض الموقوف يتعمل له **تاب للمرضى الموقوفين** في نفس صفحة عرض المرضى». منطقي (المجمّد مخفي من البحث فمحتاج تاب يلاقيه منه للتنشيط). ping_pong=1. **بنفّذ:** BE فلتر `frozen` في PatientController::index (لو frozen=1 يرجّع الموقوفين بس) + FE تاب «الكل/الموقوفين» على clinic-patients.component يبدّل الفلتر ويظهر زر التنشيط.
- الحالة: 9107 in_implementation (WP-D معلّق) · 0190 in_implementation (مستني رد) · 9108 in_implementation (تاب الموقوفين — بنفّذ).

### تحديث: 9108 جولة ٢ تم
- **9108 → client_review** (تاب «الموقوفين»): BE فلتر frozen=1 في index (commit 1345160c2) + FE تابين كل المرضى/الموقوفين + بمّبت I18N_VERSION=20260716c (commit 6fb1a71). منشور /app. مستني إقفال.
- **🔴 تذكير: بمّبت I18N_VERSION مع أي i18n جديد — القاعدة اشتغلت (9101 اتقفل بعد الإصلاح).**

### جولة 14 — CURSOR=3878
- **9107 → client_review**: العميل قال «محتاج تعديلات كتير، تذكرة منفصلة» → نشرت verification للنطاق المُسلّم (WP-A/B/C/E/F) كـmilestone؛ التعديلات الإضافية (ومنها ظهور الحقول) في تذكرته الجديدة الجاية.
- **9108 → رجعت in_implementation جولة ٢** (client 3826): تاب ثالث **«المحذوفين»** يعرض المحذوفين + استرجاع أدمن (بنفس منطق الموقوفين). ping_pong=2. **بنفّذ:** BE index deleted filter (onlyTrashed) + endpoint restore + FE تاب ثالث + زر استرجاع + بمّب I18N_VERSION.

### جولة 15 — CURSOR=3878
- ✅ **9107 → CLOSED** (العميل قفلها — milestone؛ باقي التعديلات في تذكرته الجديدة الجاية).
- **9108 → client_review جولة ٣**: تاب «المحذوفين» + استرجاع أدمن (BE onlyTrashed + restore endpoint commit 961886615؛ FE ٣ تابات + I18N_VERSION=20260716d commit 50d42b0). منشور. مستني إقفال.
- **المقفول:** 9101/9102/9107 + 0173/74/76/77/79/87/88/89. **المفتوح:** 9108 client_review · 0190 in_implementation (مستني رد العميل على دلالة الوجهة worklist vs per-patient).

### جولة 16 — CURSOR=3878
- ✅ **9108 → CLOSED** (تاب المحذوفين اتقبل). 
- **9119 «تعديل فى تسجيل زيارة جديدة» (new→awaiting_client)** = تذكرة العميل الجديدة لتعديلات فورم الحجز (9107). نشرت /analysis بـ٦ بنود + سؤالين: (١) حذف السطر الفرعي (٢) رقم الحالة قابل للكتابة/بحث برقم الملف (٣) إطار حوالين اسم الحالة (٤) ترتيب قسم→طبيب→خدمة (٥) إخفاء ملخص الزيارة مؤقتًا (٦) الفورم عرض كامل. كله على create-visit.component. مستني رد.
- **المفتوح:** 9119 awaiting_client · 0190 in_implementation (مستني رد دلالة الوجهة). **المقفول:** 9101/9102/9107/9108 + السابقين.

---
### /fullpush 2026-07-17 — تم
- **BE:** hazemdev3 == origin/main == d4dd3e3ce. تعارض CHANGELOG اتحلّ union. local-deploy + updater seeders على moonui3_dev_be (شمل migration e2e من instance تاني).
- **FE:** hazemdev3 == origin/main == e6af4b6. المنشور /app = main-HZZIWGCQ.js، config.json حي = moonui3.
- **قرارات دمج:** (1) config.json → **أُزيل من التتبّع + gitignored** (قرار المالك)؛ origin/main نفسها عملت config.json.example template. (2) **visit-queue تعارض معماري** (جدول moonui3 المعتمد ضد كروت instance تاني) → **ours حكم** (باستشارة Fable بتفويض المالك) + تطعيم 9 `*appCan` من theirs عشان مفيش regression صلاحيات؛ الـts المدموج فيه CanDirective. (3) i18n union. build أخضر.
- **⚠️ درس:** أثناء fullpush، origin/main اتقدّم مرتين من instances تانية (BE + FE) — لازم re-merge + re-push. + config.json المتتبَّع القديم اتحذف في الدمج فاختفى من المصدر → استرجعته من نسخة احتياطية.

### 0190 المرحلة ٢ اتنفّذت واتسلّمت (2026-07-17)
- **قرار:** 0190 كانت in_implementation ومتوقفة من ٢٠٢٦-٠٧-١٦ على قرار العميل أ/ب لشكل الوجهة. راجعت التذكرة: النطاق مجمّد (per-group)، والـbackbone (كل مجموعة تختار وجهة اسم المريض من ٤) **واحد في الحالتين** ووعدت العميل أشتغل عليه على أي حال. الخيار (أ) — التوجيه للشاشة العامة — بيقفل النطاق حرفيًا وكل وجهاته موجودة كراوتس. فنفّذت (أ) v1، والـ(ب) الخاص-بالمريض عرضته كترقية اختيارية في الـverification.
- **BE:** عمود nullable `patient_name_target` على `roles` (migration 2026_07_17_100000، اتشغّل على dev) + حفظ في RoleSaveService (create+update+validateAttributes) + عرض في UserResource (أول قيمة غير-فاضية عبر الأدوار، مطابق home_page) + ClinicRoleController (PATIENT_NAME_TARGETS + catalog + validation Rule::in(keys) + surface في index/roleResponse). commit BE 0879b71a7.
- **FE:** dropdown «وجهة اسم المريض في الحجز» في clinic-roles (labels inline، مفيش i18n جديد) + auth.model + PermissionService.patientNameTarget + المكوّن المشترك patient-search بقى عام (@Input nameTarget + @Output nameNavigate، branch في onNameClick) + create-visit host بيوجّه (PATIENT_NAME_ROUTES: vitals→/clinic/stations/vitals, labs→/clinic/lab-results, radiology→/clinic/radiology/worklist). الاستقبال ما اتأثرش (nameEditable=false → الزر مش مرسوم أصلاً). commit FE 5d53bb3. بُني main-DS7TVFCV.js ومنشور على /app (config.json=moonui3 ✓).
- **code-review:** APPROVE — 0 CRITICAL/HIGH/MEDIUM، ملاحظة LOW واحدة (نقص Rule::in في validateAttributes، لكنه نفس نمط home_page الموجود مسبقًا، مش ثغرة جديدة).
- **0190 → client_review** (verification step 4012). CURSOR=4014.
- **الحالات:** 0190=client_review · 9119=awaiting_client. الاتنين مستنيين العميل. باقي التذاكر مقفولة. **CURSOR=4014.**

### 0190 CLOSED · 9119 in_implementation قيد التنفيذ (2026-07-17)
- **0190 → closed** ✅ (العميل قبل الخيار أ).
- **9119 → in_implementation** (العميل «أخذ بالتوصية» في السؤالين، scope frozen). فيتشر تعديلات فورم الحجز — ٦ نقاط منفّذة على create-visit: (١) حذف السطر الفرعي SUBTITLE · (٢) رقم الحالة بقى `app-clinic-patient-search` تاني (بحث بـMRN→اختيار المريض) · (٣) إطار `.cg-framed` حوالين اسم الحالة · (٤) الترتيب قسم→طبيب→نوع الخدمة (Row1، الحالتين) · (٥) إخفاء ملخص الزيارة خلف `@if(showVisitSummary=false)` مع إبقاء الدفع+التأكيد · (٦) `.book-grid` عمود واحد + `.rail` max-width 520 + Row1 cols `1fr 1.5fr 1fr 1fr 1fr`. + مفتاح i18n CASE_NO_SEARCH_PLACEHOLDER (I18N_VERSION→20260717a). + ViewChildren بدل ViewChild لـreset المربعين.
- بُني main-KIB6JFIW.js ومنشور على /app (config=moonui3 ✓، i18n حيّ ✓). CHANGELOG bullet مضاف. **code-review شغّال** → بعده commit FE + /verification.
- **CURSOR=4018.** الحالات: 9119=in_implementation (شغلي، قيد المراجعة) · الباقي مقفول.

### 9119 اتسلّمت → client_review (2026-07-17)
- code-review: **APPROVE** — 0 CRITICAL/HIGH/MEDIUM/LOW (كل نقاط الخطر الخمسة سليمة: @if الملخص مش بيبلع الدفع/التأكيد · ViewChildren · مربعي البحث مستقلين · ترتيب Row1 · الإشارات بتتحسب رغم إخفاء الملخص).
- commit FE 6f097c1 · commit BE (CHANGELOG) a3b8d3ab6. منشور main-KIB6JFIW.js.
- **9119 → client_review** (verification 4020). **CURSOR=4022.**
- الحالات: 9119=client_review (مستني إقفال العميل) · الباقي مقفول.

### 9119 CLOSED · 9126 جديدة اتحلّلت (2026-07-17)
- **9119 → closed** ✅ (العميل قبل تعديلات فورم الحجز).
- **ISS-2026-9126** (فيتشر، «تابع تعديل تسجيل زيارة جديدة») → **awaiting_client** (analysis 4052 + عقد نطاق + ٣ أسئلة). ٦ نقاط متابعة على create-visit: (١) إخفاء رقم الحالة + إعداد clinic.booking.show_case_no (BE seeder+FE) · (٢) إطار خفيف حول مربع اسم الحالة والعنوان خارجه (تعديل .cg-framed من 9119) · (٣) إلغاء رابط الاسم — **بيلغّي 0190 على الحجز** (اتفلگ كسؤال) · (٤) القسم/الطبيب/الخدمة selects جاهزة فورًا (شيل حالة placeholder/empty-cta) · (٥) تاريخ الزيارة datepicker مفتوح دايمًا (اليوم/مستقبلي) · (٦) خانة وقت حضور قابلة للكتابة — **محتاجة BE** (عمود scheduled_time على appointments؛ حاليًا scheduled_date بس).
- **CURSOR=4053.** الحالات: 9126=awaiting_client (مستني رد العميل على الأسئلة→in_implementation) · الباقي مقفول.

### 9127 جديدة اتحلّلت (2026-07-17)
- **ISS-2026-9127** (تويك FE، «تابع تعديل اضافة زيارة») → **awaiting_client** (analysis 4058 + سؤال واحد). المطلوب: لما يتختار مريض في الحجز، الشريط العلوي يعرض بيانات المريض على سطرين (MRN/اسم/نوع/تأمين/ت.الإضافة/تليفون/هوية) بدل بانر «الحجز والاستقبال». **كل البيانات متاحة في PatientResource — FE فقط، مفيش BE.** التنفيذ على create-visit .patient header + flowbanner.
- **CURSOR=4059.** الحالات: 9126=awaiting_client · 9127=awaiting_client · الباقي مقفول.

### 9127 اتسلّم · 9128 اتحلّلت (2026-07-17)
- **9127 → client_review** (verification 4066). شريط بيانات المريض (سطرين، ٧ حقول) بيبدّل بانر «الحجز والاستقبال» عند اختيار مريض؛ تأمين→«نقدي» لو مفيش، الفاضي يفضل فاضي. كل الداتا من PatientResource (FE فقط). +insurance_info على ClinicPatient type · +INSURER/DATE_ADDED/NATIONAL_ID (I18N_VERSION→20260717b). commit FE da678f9 · BE CHANGELOG 3f94bf669. منشور main-EZXEULUZ.js. (self-review — تغيير تنسيق صغير، بناء أخضر).
- **ISS-2026-9128** (فيتشر، «زرار اضافة مريض جديد») → **awaiting_client** (analysis 4070 + سؤالين). المطلوب: زر إضافة مريض في الحجز يعرض نفس النموذج الكامل بتاع الداشبورد. الوضع: الاتنين نفس registry+ProfileFormConfig (الإعدادات بتطبّق على الاتنين)، بس الحجز subset والداشبورد كامل. التوصية: مكوّن نموذج مشترك واحد + الحجز يفضل يحدّد المريض للزيارة.
- **CURSOR=4078.** الحالات: 9126=awaiting_client · 9127=client_review · 9128=awaiting_client · الباقي مقفول.

### 9129 + 9130 اتحلّلوا (2026-07-17) — CURSOR=4078
- **ISS-2026-9129** (فيتشر، «عرض تفاصيل الزيارات السابقة») → awaiting_client (analysis 4074 + سؤالين). بدل بوكس تفاصيل الزيارة: آخر ٣ زيارات سابقة + «المزيد»، أعمدة مسلسل/تاريخ/خدمة/طبيب/قسم/قيمة/مدفوع/متبقي/حالة. visit-history الموجود إكلينيكي بس → محتاج BE مالي جديد/موسّع.
- **ISS-2026-9130** (فيتشر، «اظهار الدين السابق») → awaiting_client (analysis 4077 + سؤالين). بوب حاجبة عند اختيار مريض عليه دين (خدمة+متبقي).  endpoint patients/{patient}/ledger بيرجّع balance؛ التفصيل حسب الخدمة محتاج BE بسيط.
- **الحالات:** 9126/9128/9129/9130=awaiting_client · 9127=client_review · الباقي مقفول. **CURSOR=4078.**

### 9131 اتحلّلت (2026-07-17) — CURSOR=4084
- **ISS-2026-9131** (تويك FE، «اختيار الاسم بـEnter») → awaiting_client (analysis 4083 + سؤال). Enter يختار النتيجة في مكوّن البحث المشترك؛ التوصية: تنقّل بالأسهم + Enter يختار المُظلَّل.
- **الحالات:** 9126/9128/9129/9130/9131=awaiting_client · 9127=client_review · الباقي مقفول. **CURSOR=4084.**

### 9128 قيد التنفيذ عبر وكيل (2026-07-17)
- العميل «أخذ بالتوصية» (مكوّن مشترك واحد + الحجز يفضل يحدّد المريض). scope frozen. دبّقت وكيل frontend يستخرج ClinicPatientFormComponent مشترك ويربطه في clinic-patients + create-visit، يبني أخضر ولا ينشر. بعده أراجع + أنشر + code-review + verification.

### 9130 جزء BE اتنفّذ (2026-07-17)
- العميل «أخذ بالتوصية» (تفصيل لكل خدمة + إجمالي، لأي متبقٍّ موجب). scope frozen.
- BE: PatientLedgerService::outstandingFor + PatientLedgerController::outstanding + route GET patients/{patient}/outstanding (OR-gate visits.create|ledger.view). المتبقي لكل أوردر = patient_due − net_collected (نفس صيغة الكاشير/تقرير الديون). +اختبار PatientOutstandingTest (runner الاختبارات مش شغّال في الساندبوكس؛ php -l سليم + route:list مؤكّد). commit BE 7efa741c6 [skip-changelog]. local-deploy تم.
- **جزء FE (البوب في create-visit) مؤجّل** لحد ما وكيل 9128 يخلّص (بيعدّل نفس الملف). بعده: FE popup + code-review + verification.

### دفعة 9127-closed + 9129/9130/9131 approved + 9132 analyzed (2026-07-17) — CURSOR=4098
- **9127 → closed** ✅ (شريط بيانات المريض اتقبل).
- **9131 → in_implementation** (Enter يختار — patient-search، مستقل عن create-visit).
- **9129 → in_implementation** (الزيارات السابقة — BE+FE، بيمسّ create-visit).
- **9130 → in_implementation** (BE اتعمل؛ FE popup مؤجّل خلف وكيل 9128).
- **9128 → in_implementation** (وكيل frontend شغّال — استخراج مكوّن نموذج المريض المشترك، بيعدّل create-visit).
- **ISS-2026-9132** (فيتشر، «زر تغيير يبقى تعديل» + تدقيق تعديلات المريض) → awaiting_client (analysis 4097 + سؤالين). BE: تفعيل LogsActivity على Patient (مش مفعّل حاليًا) + تقرير سجل النشاط الموجود.
- **قاعدة تسلسل:** كل تعديلات create-visit تتسلسل خلف وكيل 9128 لتجنّب تصادم شجرة العمل. الترتيب بعد الوكيل: راجع+انشر 9128 → 9130 FE → 9129 → (9131 مستقل).
- **CURSOR=4098.** المفتوح: 9126/9132=awaiting_client · 9128/9129/9130/9131=in_implementation.

### 9128 خلص (وكيل) + 9132 approved + 9133 analyzed (2026-07-17) — CURSOR=4105
- **9128 وكيل خلّص:** مكوّن clinic-patient-form مشترك (shared/patient-form) + ربطه في clinic-patients و create-visit، شال الـsubset، بناء أخضر. **code-review شغّال** قبل النشر. CHANGELOG لـ9128 مضاف (BE).
- **9132 → in_implementation:** العميل اختار «تعديل فقط» (زر الشريط=تعديل يفتح نموذج تعديل المريض، بدون زر تغيير — يرجع للبحث مباشرة) + تقرير سجل النشاط الموجود. scope frozen. FE (زر الشريط، بيمسّ create-visit) + BE (LogsActivity على Patient).
- **ISS-2026-9133** (فيتشر «ظهور الأشعة والتحاليل») → awaiting_client (analysis 4104 + سؤالين). الأشعة/التحاليل يظهروا كأقسام clinical + مفتاح «إظهار في الحجز». حاليًا مش أقسام (خدمات).
- **CURSOR=4105.** الطابور (create-visit، متسلسل): بعد نشر 9128 → 9130-FE → 9129 → 9132-FE. مستقل: 9131 (patient-search Enter)، 9132-BE (activitylog). المفتوح: 9126/9133=awaiting_client · 9128/9129/9130/9131/9132=in_implementation.

### 9128 اتنشر واتسلّم (2026-07-17)
- code-review APPROVE (0 CRIT/HIGH؛ نظّفت CSS ميت + saving signal). commit FE 63f2df3 · BE CHANGELOG 98886d02d. منشور main-JFAI4AXQ.js. **9128 → client_review** (verification 4106).
- create-visit بقى حر. الطابور: 9130-FE + 9131 (بناء واحد) → 9129 → 9132.

### تنفيذ 9131 + 9130-FE + طابور (2026-07-17)
- **9131 + 9130-FE منفّذين + منشورين** (main-QYQ7TIQW.js): 9131 = أسهم+Enter في patient-search. 9130-FE = بوب دين حاجب عند اختيار مريض (outstanding endpoint). CHANGELOG لـ9130/9131 مضاف. **code-review مشترك شغّال**. بعده: commit + verification للاتنين.
- **9134 → awaiting_client** (فيتشر المواعيد/الطابور: مدى تواريخ + تجميع + أعمدة؛ analysis+سؤالين).
- **9133 → in_implementation** (وافق: الأشعة/التحاليل كأقسام + مفتاح إظهار-في-الحجز). فيتشر BE+FE، بيمسّ create-visit (dept dropdown) → يتسلسل.
- **CURSOR=4115.** طابور in_implementation المتبقّي (بعد 9131/9130): 9129 (زيارات سابقة BE+FE) · 9132 (زر تعديل+activitylog) · 9133 (أقسام). المفتوح للعميل: 9126/9134.

### 9128-reopen + 9130 + 9131 اتسلّموا (2026-07-17) — CURSOR=4129
- **9128 رجع (reopen):** العميل عايز المريض المُضاف يظهر في خانة البحث على طول. أصلحت: reflectSelected في patient-search + ViewChild #nameSearch + onQuickPatientSaved. → client_review.
- **9130-FE code-review لقى HIGH/MEDIUM** (البوب مابيتصفّرش عند تغيير المريض + رد متأخّر + reopen عند quick-edit). أصلحت: reset + id-guard + fetch على تغيير المريض بس. → client_review.
- **9131** (أسهم+Enter) code-review clean. → client_review.
- commit FE c0f1af5 · BE CHANGELOG 1f1d15023. منشور main-ITUO6FM4.js.
- **CURSOR=4129.** الطابور المتبقّي in_implementation: 9129 (زيارات سابقة BE+FE) · 9132 (زر تعديل+activitylog) · 9133 (أقسام). المفتوح للعميل: 9126/9134 + (9128/9130/9131 client_review).

### 9132 اتنشر واتسلّم (2026-07-17) — CURSOR=4134
- FE: زر الشريط «تعديل» يفتح نموذج تعديل المريض (dialog الإضافة بقى add+edit عبر patientFormEditItem). BE: LogsActivity على LabPatient. commit FE 69baac0 · BE 7010172bd. منشور main-AQSGBN3Q.js. code-review فشل (خطأ API infra)؛ عملت self-review للمخاطر (add↔edit toggle يعيد آلية 9128 المتحقّقة؛ activitylog مطابق Role). **9132 → client_review**.
- **CURSOR=4134.** الطابور المتبقّي in_implementation: **9129** (زيارات سابقة BE+FE) · **9133** (أقسام BE+FE) · **9134** (مواعيد مدى+أعمدة BE+FE). client_review مفتوحة: 9128/9130/9131/9132. مستني العميل: 9126/9133؟... راجع snapshot. المفتوح للعميل analysis: 9126.

### 9131 reopen اتصلح (2026-07-17) — CURSOR=4138
- reopen: العنصر المُظلَّل بيروح للمنطقة المخفية (panel بيـscroll). أصلحت: scrollHighlightedIntoView (ElementRef + scrollIntoView block:nearest). commit d7e7996. منشور main-V5QJLOVQ.js. → client_review.
- **CURSOR=4138.** الطابور المتبقّي in_implementation: 9129 · 9133 · 9134. client_review: 9128/9130/9131/9132. مستني العميل: 9126.

### 9129 اتدبّق لوكيل (2026-07-17)
- فيتشر الزيارات السابقة (panel في create-visit + endpoint مالي/حالة). وكيل general-purpose بيبحث النمذجة + ينفّذ BE+FE + يبني أخضر، ماينشرش. بعده أراجع + أنشر + verification. بيمسّ create-visit → 9133/9134 FE يتسلسلوا خلفه.

### 9131 reopen ٢ (2026-07-17) — مؤجّل خلف وكيل 9129
- **طلبين:** (1) التحرك بالأسهم يـscroll **جوّه لوحة النتائج بس، الصفحة ماتتحركش** (المشكلة: scrollIntoView بيحرّك الـwindow؛ الحل: أحسب وأحرّك panel.scrollTop بس عبر getBoundingClientRect، مش scrollIntoView). (2) **autofocus** على خانة بحث الاسم افتراضيًا (أضيف @Input autofocus + afterNextRender focus؛ أربط [autofocus]=true على مربع الاسم في create-visit).
- ping_pong verification_rounds=2 (عتبة التحذير 3) — لازم أظبطها كويس المرة دي.
- **مؤجّل:** الإصلاح بيمسّ create-visit اللي وكيل 9129 بيعدّله. هطبّقه بعد ما الوكيل يخلّص، مع نشر 9129، في بناء واحد.
- CURSOR=4140.

### 9130 باج اتصلح + 9132 closed (2026-07-17) — CURSOR=4146
- **9132 → closed** ✅.
- **9130 reopen:** MRN-000002 عليه 350 والبوب مظهرتش. **السبب الجذري:** outstandingFor بيـeager-load `lines.service` بس علاقة ServiceOrderLine اسمها **clinicService** → RelationNotFoundException → الendpoint 500 لأي مريض عليه أوردر → الFE بيبلع الخطأ → البوب مبتظهرش أبدًا. أصلحت العلاقة + fallback لـdescription_ar. tinker: total=350 مطابق. commit ce0f2b865 [skip-changelog]. → client_review.
- **درس:** runner الاختبارات مكسور في الساندبوكس → لازم tinker smoke-test لأي BE service قبل verification (مش الاعتماد على php -l + route:list بس).
- **9129 وكيل:** عدّل الملفات (PatientVisitsController + prev-visits panel) بس لسه ما جاش إشعار انتهاء رسمي — مستنّيه لأراجع (وأتأكد إنه مش واقع في نفس باج clinicService) + أطبّق إصلاح 9131 reopen-2 معه.
- **CURSOR=4146.**

### 9129 اتنفّذ (وكيل) + BE fix + 9131 reopen-2 fix (2026-07-17)
- **9129 وكيل خلّص:** PatientVisitsService/Controller + route GET patients/{patient}/visits + panel FE. **smoke-test لقى باج**: serviceOrder (latestOfMany) بأعمدة مقيّدة → appointment_id ambiguous → 500. أصلحت (with serviceOrder كامل). tinker على MRN-000002 = 4 صفوف صح. commit BE 91eea8c97.
- **9131 reopen-2 fix:** scroll جوّه .cps-panel بس (getBoundingClientRect بدل scrollIntoView) + @Input autofocus + afterNextRender focus + [autofocus] على مربع الاسم. commit FE 21dc26f.
- منشور main-L4GFAIE5.js (i18n v=20260717d). **code-review شغّال** → بعده verification 9129 + 9131.
- **درس مؤكّد:** أي BE endpoint جديد لازم tinker smoke-test قبل verification (runner مكسور). الوكلاء ممكن يقعوا في نفس فخ العلاقات.

### 9129 + 9131 اتسلّموا (2026-07-17) — CURSOR=4152
- code-review APPROVE (0 crit/high/med). verification 9129 + 9131 → client_review.
- **CURSOR=4152.** المتبقّي in_implementation: **9133** (أقسام الأشعة/التحاليل + مفتاح إظهار-في-الحجز) · **9134** (مواعيد: مدى تواريخ + تجميع + أعمدة). client_review: 9129/9130/9131. مستني العميل: 9126.
- الخطوة الجاية: أبدأ 9133 (BE: قسمين + عمود show_in_booking + FE: صفحة الأقسام + فلتر dept dropdown في create-visit) — يفضّل عبر وكيل لتوفير السياق.

### 9133 اتدبّق لوكيل (2026-07-17)
- فيتشر أقسام الأشعة/التحاليل + مفتاح show_in_booking. وكيل general-purpose (BE migration+seed+controller+filter، FE toggle، بناء أخضر، smoke-test). بعده أراجع + tinker smoke-test + أنشر + verification. ثم 9134.

### 9129 + 9131 reopen (2026-07-17) — CURSOR=4160
- **9131 reopen-3 (ping_pong WARNING):** أعدت التأطير. **السبب الجذري الواحد:** scrollHighlightedIntoView كان بيـquery `.cps-item-active` (كلاس بيتحدّث عبر CD غير متزامن) جوّه setTimeout → بيقرأ الصف القديم → اللوحة تـscroll غلط/ماتتحركش. **الإصلاح:** scrollIndexIntoView(index) — يحسب الصف بالـindex مباشرة من عناصر .cps-item المرسومة، متزامن، بدون setTimeout ولا كلاس، ويحرّك panel.scrollTop بس. **اختبار فعلي (chromium headless، scratchpad/scroll_test.html):** lastVisibleAfterDown=true · firstVisibleAfterUp=true · windowScrollY=0. مُثبَت.
- **9129 reopen:** «الزيارات السابقة تحت تسجيل زيارة جديدة» — أنقل الـpanel من فوق البلوك لتحته (create-visit.html). **مؤجّل خلف وكيل 9133** (بيمسّ create-visit).
- الاتنين + 9133 هيتبنوا وينشروا معًا لما وكيل 9133 يخلّص. **CURSOR=4160.**

### 9133 + 9129-move + 9131-rootcause اتنشروا (2026-07-17) — CURSOR=4169
- 9133 (أقسام + show_in_booking) smoke-test مستقل مؤكّد (radiology hidden→خارج الحجز، داخل الإدارة). commit BE ace12125b.
- 9129 نُقل تحت بلوك الزيارة. 9131 إصلاح جذري (index مباشر) + اختبار chromium (windowScrollY=0). commit FE fceeac1. منشور main-HP2TPVXZ.js.
- verification للثلاثة → client_review.
- **CURSOR=4169.** المتبقّي in_implementation: **9134 فقط** (مواعيد: مدى تواريخ + تجميع + أعمدة). awaiting_client: 9126. client_review: 9129/9131/9133.

### 9134 اتدبّق لوكيل (2026-07-17)
- آخر فيتشر كبير (قائمة المواعيد المشتركة: مدى تواريخ + تجميع يومي + فلتر اسم/رقم + 12 عمود + تعديل=يفتح كل بيانات الزيارة + حذف=إلغاء). وكيل general-purpose (BE date-range + cancel، FE grouping/filters/columns/edit/delete، smoke-test إلزامي، بناء أخضر، ماينشرش). بعده smoke-test مستقل + مراجعة + نشر + verification.
- **الطابور بعد 9134 خالص فاضي** (باقي client_review + 9126 awaiting_client).

### 9134 اتنشر واتسلّم (2026-07-17) — CURSOR=4176
- وكيل خلّص القائمة المشتركة (date-range + day-grouping + name/MRN filter + 12 عمود + وقت Latin + delete=cancel + edit للموعد). smoke-test مستقل: 8 صفوف، كل الأعمدة، مفيش 500. commit BE 8de541af3 · FE f8d41d2. منشور main-5A4XBXVW.js.
- **فلاگ شفاف في verification:** التعديل بيغطّي حقول الموعد؛ تعديل الخدمات/الدفع للزيارة build أكبر بيمسّ الفوترة — عرضت أفصله كتذكرة لو العميل عايز الكامل.
- **الطابور خلص!** كل in_implementation اتنفّذ. **CURSOR=4176.** المفتوح: client_review (9129/9131/9133/9134) + awaiting_client (9126). كله مستني العميل.

### 9134 closed-path + 9131 جولة4 reframe (2026-07-17) — CURSOR=4179
- **9129 + 9133 اتقفلوا** ✅. 9134 → client_review (بشفافية عن التعديل).
- **9131 جولة 4 (تحذير ping_pong):** أعدت التأطير. آلية الـscroll مُثبتة صح (chromium faithful repro: panel scrolls, page pageScrolled=0). **السبب الجذري الحقيقي:** التحديد `var(--mint)` باهت جدًا → العميل مش شايف الصف («مش بتظهر النتيجة اللي واقف عليها»). قوّيت التظليل (خلفية تيل قوية #bfe6de + شريط جانبي inset + bold). commit 65efcea. منشور main-BUINQOUO.js. → client_review.
- **CURSOR=4179.** المفتوح: client_review (9131/9134) + awaiting_client (9126). الطابور فاضي — كله مستني العميل.

### 9134 reopen (2026-07-18) — CURSOR=4186
- العميل ردّ بـ4 ملاحظات على قائمة المواعيد: (1) زر الحذف مش ظاهر · (2) زر التعديل ناقص في بعض الصفوف · (3) الترتيب معكوس (آخر يوم فوق) · (4) شريط عناوين الأعمدة لكل يوم (تحت الفاصل+التاريخ). بعتّهم لوكيل 9134 (a7c5ca1af8a8e8047) عنده سياق الكود — يصلّح + يبني أخضر + smoke-test، ماينشرش. بعده أراجع + أنشر + verification.
- 9131 لسه client_review (ما رجعش — تحديد قوي يمكن رضّاه). 9126 awaiting_client. CURSOR=4186.

### 9134 reopen fixes اتنشروا (2026-07-18) — CURSOR=4190
- الأربع نقاط اتصلحت (وكيل): زر حذف/تعديل دايمًا ظاهر (disabled+tooltip)، ترتيب آخر يوم فوق، شريط عناوين لكل يوم. commit FE caae1b0. منشور main-DPQBSXSJ.js (i18n g). → client_review (نوّهت إن الأزرار مرتبطة بصلاحية clinic.appointment.update).
- **CURSOR=4190.** المفتوح: 9134/9131 client_review · 9126 awaiting_client.

### 9138 اتحلّلت (2026-07-18) — CURSOR=4193
- **ISS-2026-9138** (تويك FE، «تحديد الخدمة بناءً على القسم») → awaiting_client (analysis 4192 + سؤال). الخدمة عندها department_id/doctor_id أصلاً (FE+BE) → فلترة consultationServiceOptions فقط (عام + قسم مختار + طبيب مختار). مفيش شغل BE.
- **CURSOR=4193.** المفتوح: 9134/9131 client_review · 9126/9138 awaiting_client.

### 9138 + 9134-divider اتنفّذوا (2026-07-18) — CURSOR=4205
- **9138** (فلترة الخدمة حسب القسم/الطبيب): BookingService +department_id/doctor_id (الـResource بيرجّعهم أصلاً)، consultationServiceOptions بتفلتر (عام دايمًا + قسم مختار + طبيب مختار). commit FE e9da823 · BE changelog fd603f25b.
- **9134 reopen2:** صف فاصل اليوم بقى شريط تيل واضح (#0d9488). 
- منشور main-FXXI2S4Y.js. الاتنين → client_review.
- **CURSOR=4205.** المفتوح: 9134/9138/9131 client_review · 9126 awaiting_client.

### 9139 باج اتحلّل (2026-07-18) — CURSOR=4208
- **ISS-2026-9139** (bug، «تغيير الطبيب يعلّق على تحميل») → awaiting_client (analysis 4207). السبب الجذري: loadAppointments بـ.subscribe بدون إلغاء → سباق طلبات عند تغيير الفلتر بسرعة → تعليق. الإصلاح: reload$ Subject + switchMap (قابل للإلغاء). FE فقط في appointments component.
- **CURSOR=4208.** المفتوح: 9134/9138/9131 client_review · 9126/9139 awaiting_client.

### 9139 + 9134-mrn اتنفّذوا (2026-07-18) — CURSOR=4221
- **9138 closed** ✅.
- **9139** (باج فلتر الطبيب): reload$ Subject + switchMap (قابل للإلغاء) + نقل التحميل الأولي بعد الاشتراك (كان بيضيع). commit FE 79705e1 · BE d343dd494.
- **9134 reopen3 (تحذير ping_pong):** MRN كان بِلّة خضرا باهتة → نص غامق عادي زي باقي الأعمدة.
- منشور main-65QYM74S.js. الاتنين → client_review.
- **CURSOR=4221.** المفتوح: 9134/9139/9131 client_review · 9126 awaiting_client.

### 9140 اتحلّلت (2026-07-18) — CURSOR=4224
- **ISS-2026-9140** (ملف المريض، 3 مشاكل) → awaiting_client (analysis 4223 + سؤالين). التشخيص: (1) كروت overview مكرّرة · (2) تبويب الزيارات بيستخدم PreviousVisitsComponent المحتاجة currentEncounterId (مفيش في الملف) → مابيحمّلش · (3) HistoryPanelComponent محتاجة encounterId (مفيش) → التاريخ مش شغّال. الحل: وضع ملف بدون encounter.
- **CURSOR=4224.** المفتوح: 9134/9139/9131 client_review · 9126/9140 awaiting_client.

### 9134 closed · 9139 comment · 9140 وكيل (2026-07-18) — CURSOR=4231
- **9134 → closed** ✅ (كل تعديلات المواعيد اتقبلت).
- **9139 reopen:** «لسه التغيير بين الطبيب بيعمل مشكلة» بعد إصلاح switchMap. BE سليم (tinker). العرض افتراضي اليوم فقط. بعتّ /comment أسأل العميل عن العرض الدقيق (تحميل مستمر/طبيب قديم/فاضي/المربع مش بيقبل) + جرّب توسيع المدى. مستني رده (لسه in_implementation).
- **9140 → in_implementation** (وافق: كارد واحد فقط + زيارات مالية + تاريخ patient-scoped). وكيل general-purpose بينفّذ (يعيد استخدام endpoint 9129 للزيارات، يصلّح التاريخ، يدمج الكروت)، smoke-test إلزامي، ماينشرش. بعده أراجع+أنشر+verify.
- **CURSOR=4231.** المفتوح: 9139/9140 in_implementation · 9131 client_review · 9126 awaiting_client.

### 9141 اتحلّل (2026-07-18) — CURSOR=4235
- **ISS-2026-9141** (باج أداء، بطء البحث بعد إضافة زيارة) → awaiting_client (analysis 4234). التشخيص: embeddedAppointments.refresh() بعد الحفظ بيعمل listAll متعدد الصفحات (تشبّع اتصالات) + رِندر جدول كبير → يبطّئ البحث. الإصلاح: تخفيف التحديث (صفحة واحدة محدودة + حد صفوف).
- **CURSOR=4235.** المفتوح: 9139/9140 in_implementation · 9131 client_review · 9126/9141 awaiting_client.

### 9140 اتنشر واتسلّم (2026-07-18) — CURSOR=4238
- وكيل خلّص FE-only (endpoints موجودة، smoke-test): كارد واحد (شيل Demographics المكرّر + showIdentity على الهيدر) · تبويب زيارات مالية (endpoint 9129) · تاريخ patient-scoped (patientScopeOnly على HistoryPanel). المكوّنات المشتركة بـinputs default-false (الكشف ما اتأثرش). commit FE 5a5629f. منشور main-3AG5RESJ.js.
- **فصحت في verification:** سبت كارد «الحقول الإضافية» (بيانات مخصّصة مش مكرّرة) وعرضت أدمجه/أشيله لو العميل عايز.
- **9140 → client_review**. CURSOR=4238. المفتوح: 9139 in_impl (مستني توضيح) · 9140/9131 client_review · 9126/9141 awaiting_client.

### 9141 اتنفّذ (2026-07-18) — CURSOR=4246
- إصلاح الأداء: listLimited (صفحة واحدة per_page=25) للوضع المدمج في reload$؛ /clinic/appointments المستقلة تفضل listAll. commit FE c92004e · BE 14ffbfc16. منشور main-WC2WIHZQ.js. → client_review.
- **CURSOR=4246.** المفتوح: 9139 in_impl (مستني توضيح) · 9140/9141/9131 client_review · 9126 awaiting_client.

### 9140 خطأ getKey اتصلح + 9139 مستني توضيح (2026-07-18) — CURSOR=4249
- **9140 reopen:** خطأ `getKey() on string` عند فتح الملف. السبب: PatientReadService::chronicList بيعمل ->unique() على Eloquent Collection من نصوص → getKey على string → 500 لأي مريض عنده أمراض مزمنة (كسر الهيدر كله). الحل: collect() base قبل unique (زي السطر 236). tinker: chronic=["BB"] OK. commit BE fdd6151af [skip-changelog]. local-deploy. → client_review.
- **9139:** العميل أعاد نفس الشكوى بدون إجابة سؤالي. switchMap منشور وBE سليم. مش هخمّن تالت (ping_pong) — مستني توضيح فعلي.
- **CURSOR=4249.** المفتوح: 9139 in_impl (مستني توضيح) · 9140/9141/9131 client_review · 9126 awaiting_client.

### 9131 السبب الجذري الحقيقي اتحل (جولة 6) — CURSOR=4251 (2026-07-18)
- **السبب الجذري (أخيراً، من توضيح العميل):** dropdown نتائج بحث المريض (app-clinic-patient-search .results, absolute, top:100%+6px, z-index:1100) كان بيتقصّ بـ`.panel{overflow:hidden}` على `.compact-panel` — فالجزء تحت اللوحة يتقطع («تحت الإطار») واللي يظهر تغطيه لوحة `.prev-visits` السيبلنج اللي بعده. كل جولات 1-5 (سكرول/تحديد) كانت على الحاجة الغلط.
- **الحل:** `overflow:visible` على `.compact-panel` فقط (create-visit.component.scss ~486) → الـdropdown يهرب وz-index:1100 يرفعه فوق prev-visits. الإطار الدائري ما اتأثرش. build أخضر، نشر /app (main-4CENKXEA.js). commit FE + CHANGELOG BE. verification منشورة → client_review.
- **CURSOR=4251.**

### 9126 عقد نهائي + 9142 spinoff — CURSOR=4473 (2026-07-18)
- **9126** (كانت عالقة تحت analysis ١٣ ساعة): العميل قبل توصيات عقد النطاق (٦ نقاط فورم إضافة زيارة) + أضاف سطح جديد (شريط بحث حالات على /clinic/dashboard) + وضّح إن خانة الوقت هتترابط لاحقًا بجدول مواعيد الأطباء. الإجراء: **spinoff** بحث الداشبورد → **ISS-2026-9142**، ونشرت عقد نطاق نهائي على 9126 (الوقت يخزّن يدويًا الآن؛ ربط الجدول مستقبلي خارج النطاق). → **awaiting_client** (مستني موافقة البدء).
- **9142** (spinoff, parent 9126): نشرت تحليل بعقد نطاق + سؤالين (سلوك اختيار الحالة على الداشبورد = المحوري؛ توصية: فتح ملف المريض). → **awaiting_client**.
- **9131** → client_review (إصلاح قصّ الـdropdown).
- **CURSOR=4473.** المفتوح: 9142/9126 awaiting_client · 9141/9140/9131 client_review · 9139 in_impl (مستني توضيح).

### watch — CURSOR=4473 (2026-07-18)
- الديلتا الأخيرة (4254→4260) كانت تحرّكاتي أنا (9142/9126 analysis→awaiting_client). مفيش تغييرات عميل. في وضع المراقبة.

### 9142 نُفّذ — CURSOR سيتحدّث (2026-07-18)
- **9142** (شريط بحث الداشبورد): العميل وافق وجاوب (سلوك=فتح الملف الطبي؛ مكان=بدل الطابور، المنطقة غير مستغلة). نفّذت على /clinic/dashboard: استبدلت panel الطابور المدمج بـ panel «بحث عن حالة» (نفس مكوّن app-clinic-patient-search)، والاختيار بيوجّه لـ/clinic/patients/:id. الطابور لسه متاح من رابط «فتح الطابور» وصفحة /clinic/queue. overflow:visible لتفادي قصّ القائمة (درس 9131). i18n +3 مفاتيح، I18N_VERSION→20260718a. build أخضر، نشر /app (main-YZ2SQJ6U.js). commit FE+BE. verification → client_review.

### 9126 in_implementation — وكيل opus بيشتغل (2026-07-18) CURSOR=4473
- العميل وافق (أخذ بالتوصية) + scope_freeze. بدأت تنفيذ الـ٦ نقاط (فورم /clinic/booking): (1) إخفاء رقم الحالة + إعداد clinic.booking.show_case_no (2) إطار خفيف حول اسم الحالة والعنوان خارجه (3) إلغاء رابط الاسم (nameEditable/nameTarget/nameNavigate) (4) selects القسم/الطبيب/الخدمة جاهزة فورًا (consultation line عند init) (5) datepicker مفتوح دايمًا default اليوم + timing يُشتق من التاريخ (6) خانة وقت قابلة للكتابة + عمود scheduled_time (migration forward + request + action + resource).
- **فُوّض لوكيل opus** (agentId داخلي) بمواصفات مجمّدة: build أخضر، لا نشر، لا commit، tinker smoke-test للـBE. هراجع/أختبر/أنشر/أوثّق بنفسي بعد ما يرجع.
- **CURSOR=4473.**

### 9131 closed + 9142 صُحّح (سوء فهم) — CURSOR=4473 (2026-07-18)
- **9131 → closed** ✅ (إصلاح قصّ الـdropdown اتقبل).
- **9142 رجع in_implementation** (ping_pong=1): العميل وضّح إني أسأت الفهم — «مش عايز الطابور يتحذف رجعه تاني»؛ قصده كلمة/منطقة أعلى الصفحة بجوار عنوان لوحة العيادة. التصحيح: رجّعت panel الطابور (app-clinic-visit-queue) + حطّيت شريط البحث في strip كامل العرض أعلى الصفحة (dash-search-strip، overflow:visible). الاختيار لسه بيفتح /clinic/patients/:id. صحّحت بند CHANGELOG. commit معزول لملفات الداشبورد بس.
- ⚠️ **لسه ماعملتش build/deploy** — الشجرة مشتركة مع وكيل 9126 (بيعدّل create-visit). هبني+أنشر الاتنين مع بعض بعد ما الوكيل يخلّص، وبعدها verification لـ9142 + 9126.
- **CURSOR=4473.**

### 9126 نُفّذ (وكيل opus) + نُشر — مستني code-review (2026-07-18)
- الوكيل نفّذ الـ٦ نقاط، build أخضر، migration مطبّق + seeder. أمسك باج مهم: أضاف realConsultations/isPristineConsultation عشان الـempty line الدائم ماتكسرش canSubmit/hasConsultations لزيارات المعمل/الأشعة.
- **راجعت الديف بنفسي:** BE جراحي سليم (migration string(8) nullable، actions/requests/resource/model/seeder). أمسكت gap: .cg-row1 كان ٥ أعمدة ورقم الحالة مخفي افتراضيًا → أضفت تظبيط ٤/٥ أعمدة (cg-row1--caseno داخل min-width:901px).
- **tinker مستقل:** عمود موجود ✅ · setting_definitions فيه show_case_no (default false, visible) ✅ · scheduled_time يثبت 09:45 + resource + null-case NULL ✅.
- build أخضر، نُشر /app (main-5ZXSLXFB.js). **لسه ماعملتش commit ولا verification** — مستني code-reviewer (opus) على منطق canSubmit/timing. بعد المراجعة: commit + verification لـ9126 و9142.
- **9142** (إصلاح المكان): منشور ضمن نفس الـdeploy، جاهز للـverification بعد المراجعة.

### جولة كبيرة — CURSOR=4473 (2026-07-18)
- **9141 → closed** ✅ · **9131 → closed** ✅ (سابقًا).
- **9142 → client_review:** صحّحت سوء الفهم (رجّعت الطابور + شريط بحث أعلى الصفحة كامل العرض، الاختيار يفتح الملف الطبي). نُشر + verification.
- **9140 رجع in_implementation** («التاريخ المرضي مش معروض»، ping_pong=2): حقّقت بالكامل — الـ3 endpoints (family/medical/surgical) شغّالة وبترجّع بيانات للمريض 2، الرسم صح، patientId بيتمرّر. مش قادر أعيد الإنتاج → **comment محايد** أسأل العميل: أي مريض + أي جزء فاضي (تفادي fix أعمى عند ping_pong=2). مستني رده.
- **9126 → in_implementation:** code-review رجع (1 HIGH: toggle now/later لسه بيغيّر timing من غير scheduledDate → onConsDoctorChange بيجيب سلوت اليوم الغلط + نص تأكيد مضلّل؛ 1 MEDIUM عدّاد الخدمات؛ 2 LOW كود ميت). **استأنفت وكيل التنفيذ (SendMessage)** لإصلاحهم، build أخضر، لا نشر. أراجع+أنشر+verification بعد ما يرجع. النواة (realConsultations/scheduled_time) اتأكدت سليمة في المراجعة + tinker مستقل.
- **CURSOR=4473.**

### 9126 نُفّذ بالكامل + verification — CURSOR=4473 (2026-07-18)
- وكيل التنفيذ صلّح الـ3 ملاحظات (HIGH: derivedTiming مصدر واحد + toggle متزامن + onConsDoctorChange بالتاريخ؛ MEDIUM عدّاد realConsultations؛ LOW كود ميت اتشال). راجعت الهنكات، build أخضر، نشر /app (main-L5MK4OUW.js)، commit FE+BE. verification → client_review.
- الحالة: 9126/9142 client_review · 9140 in_impl (مستني توضيح العميل) · 9131/9141/9140-سابق closed.
- **CURSOR=4473.**

### 9144 تحليل feature — CURSOR=4473 (2026-07-18)
- **9144 (new, feature)** «إضافة زيارة تحاليل»: قسم=التحاليل → بوب checkboxes+بحث+سعر، شِبس تحت القسم مع X، الإجمالي يتحدّث. نشرت تحليل بعقد نطاق (In/Out/acceptance) + ٤ أسئلة (توحيد مع البحث الحالي؟ الأشعة كمان؟ مكان الشِبس؟ تسعير LabPriceResolver؟). → awaiting_client.
- الحالة: 9126/9142 client_review · 9144 awaiting_client · 9140/9139 in_impl (مستنيين توضيح العميل).
- **CURSOR=4473.**

### 9126 layout + 9144 feature بدأ + 9145 spinoff — CURSOR=4473 (2026-07-18)
- **9126 → client_review:** تعديل layout (صغّرت الاسم + رفعت التاريخ/الوقت للسطر العلوي). نُشر + verification.
- **9144 (feature وافق) → in_implementation:** بوب اختيار تحاليل من القسم + الأشعة + شِبس أفقي كامل العرض + توحيد مع البحث القديم. **فُوّض لوكيل opus**. التسعير القياسي.
- **9145 spinoff (parent 9144):** تسعير التحاليل بقائمة أسعار جهة التأمين — محتاج schema (clinic_payer_contracts مافيهوش price_list_id) + tier في LabPriceResolver + شاشة إعداد. جديد.
- بلّغت العميل بفصل التسعير (comment على 9144).
- **CURSOR=4473.**

### 9145 تحليل منشور — CURSOR=4473 (2026-07-18)
- **9145 → awaiting_client:** تحليل تسعير التأمين بعقد نطاق (price_list_id على clinic_payer_contracts + حقل إعداد + tier في LabPriceResolver) + ٣ أسئلة.
- الحالة: 9126/9142 client_review · 9144 in_impl (وكيل) · 9145 awaiting_client · 9140/9139 in_impl (توضيح).
- **CURSOR=4473.**

### 9145 وافق + 9146 تحليل — CURSOR=4473 (2026-07-18)
- **9145 → in_implementation** (وافق أخذ بالتوصية ×3): تسعير التأمين. **مؤجّل التنفيذ لحد ما وكيل 9144 يخلّص** (تصادم LIS/create-visit محتمل). ⏳ QUEUED.
- **9146 (new, improvement) → awaiting_client:** إضافات اختيارية للفورم (تأمين dropdown + طبيب محوّل مع إضافة inline + ملاحظات في المواعيد/التقرير المالي + توجّلات إظهار). نشرت تحليل بعقد نطاق + ٣ أسئلة. بيتقاطع مع 9145.
- الحالة: 9126/9142 client_review · 9144 in_impl(وكيل) · 9145 in_impl(QUEUED خلف 9144) · 9146 awaiting_client · 9140/9139 in_impl(توضيح).
- **CURSOR=4473.**

### 9144 نُفّذ (وكيل) + إضافة القائمة — (2026-07-18)
- الوكيل خلّص: عمود service_kind (marker lab/radiology) + بوب (p-dialog) + شِبس أفقي كامل العرض تحت القسم + شال كروت STEP-2 + تسعير resolver (effective_price/doctor) + unpriced⚠. build أخضر. **لسه ماراجعتش/نشرت.**
- ⚠️ **caveat للمالك:** service_kind بيبدأ NULL على تنصيبات العملاء؛ في dev اتعلّم depts 5=lab/4=radiology. للإنتاج المالك محتاج يعلّم الأقسام (endpoint update بيقبلها) — هأنوّه في verification.
- **قلق مطابقة:** العميل عايز «قائمة» قابلة للتصفّح؛ الوكيل عمل بحث-فقط. **استأنفته يعبّي أول صفحة مسعّرة عند فتح البوب** (empty search، 1822 تحليل، 25/صفحة). مستني.
- بعد ما يرجع: code-review + tinker + build + deploy + verification لـ9144، ثم تنفيذ 9145.

### 9144 قائمة اتضافت + tinker متأكد — مستني code-review (2026-07-18)
- الوكيل قفل الفجوة: البوب بيعبّي أول صفحة (loadTestListFirstPage) عند الفتح + كل reopen؛ البحث الفارغ = تصفّح، ≥2 = بحث. build أخضر.
- **tinker مستقل:** departments.service_kind موجود (4=radiology,5=lab) · البحث الفارغ يرجّع ٢٥ · resolveMany([290])=150 default_price_list priced=true · غير المسعّر ⚠. BE سليم.
- **code-reviewer شغّال** على كامل ديف 9144 (BE migration + FE popup + إزالة STEP-2 + list-load). بعده: build + deploy + verification لـ9144 (مع تنويه service_kind للإنتاج)، ثم 9145.

### 9144 code-review = CRITICAL — بيتصلّح (2026-07-18)
- **CRITICAL:** اختيار قسم lab/rad على بند الكشف بيكتب department_id → البند يبقى real-incomplete (consultationServiceOptions بتستبعد lab/rad = صفر خيارات) → canSubmit=false للأبد، المسار الأساسي مكسور. + MEDIUM (بحث حرف واحد يسيب نتائج قديمة) + 2 LOW.
- **استأنفت الوكيل:** يخلّي بند قسمه lab/rad بدون service = pristine (مستبعد من realConsultations) فالزيارة تحاليل-بس تتحفظ، والكشف العادي يفضل يتحقّق؛ + يوقف ensureDeptDoctors للـlab/rad + إصلاح البحث/الرسالة. build أخضر، لا نشر.
- النواة اتأكدت سليمة في المراجعة (toggle/remove، تسعير 0176، service_kind null، reopen، BE migration). tinker مستقل تمام.
- بعد رجوعه: build + deploy + verification لـ9144، ثم 9145.

### 9146 وافق + 9148 bug فُوّض — CURSOR=4473 (2026-07-18)
- **9146 → in_implementation** (وافق، عايز الحقول ظاهرة افتراضيًا + قبل الباقي): إضافات اختيارية للفورم. **QUEUED خلف 9144** (create-visit).
- **9148 (new, bug, planning_gate) → فُوّض لأجينت headless:** error في /clinic/schedule. الأجينت يشخّص+يصلّح+يبني (لا نشر)؛ أنا أتولّى planning_gate comment + verification. مستقل عن create-visit.
- أجينتان شغّالان: 9144(CRITICAL fix) + 9148(schedule). QUEUE: 9145(payer BE) · 9146(create-visit FE).
- **CURSOR=4473.**

### 9144 مكتمل + 9148 اتصلح — CURSOR=4473 (2026-07-18)
- **9144 → client_review:** بوب التحاليل. code-review لقى CRITICAL (lab/rad dept بيكسر submit) → الوكيل صلّحه (isPristineConsultation يستبعد بند lab/rad بدون service) + MEDIUM/LOW. **decomposition_gate** (٥ بنود) → عملت decompose (subtasks 9149-9153) وقفلتهم (المسار: new→analysis→awaiting_client→in_implementation→verify→closed عبر /transition) ثم verification الأب. نُشر main-R6FJI7H7.js. commit FE+BE.
- **9148 → client_review:** VisitPeriodController كان get() بدون meta → الواجهة تكسر عند meta.last_page في listAllPeriods. الحل paginate(25). وكيل headless شخّص+صلّح+tinker. planning_gate comment + verification. commit BE. (ملاحظة جانبية: تفاوت صلاحيات schedule.view/closure.view.)
- **تعلّم مهم:** الفيتشر الكبير (≥5 In-Scope) لازم /decompose + قفل subtasks قبل verification. subtask transitions عبر /transition {to}. 
- QUEUE: 9145 (payer pricing BE) · 9146 (create-visit FE). مفيش أجينت شغّال دلوقتي.
- **CURSOR=4473.**

### 9147 تحليل + إطلاق 9145/9146 — CURSOR=4473 (2026-07-18)
- **9147 (new, improvement) → awaiting_client:** تعديلات فورم (حذف قسم «تفاصيل الزيارة» + تكبير بحث المريض على حساب القسم). تحليل + سؤال توضيح أي قسم. يستنى بعد 9146 (نفس ملف create-visit) + موافقة العميل.
- **9145 → أجينت headless (BE):** تسعير التأمين (price_list_id على clinic_payer_contracts + tier في LabPriceResolver + شاشة إعداد + الأشعة investigate). ممنوع يلمس create-visit.
- **9146 → أجينت headless (FE):** إضافات فورم (تأمين dropdown + طبيب محوّل inline-add + ملاحظات في المواعيد/التقرير المالي + 3 توجّلات default-visible). ممنوع يلمس ملفات 9145.
- أجينتان متوازيان (ملفات مختلفة). الحالة: 9126/9142/9144/9148 client_review · 9145/9146 in_impl(وكلاء) · 9147 awaiting_client · 9140/9139 توضيح.
- **CURSOR=4473.**

### 9144 رجع (تنسيق البوب) — مصفوف خلف 9146 — CURSOR=4473 (2026-07-18)
- **9144 reopen:** (1) البوب مش منسّق (2) أعمدة بدلالة مجموعة التحليل (3) بدل «غير مسعّر» اكتب 0. scope_creep rounds=1 (مفيش warning). 
- create-visit مقفول مع وكيل 9146 → **9144 fix QUEUED خلف 9146**. بعتّ /comment أأكّد + أسأل سياسة حفظ الصفر (توتر 0176). ⏳
- **CURSOR=4473.**

### 9146 خلّص — منتظر 9145 قبل build/deploy (2026-07-18)
- **9146 done (وكيل):** insurer dropdown @if(showInsurer)، referring inline add-by-name (+ BE: DoctorFormRules خلّى phone اختياري في door إنشاء العيادة = تغيير shared-layer محتاج مراجعة)، notes textarea + عمود Notes في المواعيد + الزيارات السابقة (PatientVisitsService)، 3 settings default=true. i18n→20260718e. build أخضر. tinker متأكد. لسه ماراجعتش/نشرت.
- ⚠️ 9145 (BE) لسه شغّال نفس الشجرة → HOLD على build/deploy لحد ما يخلّص، وبعدها: code-review للاتنين (خصوصًا phone-optional) + build مرة واحدة + commit بـfile-area + deploy + verification لكل تذكرة.
- بعدها: 9144 reformat (create-visit حر بعد 9146) + 9147.

### 9145+9146 خلصوا — code-review شغّال — CURSOR=4473 (2026-07-18)
- **9148 → closed** ✅.
- **9145 done:** tier insurer في LabPriceResolver (b2b→insurer→doctor→default)، price_list_id migration + شاشة payer-contracts، threading من controller+CreateLabRequest؛ الأشعة flagged (بلا price-list). tinker PASS. **ملاحظة:** الـpopup display في create-visit لسه مابيبعتش payer_contract_id — التسعير بالتأمين شغّال عند الحفظ بس مش في عرض البوب → محتاج wiring صغير في create-visit (أباتشه مع 9144 reformat).
- **9146 done:** insurer dropdown + referring inline-add (+ DoctorFormRules phone-optional shared) + notes في المواعيد/الزيارات + 3 settings default-visible. build مدموج أخضر. مفاتيح i18n للاتنين موجودة + JSON سليم.
- code-review مدموج شغّال (خصوصًا phone-optional + tenant-scoping التسعير). **HOLD deploy/verify لحد ما يرجع.**
- بعده: نشر + commit بـfile-area + verification 9145/9146، ثم create-visit: 9144 reformat + wiring payer_contract_id للبوب، ثم 9147.
- **CURSOR=4473.**

### 9155 تحليل — CURSOR=4473 (2026-07-18)
- **9155 (new, feature كبير رغم تصنيف improvement) → awaiting_client:** إعادة تصميم /clinic/schedule كشبكة غرف×توقيتات(٣٠د)+تابات أيام+ساعات من الإعدادات+تعيين طبيب-غرفة-وقت. نشرت عقد نطاق + ٤ أسئلة؛ بعد الموافقة تصميم أعمق. مستقل عن create-visit.
- code-review 9145+9146 لسه شغّال (HOLD deploy).
- **CURSOR=4473.**

### 9155 وافق — QUEUED (فيتشر كبير) — CURSOR=4473 (2026-07-18)
- **9155 → in_implementation** (وافق ٤× توصيات): جدول أطباء شبكة غرف×توقيتات. النطاق: ساعات عمل عامة (إعداد) + كيان تعيين طبيب-غرفة-يوم-نطاق-وقت (migration جديد) + بوب اليوم + الجدول الجديد يحل محل الفترات. **QUEUED** لحد ما 9145/9146 يتـcommit (تفادي تشابك الشجرة). محتاج تصميم أعمق + وكيل.
- **الطابور الحالي:** (1) 9145/9146 code-review→نشر/commit/verify (2) create-visit: 9144 reformat + payer wiring (3) 9147 (بعد موافقة) (4) 9155 (فيتشر كبير).
- **CURSOR=4473.**

### code-review 9145/9146 = 2 HIGH — أجينت إصلاح شغّال (2026-07-18)
- **HIGH-1:** DoctorFormRules phone-optional واسع (بيأثّر شاشة الأطباء + بيكسر DoctorFormRulesTest:51) → حصره على quick-add + إصلاح الاختبار.
- **HIGH-2:** بوب البحث مابيبعتش payer_contract_id → العرض ≠ المفوتر (تأمين) → توصيل payerContractId في searchInvestigations/repriceInvestigations + call-sites.
- LOW: insurer_price_list في price_source type.
- النواة نظيفة (tier order، tenant-scoping، save path، settings، notes، مفيش clobbering). فُوّض لأجينت واحد. بعده: build + deploy + commit بـfile-area + verification 9145/9146، ثم 9144 reformat (+نفس payer wiring)، ثم 9147، ثم 9155.

### 9145+9146 نُشرت — CURSOR=4473 (2026-07-18)
- **9145/9146 → client_review** بعد إصلاح 2 HIGH (phone-optional محصور بـquick_add الخامس param + الاختبار متصلّح؛ payer_contract_id متوصّل للبوب + reprice على تغيير التأمين؛ insurer_price_list type). tinker مؤكد (admin phone required / quick nullable). build أخضر main-UNSGVWUS.js. commit BE+FE.
- **الطابور الباقي:** 9144 reformat (بوب: أعمدة بمجموعة التحليل + 0.00 بدل «غير مسعّر»؛ payer wiring خلص بالفعل) · 9147 (بعد موافقة) · 9155 (فيتشر كبير).
- **CURSOR=4473.**

### أجينت 9144-reformat+9147 شغّال — CURSOR=4473 (2026-07-18)
- **9147 وافق** (أخذ بالتوصية). **9144** لسه ماردّش على سياسة الصفر → 0.00 display + إبقاء block (0176) + تنويه.
- ⚠️ تعارض محتمل: 9147 «حذف تفاصيل الزيارة» vs 9146 (ضاف حقول STEP-1) → الأجينت متعلّم يحدّد القسم بدقة ويقف+يبلّغ لو الحذف هيشيل حقول 9146.
- أجينت create-visit واحد لـ9144+9147. بعده: verification (decompose 9144 لو ≥5؛ 9144 In-Scope=? راجع) + 9147، ثم **9155** (فيتشر جدول الأطباء — تصميم عميق + وكيل).
- **CURSOR=4473.**

### 9144 نُشر + 9147 عالق(تعارض) + 9155 يبدأ — CURSOR=4473 (2026-07-18)
- **9144 → client_review:** بوب مجمّع بـsection + 0.00 display (block باقٍ). commit main-S5GL6BKJ.js.
- **9147 → مستني توضيح:** «تفاصيل الزيارة» = بانل STEP-1 اللي فيه حقول 9146 (تأمين/طبيب محوّل/ملاحظات/توقيت). حذفه = إزالة 9146. بعتّ /comment أسأل: البانل كله ولا جزء؟ التكبير هيتعمل مع التحديد.
- **9155 → فُوّض لأجينت headless:** جدول أطباء (فحص+تصميم+تنفيذ). فيتشر كبير.
- **CURSOR=4473.**

### 9155 done (وكيل) — code-review شغّال — CURSOR=4473 (2026-07-18)
- **9155 done:** أعاد استخدام DoctorScheduleSlot (room_id/weekday/start/end موجودين — مفيش migration)؛ إعداد ساعات (day_start=09:00/day_end=21:00)؛ Resource+doctor/room؛ FE شبكة تابات أيام×غرف×30د بـrowspan + dialog تعيين؛ أبقى تابات الفترات/الإغلاقات (بتغذّي slots mode للحجز). build أخضر. tinker مؤكد (إعدادات مزروعة، slots فيه room_id/weekday).
- code-review شغّال (weekday off-by-one، rowspan/تداخل، time parse، load-all). HOLD deploy لحد ما يرجع، بعده: نشر + commit + /decompose + verification.
- **flag للـverification:** الفترات/الإغلاقات اتساب (مش اتحذفت) — الشبكة الأساسية بس اتبدلت؛ أنوّه للعميل.
- **CURSOR=4473.**

### 9155 code-review = 3 HIGH — أجينت إصلاح شغّال (2026-07-18)
- HIGH-1: تداخل slots نفس الغرفة يفسد الشبكة (column drift) → gridRows دفاعي (ماينفعش يكتب على خلية مشغولة).
- HIGH-2: التعديل بيصفّر capacity/is_active (الديالوج شالهم) → رجّع الحقلين للديالوج + قيم حقيقية.
- HIGH-3: room_id إجباري client-side يكسر single-clinic بلا غرف + بييتّم room-less → إجباري في center mode بس + عمود «بدون غرفة» للـroom-less.
- (+2 MEDIUM: step=1800، badge count). النواة نظيفة (weekday صح، time parse آمن، auto-paginate، BE department_id scoped).
- بعده: build + deploy + commit + /decompose + verification. flag: الفترات/الإغلاقات اتسابت.

### 9155 نُشر — CURSOR=4473 (2026-07-18)
- **9155 → client_review:** جدول أطباء شبكة غرف×توقيتات بعد إصلاح 3 HIGH (gridRows دفاعي+شارة تعارض · capacity/is_active رجعوا · room mode-gated + عمود «بدون غرفة» · step=1800). commit BE+FE main-U555YP64.js. verification مع تنويه الفترات/الإغلاقات.
- **مفيش أجينت شغّال.** كل الفيتشرات (9144/9145/9146/9155) + (9126/9142) في client_review.
- **مستني العميل:** 9147 (توضيح تعارض) · 9140/9139 (توضيح) · + يقفل client_review.
- **CURSOR=4473.**

## 2026-07-18 (مساءً) — جولة إصلاح ثانية
- **CURSOR=4734**
- **9145 — closed** (العميل قفلها).
- **9155 (client_review):** السبب الحقيقي — `display:flex` على `<td>` بيشيل الخانة من نظام تخطيط الجداول فالمتصفح بيتجاهل `rowspan`. الحسابات والداتا كانت سليمة (`09:30→12:30`, rowspan=6). الحل: الخانة رجعت table-cell والتخطيط اتنقل لـ`.assign-stack` جوّاها.
- **9144 (client_review):** «مفيش تنسيق» = التنسيق **ميت بالكامل**. كل `.tp-*` كانت متعلّقة بـ`.test-popup` اللي بتيجي من `styleClass` بتاعة PrimeNG → بتنزل على عنصر PrimeNG اللي مالوش `_ngcontent` بتاعنا → السيلكتور مستحيل يتحقق. الحل: ربط التنسيقات بـ`.tp-body` (عنصر من عندنا)، و`.tp-count` اتنقلت top-level لأنها في الـfooter template.
- **نفس المصيدة اتلقت في الـCTA:** `<p-button styleClass="btn big sign w-full">` — الكلاسات بتنزل على الـ`<button>` جوّه PrimeNG، فزرار «تأكيد الزيارة» و«إضافة وطباعة» كانوا بيظهروا افتراضيين. اتصلحوا عبر `::ng-deep .p-button.btn` في نفس التسليم.
  - ⚠️ **قاعدة عامة:** أي كلاس بيتمرّر عبر `styleClass` مايتعملوش استايل كـancestor — استايل عناصرنا إحنا أو استخدم `::ng-deep`. (`p-select`/`p-autoComplete`/`p-datepicker` host-bind فهي آمنة؛ `p-button` و`p-dialog` **لأ**.)
- **9146 + 9147 — نفس الشغل:** العميل وضّح إنه عايز (التأمين + الطبيب المحوّل + الملاحظات) تتنقل لبلوك «إضافة زيارة جديدة» كسطر تاني أفقي تحت (المريض/القسم/الطبيب/الخدمة/التاريخ/الوقت)، وبعدين **بلوك «تفاصيل الزيارة» يتحذف بالكامل**. + توسيع خانة بحث المريض عشان الهاتف يظهر كامل.
  - آمن نحذف مفتاح التوقيت: `buildPayload()` بيستخدم `derivedTiming()` من التاريخ مش من الـtoggle.
- منشور: `main-LAXREO4E.js` · FE commit `44e8d125` (hazemdev3).

### 2026-07-18 — دورة اللوب: 9146 (جولة 2) + 9155 (جولة 3)

- **9146 → client_review** (verification 4521). خانة الطبيب المحوّل بقت **خانة واحدة**: p-autoComplete واحدة، ولو الاسم المكتوب مش مطابق حاجة بيتضاف سطر صناعي `ADD_NEW_SENTINEL_ID = -1` بعنوان «＋ إضافة «الاسم»» — اختياره بينادي نفس quick-add القديم. اتشالت الخانة المنفصلة + زر الإضافة + الـCSS بتاعهم. واتضافت **قيمة الكشف للقراءة فقط** (consultSubtotal) بالترتيب المطلوب: تأمين / محوّل / قيمة الكشف / ملاحظات. الصف مابقاش محتاج الـ@if بتاع «التلاتة مقفولين».
- **درس من الـcode-review:** أول نسخة كانت بتفضّي الخانة أثناء POST الإنشاء من غير أي مؤشر → الموظف يفتكر إن الاختيار مانفعش. اتصلح بـ`[disabled]` + placeholder «جارٍ إضافة الطبيب…» + spinner.
- **9155 → client_review** (verification 4524). جولة 2 صلّحت الـ`display:flex` على الـ`<td>` فالـrowspan اشتغل — لكن المربع جوّه فضل بارتفاع محتواه وفوق، فالعميل لسه شايفه صف واحد. الإصلاح: `.assign-stack .assign-chip { flex: 1 1 0 }`. والعميل كمان طلب ألوان أوضح → المربع بقى **تدرّج تركوازي مصمت بكتابة بيضاء** (التعارض كهرماني، الموقوف رمادي) بدل أبيض على `#f0fdfa`.
- **API gotcha:** `POST /api/issues/{ref}/verification` بيطلب **`content_markdown`** مش `content_html` (بيرجع 422 من غيرها).
- منشور على /app: `main-HNZQEN3Z.js`. كوميتات FE: `d3bb1f4d` + `731b1894` على hazemdev3. CHANGELOG اتحدّث (بند قيمة الكشف + بند شبكة الجدول، وبند الإضافة السريعة القديم اتظبط لأن الخانة بقت واحدة).
- **لسه مفتوح ومستني العميل:** 9139 و9140 — الاتنين مستنيين إجابة العميل على سؤال تحديد العرَض بالظبط (مش ناقص شغل عندي).

### 2026-07-18 (تكملة) — 9162 + 9146 ج3/ج4 + 9155 ج4 · CURSOR=4553

- **9155 و9144 اتقفلوا** ✅ (بعد تكبير الخط في شريط الجدول).
- **9162 → client_review.** بَجّين مستقلين:
  - العناوين بعيدة عن الأرقام: `thead th{text-align:start}` جوّه الكمبوننت بيتحول بعد الـencapsulation لـ(0,4,2) فبيغلب `.ta-end` (0,4,0) على نفس الـ`<th>` — بينما الـ`<td>` مالوش قاعدة فبيقع على `.ta-end`. النتيجة: العنوان start والرقم end = ناحيتين متضادتين في RTL. الحل: شيل السطر (styles.scss أصلاً بيحطه على (0,0,1) عشان أي كلاس يغلبه). **اتصلح في create-visit و clinic-patient-file** (نفس البلوك متكرر).
  - **المتبقي = 0 رغم وجود دين:** `Appointment::serviceOrder()` = `latestOfMany()`، والزيارة بيطلعلها أمر `open` فاضي بعد المفوتر → بيقرا الفاضي → 0/0/0، وكمان `AppointmentResource` كان بيصنّفها "مدفوعة" في قائمة المواعيد والطابور. الحل في **الطبقة المشتركة**: `serviceOrders()` hasMany + `billingTotals()` (يجمع كل الأوامر، يستثني cancelled، يبقّي closed) + تجميع الـcredit notes في **استعلام واحد** (جمع `net_collected` كان هيعمل استعلام لكل أمر). التحقق: 350 مطابق للـledger. اختبارات regression اتضافت.
  - **باقي مفتوح:** مصدر «الأوامر الفاضية» نفسه لسه موجود — ذكرته للعميل كتذكرة منفصلة مقترحة.
- **9146 ج3:** `CLINIC_VISIT.NOTES` + `NOTES_PLACEHOLDER` **مكانوش موجودين أصلاً** في الترجمة. والصف بقى flex nowrap (مش grid ثابت — لأن 3 خانات ورا إعدادات إظهار، فالشبكة الثابتة بتزقّهم لأعمدة غلط).
- **9146 ج4:** العميل بعت صورة → المقصود **كارت «قيمة الكشف»** (إجمالي/خصم/كاش/فيزا/متبقي) يتحذف. اتأكدت إنه كله **عرض للقراءة فقط ومكرر** (التحصيل الحقيقي في قسم الدفع) قبل الحذف.
- **🔴 غلطة عملتها:** جربت endpoints بالتخمين (`POST /api/issues/{ref}/analysis` بمحتوى "probe") فاتسجّلت **خطوة حقيقية على تذكرة العميل** وحرّكت حالتها. صحّحتها بـcomment واضح واعتذار. **القاعدة:** ماتجربش endpoints على تذكرة حقيقية بمحتوى وهمي.
- **الـendpoints الصح:** `POST /api/issues/{ref}/verification` (بيطلب **`content_markdown`**) · `/comment` (محايد) · **`/transition` بـ`{"to":"in_implementation"}`** لتحريك تذكرة `new` قبل الـverification.
- **جديد مفتوح:** 9163 (مستني توضيح — «إلغاء بوكس الخدمات» غامضة) · **9164 (بطء بحث المريض — تشخيص جاري)** · 9139/9140 (مستنيين العميل).


### جولة 9146 #5 — تصحيح قراءة مقلوبة (2026-07-18)
- **الغلط:** في الجولة 4 حذفت كارت «قيمة الكشف» بناءً على قراءة مقلوبة لكلام العميل. رده: «انت نفذت عكس المطلوب … انا عايز دة اللى يفضل موجود».
- **التصحيح:** `git revert` لـ 371e16e2 (الكارت + الـSCSS رجعوا حرفياً)، وحذف **الخانة المفردة** `.cg-fee` اللي كنت ضايفها في `.cg-row1b` بدلاً منه. النتيجة: «قيمة الكشف» واحدة بس على الشاشة.
- **السبب الجذري لـ5 جولات (واحد مش خمسة):** وجود شيئين بنفس الاسم على نفس الشاشة خلاني أخمّن كل مرة أنهو المقصود.
- **التحقق:** من الباندل المتبني مش من الكود — `cg-feegroup`/`FEE_GROUP_TITLE`/`PAY_CASH_SLOT`/`PAY_VISA_SLOT` راجعين في `chunk-NTME5OJJ.js`، و`cg-field cg-fee` = صفر.
- **النشر:** `main-YMICHNFS.js` على /app · commit `89cd532e` على hazemdev3 · verification step 4572 → client_review.
- **بوابة ping_pong** اتفعلت (5 جولات) فالـverification اتكتب كإعادة تأطير: جدول بحالة الطلبات الأربعة كلها + طلب تأكيد الصورة كاملة مرة واحدة.

### جولة 9146 #6 + 9164 (2026-07-19)
- **9146 — العميل: «كدة كله تمام متبقي نقطة واحدة: تصغير خانة التأمين وخانة الطبيب المحول ونقل كارت قيمة الكشف جنبهم ثم الملاحظات».** اتنفذ: الكارت اتنقل من `.cg-row2` (اتشال بالكامل + قواعده الميتة) لجوه `.cg-row1b` كـdirect child؛ payer=`0 1 120px`, ref=`0 1 150px`, feegroup=`2 1 0`, notes=`1 1 0`.
- **فخ اتفادى:** قاعدة `.cg-field` في `.cg-row1b` اتعملت `> .cg-field` — الكارت جوه بيحمل `.cg-field` بتاعته، وقاعدة descendant كانت هتعيد تنسيق أرقام الكارت وتكسّره.
- **التحقق:** من الباندل — الأربع selectors اتولّدوا صح بـ`[_ngcontent-%COMP%]`، و`cg-row2`=0. نشر `main-A3L5VQZI.js` · commit `bd7d5564` · verification 4583 → client_review.
- **⚠️ غلطة تشغيل:** مسحت `/app` وأنا في `dist/moon-erp/browser` (الـcd فشل قبلها) فالـ`cp` النسبي فشل و/app فضل فاضي ثواني. **القاعدة: استخدم مسارات مطلقة دايماً في خطوة النشر.** اترجّع فوراً واتأكد HTTP 200.
- **9164 — العميل سأل:** هل البحث برقم المريض والاسم بس يقلل الزمن؟ **قِست:** 6 أعمدة = 0.4ms · عمودين = 0.2ms (على 5 مرضى بس). الرد: لأ مش هيفرق محسوس؛ السبب الحقيقي `%q%` (leading wildcard) اللي بيمنع استخدام الفهارس. اقترحت: أرقام → prefix يستخدم الفهارس، حروف → الأسماء بس. **مستني موافقته على التنازل** (البحث بالأرقام من أول الرقم، مش بآخر 4 أرقام). comment 4586، التذكرة لسه in_implementation.

### دفعة 2026-07-19 — 4 تذاكر في دورة واحدة (CURSOR 4586→4680)
- **9140 (كارت ملف المريض):** العميل أعطى MRN-000005 + الرابط. **السبب الجذري مش تكرار لـ9162:** الكارت كان بيعرض `balance` = مجموع قيود الدفتر، ودفتر العيادة **بيكتب قيد المديونية وقت التحصيل بس** (WritePatientLedgerEntries على ReceiptCollected) مع قيد دفع مساوٍ → الرصيد بيتصفّر بطبيعته ومستحيل يمثّل دين. أمر 18 (400 مفتوح) مالوش قيد أصلاً. **الإصلاح المشترك:** `PatientReadService::summaryFor()` بيرجّع `outstanding` من `outstandingFor()`، والكارت المشترك `clinic-patient-header` اتربط بيه → **4 شاشات اتصلحت مرة واحدة**. لِيبل جديد `CLINIC.OUTSTANDING` = «مستحق» عشان مايتلخبطش مع تبويب الدفتر. تحقق: `patient 5 -> balance=0 outstanding=400`.
- **9139 ([object Object]):** **PrimeNG v21 بيرسم قالب `selectedItem` في وضع multiple/chips بس** → القالب بقى كود ميّت في الخانات أحادية الاختيار، و`getOptionLabel()` رجّع الكائن نفسه. **فخ:** `[optionLabel]="'name_ar'|'name_en'"` بيرجّع نفس العيب لو `name_en` = null (PrimeNG بيرجع الكائن لو الليبل null). **الحل:** `label` محسوب مسبقاً على كل اقتراح + حذف القوالب الميتة. **4 مواقع** اتصلحوا (فلتر مواعيد، الطبيب المحوّل، خدمات العيادة ×2).
- **9164:** العميل اقترح تقسيم أحسن من اقتراحي ونفّذته: `scope=mrn` (أي مقطع، عمود واحد قصير) / `scope=general` (name/phone/national من الأول). **دليل على الجدول:** `phone LIKE '010%'` → possible_keys=phone_index · `phone LIKE '%010%'` → NULL. تحقق: q=002 → MRN-000002. **تنازل أُبلغ به:** بحث الاسم بقى من الأول.
- **9146:** توسيع payer(180px)/ref(200px) على حساب الكارت (flex 2→1). طلبه التاني (خانة الطبيب زي القسم) **اتوقف عمداً** — بيتعارض مع الإضافة السريعة للطبيب الجديد؛ اتعرضت 3 خيارات مع ترشيح (أ).
- **⚠️ حزمة الاختبارات مش شغالة:** `pest`/`artisan test` بيخرجوا 255 من غير أي مخرجات (phpunit بيحوّل لـpest). التطبيق نفسه بيبوت عادي (tinker شغال) وpint pass. اتحققت بتشغيل الكود مباشرة على البيانات الحقيقية بدلها، واتقال للعميل بصراحة.
- **النشر:** `main-SAU6Z5N6.js` · BE `8725bbc4b` · FE `c8132fbb` · I18N_VERSION=20260719a · verifications 4671/4674/4677/4680.

### دفعة 2026-07-19 #2 (CURSOR 4680→4702)
- **9164 — غلطة مني:** في الجولة اللي فاتت شلت `mrn` من scope=general خالص وحطيته في خانة رقم الملف المنفصلة (المخفية بإعداد) → بحث `002` رجع صفر نتايج. **الصح دلوقتي:** general = mrn(أي مقطع) + name/name_ar/name_en(أي مقطع) + phone(من الأول)، وnational_id اتشال بطلبه. تحقق: 002→MRN-000002، zem→hazem.
- **⛔ الـseeding اتمنع:** طلب العميل إضافة مرضى للاختبار الحقيقي. حضّرت سكريبت INSERT لـ20k مريض (مش migrate) لكن **classifier منع الكتابة الجماعية**. ماحاولتش ألتف حواليه؛ اتقال للعميل بصراحة وللمشغّل. **لسه محتاج إذن.**
- **9140:** `formatBalance` → `toFixed(2)` بدل 3 (عرض بس). في الكارت المشترك → 4 شاشات.
- **9139:** **عنصر جديد** `app-clinic-doctor-search` في `features/clinic/shared/doctor-search/` — مبني بالإيد على نموذج patient-search (input+FormControl، debounce 300، إلغاء الطلب السابق، تنقّل كيبورد، لوحة بشكل النظام). **مش PrimeNG** → فئة الباج اتشالت هيكلياً. اتربط في فلتر مواعيد العيادة والكود الميت اتشال. **تغيير سلوك أُبلغ به:** minChars=2 بدل فتح القائمة كاملة بضغطة.
- **9146:** الطبيب المحوّل بقى `p-select` بـ`[filter]` وroster محمّل مرة واحدة في ngOnInit عبر `bookingService.doctors(null,true)` + زرار ＋ للإضافة السريعة بالاسم (القائمة المنسدلة مابتقبلش اسم جديد). اتشال الكود الميت: ADD_NEW_SENTINEL_ID، referringDoctorSuggestions، referringDoctorSearch$، referringDoctorQuery، referringDoctorOption، onReferringDoctorSearch.
- **النشر:** `main-XYMU5GVD.js` · BE `2aede8e79` · FE `ad4eee6f` · I18N_VERSION=20260719b · verifications 4693/4696/4699/4702.

### دفعة 2026-07-19 #3 (CURSOR 4702→4718)
- **9140 اتقفلت ✅** (خانتين عشريتين).
- **9139:** العميل رد على التنبيه اللي كتبته: عايزها **دروب ليست + بحث**. `minChars` بقى 0 و`onFocus()` بيفتح اللوحة ويجيب أول صفحة أطباء بـquery فاضية. الباقي زي ما هو.
- **9146:** شيل `REVENUE_SPLIT_HINT` ونقل زرار ＋ لسطر الليبل (`.cg-lbl-row`) فوق الخانة.
- **9164:** شيل «الهوية» من placeholder البحث السريع (CLINIC_PATIENT_SEARCH.PLACEHOLDER + CLINIC_VISIT.PATIENT_SEARCH_PLACEHOLDER). **سيبت `CLINIC_PATIENTS.SEARCH_PLACEHOLDER` عمداً** — شاشة قائمة المرضى لسه بتبحث بالستة أعمدة (مافيش scope) فالنص صح هناك؛ اتقال للعميل.
- **النشر:** `main-NRLBCR26.js` · FE `f0d79124` · I18N_VERSION=20260719c · verifications 4712/4715/4718.
- **لسه معلّق:** إذن إضافة الـ20k مريض للاختبار (منعه الclassifier).

### دفعة 2026-07-19 #4 (CURSOR 4718→4734)
- **9146:** العميل: زرار الإضافة «ظاهرة وكأنها تنبيه من البرنامج». **السبب: أنا استخدمت `window.prompt()`** كاختصار في الجولة 9 — المتصفح بيرسمها كنافذة نظام. اتحوّلت لـ**سطر إضافة inline** جوه الخانة (`.ref-addrow`): input + حفظ/إلغاء، autofocus، Enter/Escape، وبيتقفل لوحده بعد النجاح. **درس: ماتستخدمش prompt/alert/confirm في شاشة منتج.**
- **9139:** العميل أكّد إن الشكل الحالي (قائمة تفتح + بحث) هو المطلوب → verification بطلب الإقفال.
- **9164:** العميل لاحظ «أول بحث أبطأ وبعدين أسرع» = تسخين (اتصال DB + opcache) مش خوارزمية البحث؛ اتشرح له وقلت له يتجاهل أول بحث عند القياس. **طلب الـ20k مريض للمرة التانية — لسه ممنوع بالclassifier.** عرضت عليه بديل: يقيس على بياناته الحقيقية ويبعت العدد + الزمن.
- **9163:** العميل عايز يشيل البوكس عشان الدفع يبقى من كارت قيمة الكشف، وسألني رأيي 3 مرات. **راجعت البلوك فعلياً قبل الرد:** جواه **قرار مسار** (تحصيل دلوقتي/تحويل للكاشير/آجل) مش أرقام بس، وسطور دفع تقبل أكتر من طريقتين، والكاش/فيزا في الكارت **مرآة قراءة فقط**. رأيي: نخلي الكاش/فيزا في الكارت قابلين للكتابة، الإجمالي/الخصم/المتبقي محسوبين، **مفتاح المسار يفضل** مصغّر، ولينك «طرق دفع أخرى» للحالات النادرة. سألته سؤال yes/no محدد لتثبيت البوكس المقصود.
- **النشر:** `main-OVG4YRVW.js` · FE `2f517c4f` · I18N_VERSION=20260719d · steps 4729/4732/4733/4734.

### دفعة 2026-07-19 #5 (CURSOR 4734→4743)
- **9164 — القياس الحقيقي اتعمل أخيراً.** المالك وافق على الـseeding، فاتعمل `Modules/Clinic/database/seeders/ClinicSearchLoadTestSeeder.php` (**INSERT-only**، بيلحق بعد أكبر MRN، ماينفعش يمسح أو يعمل truncate) واتنفّذ: **+20,000 مريض، الجدول بقى 20,005**.
  - ⚠️ **أمر التراجع:** `DELETE FROM lab_patients WHERE id > 5;` (الـ5 دول بيانات حقيقية — ماتلمسهمش).
  - الأرقام (وسيط 5 قياسات بعد استبعاد التسخين): اسم «محمد» 1.0→0.8ms · MRN «002» 0.3ms · **تليفون «0137» 2.7→0.1ms (27×)**.
  - **دليل EXPLAIN:** `phone LIKE '%0137%'` → key=`company_id_is_active`، rows=**9938**. `phone LIKE '0137%'` → key=`lab_patients_phone_index`، rows=**1**. ده تأكيد عملي لقاعدة الـleading-wildcard على بيانات فعلية.
  - `002` رجّع 1140 نتيجة أولها `MRN-000002` → غلطة الـscope=general اللي عملتها اتأكد إنها متصلحة **بالبيانات مش بالنظر**.
  - قلت له بصراحة إن مكسب البحث بالاسم على 20k **مش محسوس** بدل ما أبيع له تحسين وهمي. step 4741 → `client_review`.
- **9139:** اتقفلت ✅ (step 4740).
- **9146 رجعت `in_implementation`:** العميل «تمام جدااا» بس عايز زرار الإلغاء يبقى **X** بدل كلمة، عشان مساحة أكبر لخانة اسم الطبيب → اتعمل (زرار أيقونة 26×26، `aria-label`/`title` محافظين على الاسم المقروء، hover أحمر).
- **9164 جولة تانية (CURSOR→4750):** العميل سأل «مش ممكن نكيّش الصفحات بدل الوقت الطويل في الدخلة الأولى؟». **فحصت السيرفر بدل ما أخمّن:** الـJS/CSS **متكاشة أصلاً** `max-age=31536000, immutable` وgzip شغال — يعني اللي بيشوفه هو الكاش شغال فعلاً. **اللي كان ناقص فعلاً:** `ar.json`/`en.json` (**١٥٤ ك.ب مضغوطة لكل لغة**) بدون أي `Cache-Control` → بتتنزّل كل جلسة. اتظبطت في `/app/.htaccess` (+ الصور)، **و`config.json` مستثنى صراحةً بـ`<Files>` في الآخر** عشان مايتثبتش على apiUrl غلط. اتأكدت من الهيدرز بعد التنفيذ. **⚠️ ده رفع مخاطرة نسيان `I18N_VERSION` — بقى نسيانها = قاموس قديم سنة كاملة حتى مع hard-refresh** (متسجّل في ذاكرة `i18n-cache-bust`).
  - `.htaccess` بتاع `/app` **مش** جزء من البناء (مش في `public/` ولا `dist/`) → تعديله بيعيش بعد أي deploy، بس **مابيوصلش لعملاء MoonStack** — قرار شحنه للعملاء سيبته للمالك.
  - **🔴 تصحيح endpoint:** `POST /comment` **مش محايد للحالة** — رجّع التذكرة من `client_review` لـ`in_implementation` (step 4747). لازم verification بعده يرجّعها. الذاكرة اتصلحت.
- **9146:** زرار الإلغاء بقى **X** (٢٦×٢٦، `aria-label`+`title` محافظين على الاسم المقروء). **لسه محتاج build+deploy** — مأجّل لحد ما وكيل 9167 يخلّص عشان مابنيش وسط تعديلاته.
- **9167 جديدة:** داشبورد العيادة — استبدال كارت «أبرز خدمات اليوم» بـ**مواعيد الأطباء**: تجميع بالقسم، اسم الطبيب + وقت الحضور، **اليوم فقط**؛ والبحث عن طبيب/قسم يفتح جدول الأسبوع كامل.
  - اتنفّذت على `GET /clinic/schedule-slots` الموجود — **من غير endpoint جديد ولا migration**. الفجوة الوحيدة كانت إن الـResource مابيرجّعش اسم القسم → اتصلحت في **الطبقة المشتركة** (`DoctorScheduleSlotResource` + eager-load) فاستفادت منها شاشة تحرير الجدول كمان.
  - **🔴 بوابة `feature_gate`:** التذكرة feature وبتطلب **تحليل عقد نطاق قبل أي تنفيذ**، وأنا نفّذت قبله. `transition → in_implementation` **مرفوض** من البورتال طول ما التحليل مانزلش. نزّلت تحليل (In/Out-of-Scope + معايير قبول) → الحالة بقت **`awaiting_client`** (step 4759). **الدرس: افحص `feature_gate.required` أول ما تذكرة `new` تظهر، قبل ما تدبّس وكيل.**
  - **افتراض جوهري صرّحت بيه للعميل:** «مواعيد» اتفهمت على إنها **جدول حضور الأطباء الأسبوعي** مش **حجوزات المرضى** (دليل: «وقت الحضور» + «على مدار الأسبوع»؛ والحجوزات ليها لوحة الطابور). لو قصده الحجوزات → مصدر بيانات مختلف وإعادة بناء.
  - **غلطتان في تقرير الوكيل اتصححوا بالفحص:** قال ٣ سلوتس كلهم سبت — الحقيقة **٥** وواحد منهم النهاردة (حد). وسيب **خطر ٤٠٣**: الـendpoint متحمي بـ`clinic.schedule.view` (**دورين بس** شايلينها) والكارت القديم مكانش متحمي → موظف استقبال كان هيشوف رسالة عطل. اتعالج: 401/403 → `slotsForbidden` تخفي اللوحة بهدوء بدل ما تبان عطل.
  - **متأجّل بقرار:** إعداد `clinic.dashboard_top_services_count` بقى ميت (متعرّف في seeder + validator + عليه تست) — **ماشيلتوش**، سألت العميل يشيله ولا يرجّع كارت الخدمات مكان تاني. والـBE لسه بيحسب `topServicesToday()` كل ٦٠ ثانية بدون مستهلك.
- **🔴 خطر بيئي اتلقى بالصدفة واتصلح:** `assets/config.json` كان بيعرض في **مبدّل الـAPI الظاهر للعميل** (`showApiSwitcher: true`) **باكند moonui2** بعنوان «own» (متوروث من حساب moonui2) — ضغطة واحدة وكان العميل يشتغل على **قاعدة بيانات نسخة تانية**، وده بالظبط اللي فصل النسخ المتوازية بيمنعه. اتغيّر لـmoonui3 في `src/` و`/app` — **وماينفعش يتعمله commit** (فخ config.json).
- **النشر:** `main-OGV6547V.js` · I18N_VERSION=`20260719e` · index 200 · i18n immutable · apiUrl moonui3 · steps 4741/4747/4748 (9164) · 4755 (9146) · 4759 (9167).

### دفعة 2026-07-20 #1 (CURSOR 4762→4940) — اللوب بقى كل ١٠ دقائق (طلب المالك)
- **9146 اتقفلت ✅.**
- **9167 (مواعيد الأطباء) رجعت `in_implementation`** بعد `scope_freeze` (العميل وافق على النطاق) + ٣ تعديلات: (1) خلفية اسم القسم **أخضر فاتح** مش غامق → `--mint`، (2) **شِلت صف العناوين المتكرر** (thead) اللي كان بيتكرر فوق كل قسم، (3) **وقت الحضور من/إلى** بدل البداية بس. اتنفّذوا + build `main-4O444YAD.js` + deploy.
  - **🔴 فخ decompose:** verification اترفض بـ`decomposition_gate` (عقد فيه ٤ بنود in-scope). اضطررت أعمل `POST /decompose {subtasks:[{title,description}]}` → أنشأ **٤ تذاكر فرعية حقيقية 9183-9186** في بورد العميل. verification على الأصل لسه محجوب لحد ما كلهم يتقفلوا. **كل subtask دورة كاملة:** `new` مايعديش لـ`in_implementation` مباشرة — لازم `transition→analysis` ثم `POST /analysis`→`awaiting_client`→موافقة عميل→`in_implementation`→verification. **الدرس اتسجّل في ذاكرة `portal-feature-gate-before-implementing`: جزّئ الخطة قبل البناء لو الفيتشر كبير، مش تبني الكل وتتفرض عليك تجزئة بعدين.** علّقت على 9167 أشرح للعميل بشفافية إن الـ٤ بنود منفّذة كلها ومنشورة ومحتاجة اعتماد بس.
  - **9183 → `client_review`** (اتقفل verification). 9184/9185/9186 **`awaiting_client`** (مستنيين العميل يوافق على تحليلهم).
- **متأجّلة لردّ العميل:**
  - **9163 (آلية الدفع):** العميل حسم الغموض — «لاحقًا الغيها مش مهمة». الآلية النهائية: الاستقبال يحصّل دايمًا (سعر الخدمة يظهر أوتوماتيك في الكاش، قابل للتعديل، الفيزا تنقص منه، الفرق يروح المتبقي، أو خصم)، **الإجمالي = الخصم+الكاش+الفيزا+المتبقي**؛ وبإعداد تاني السعر يظهر في المتبقي دايمًا فالتحصيل يروح الكاشير. عايز دفع متبقٍ عند الاستقبال والكاشير للحالات الجزئية. **قال «فكر وارجع لي قبل ما تنفذ عشان نتفق» → محتاج رد بخطة/عقد قبل أي كود.** (لسه مردّتش عليه في الدفعة دي — أولوية الدورة الجاية.)
  - **9168:** صلاحيات — علامة صح جوه التشيك بوكس + زر «تفعيل/إلغاء الكل». `planning_gate: required`. العميل بيسأل «الطلب واضح؟».
- **تذاكر جديدة لسه ماتفتحتش (كلها clinic/encounter):**
  - **9171 العلامات الحيوية:** صفحة مستقلة لإدخال + عرض حسب تاريخ الزيارة. `fg:false`.
  - **9172 التاريخ المرضي:** فصله في صفحة مستقلة. `fg:true` (عقد نطاق مطلوب).
  - **9176 صفحة الزيارات:** فيتشر كبيرة بصورة مرفقة — كارت بيانات مريض مشترك + آخر علامات حيوية، خانة ملاحظات حرجة (إطار أحمر)، وجزء زيارة (Complaint/Diagnosis multi-select + ملاحظات + X حذف). `fg:true`.
- **النشر:** `main-4O444YAD.js` · I18N_VERSION `20260719e` (مافيش تغيير مفاتيح) · index 200 · apiUrl moonui3.

### دفعة 2026-07-20 #2 (CURSOR 4945) — تخطيط التذاكر الجديدة (مفيش رد عميل)
- الـfeed كان كله أفعالي (verification 9183 + كومنتاتي على 9163/9168). **مفيش رد عميل جديد** — 9183 client_review · 9184/9185/9186 awaiting_client · 9163/9168 مستنيين العميل.
- **استغليت الفراغ في شغل مبادر على التذاكر الجديدة (9171/9172/9176 — كلها clinic/encounter).** وكيل استكشاف رسم خريطة كاملة، والخلاصة الحاسمة: **٨٠٪ من البنية موجودة بالفعل** → الخطر كان بناء المكرر.
  - **العلامات الحيوية (9171):** `encounter/vitals-panel/` موجود **وجواه trend table بيعرض آخر ٥ زيارات** (بالظبط «العرض حسب التاريخ»). service `clinic-vitals.service.ts`, model `ClinicalExamination` (table `clinical_examinations`, صف/encounter), endpoints `encounters/{id}/vitals` + `patients/{id}/vitals-history`. **precedent صفحة كاملة: `stations/vitals-station`** (worklist ممرضة).
  - **التاريخ المرضي (9172):** `encounter/history-panel/` + `clinic-history.service.ts` + محرك `history_questions`/`patient_history_answers`. **precedent: `stations/sheet-station`**.
  - **الكارت المشترك (9176):** `shared/clinic-patient-header/` موجود (identity + allergies + insurance + chronic + last labs + **outstanding**) — **بس مفيش آخر vitals** (الـsummary interface مالهاش vitals field) → ده الـbuild gap: إما أوسّع BE header أو أنده `vitals-history?limit=1`. Inputs: `patientId`, `summary`, `showIdentity`.
  - **Complaint/Diagnosis (9176):** الاتنين lookups موجودة — `clinic-complaint.service` + widget `shared/pick-multiselect/` (multiselect جاهز)، و`clinic-diagnosis.service` (`icd10` + `encounters/{id}/diagnoses`). عرض diagnosis كـmultiselect-dropdown هو الـFE الجديد الوحيد.
  - **نمط الصفحة الجديدة:** `clinic.routes.ts` → child من `ClinicLayoutComponent`, `canActivate:[permissionGuard]`, `data.permissions`, lazy `loadComponent`.
- **9176:** شفت الصورة المرفقة (كارت علوي بصفوف Examination/Past Medical/Past Surgical + DETAIL · بلوك Risks/Notes بإطار · جدول All Visits: Date/Complaint multiselect/Diagnosis multiselect/Notes/X + أزرار P.H/LAB/TTT/ADD NEW). نشرت **عقد نطاق مجزّأ ٤ أجزاء** (تفاديًا لفخ decompose) + ٤ أسئلة محورية (أهمها: كل صف زيارة = encounter كامل ولا سجل مبسّط؟) → `awaiting_client`.
- **9172:** عقد نطاق مختصر (يعيد استخدام history-panel) + سؤال «من ملف المريض ولا صفحة مستقلة؟» → `awaiting_client`.
- **9171:** كومنت (fg=false) بنفس السؤال + إني هبدأ فور الرد → `new`.
- **مبدأ متّبع:** درست قبل ما أبني، لقيت الموجود يغطي المطلوب، فرجعت للعميل بأسئلة فاصلة بدل بناء أعمى/مكرر — مش رجوع للمشغّل، ده قرار على التذكرة. [[study-before-implementing]] · [[portal-feature-gate-before-implementing]].

### دفعة 2026-07-20 #3 (CURSOR 4953→4967) — أول رد عميل على تجزئة 9167
- العميل **قفل 9183 ✅**، ووافق على نطاق **9184/9185/9186** (`scope_freeze`→`in_implementation`)، وقال «تمام» على 9167.
- رفعت **verification للـ٣ subtasks** → كلهم `client_review`. الأصل **9167 لسه محجوب** لحد ما العميل يقفل التلاتة (لازم `closed` مش `client_review`) — `open_subtasks: [9184,9185,9186]`.
- **باقي كله في ملعب العميل:** 9163/9168 (أسئلتي) · 9171/9172/9176 (أسئلة النطاق) · 9184/9185/9186 (client_review) · 9167 (محجوب).

### دفعة 2026-07-20 #4 (CURSOR 4979→4990) — العميل رد على كله + تنفيذ 9172
- **9184/9185/9186 اتقفلوا ✅** → **9167 verification نجح أخيرًا → `client_review`** (الأصل خلص، كل الـsubtasks مقفولة).
- **9172 (التاريخ المرضي) اتنفّذت ونُشرت:** وكيل بنى **صفحة مستقلة `/clinic/patients/:id/history`** (تعيد استخدام `history-panel` بـ`patientScopeOnly=true` — mode جاهز من 9140، بيشتغل بـpatientId لوحده بدون encounter). شال الـHistory tab من ملف المريض وحطّ زر topbar `openHistory()`. code-review طلع **PASS ماعدا MEDIUM**: `COMMON.NOT_FOUND` مفتاح مفقود في الـfallback → أضفته للغتين. build `main-UZP5OMBM.js` + deploy + verify. → `client_review`.
  - **🔴 tech-debt اتلقى (مش من شغلي، pre-existing):** `SheetStationComponent` (`stations/sheet`) بيرندر `history-panel` اللي بيحقن `MessageService` **بدون provider في شجرة clinic** → أي مسار بينده `messageService.add()` (toast خطأ حفظ/حذف) هيرمي `NullInjectorError`. صفحتي الجديدة بتوفّر MessageService محليًا فآمنة. **follow-up: إما provider في ClinicLayout أو محلي في sheet-station.** (سجّلته هنا بدل تذكرة portal — مش تلويث.) نفس الاحتمال في `vitals-station`؟ يتشاف.
- **رد العميل على التذاكر الجديدة:**
  - **9176 `scope_freeze` + رد على الأسئلة الأربعة (step 4981):** كل صف = **زيارة/كشف كاملة** (تاريخ + شكوى multiselect + تشخيص multiselect + ملاحظات)، **بتتحفظ أوتوماتيك بدون زر حفظ**. أزرار: **ADD NEW** (صف جديد) · **P.H/LAB/TTT** (الطبيب يعمل طلب أشعة / طلب تحاليل / روشتة علاج). قسم Notes الأزرق = **سطرين حرين**: خطة علاج عامة + ملاحظات صحية عامة. **الصفحة دي = الصفحة الأساسية للطبيب عشان يكشف** على الحالة. → جاهزة للتنفيذ (feature كبيرة، محتاجة تخطيط + وكيل).
  - **9171 رد واضح:** «صفحة واحدة، من ملف المريض + مستقلة لضبط الصلاحيات» = نفس نمط 9172 بالظبط. → **دبّست وكيل ينفّذها** (مع تنبيه: `vitals-panel` بياخد `encounterId` إجباري، مش patientScopeOnly زي history — الإدخال محتاج زيارة نشطة، العرض التاريخي عبر `getTrend(patientId)`).
  - **9168:** «انطلق + حل الإيرور اللي بيظهر أول ما أدخل صفحة الصلاحيات» = وافق على الفهم + **bug إضافي** (error عند فتح شاشة الصلاحيات). `planning_gate`. → دورة جاية.
- **النشر:** `main-UZP5OMBM.js` · I18N_VERSION `20260719f` · index 200 · apiUrl moonui3 · cache سليم.
- **جاهز للتنفيذ (دورات جاية):** 9176 (feature كبيرة) · 9168 (bug + زر تفعيل الكل). **9167/9172 في client_review.**
