# م5 (الطابور ومحطات الزيارة) — نقطة الوقف المؤقت (2026-07-07)

> **⏸️ متوقفة مؤقتًا** بطلب المالك (تعديل في التحاليل/LIS الأول). **مفيش كود لـم5 — الاستكشاف بس.** عند العودة: كمّل من «الخطوة الجاية» تحت بلا إعادة استكشاف.

## نقطة الوقف
- ✅ **استكشاف المحطات (vitals/history/readiness) خلص** — الخريطة محفوظة تحت.
- 🔄 **استكشاف الطابور/الزيارة (queue/encounter) كان شغّال لحظة الوقف** — لو خلّص، نتيجته في transcript؛ لو لأ يُعاد.
- ⬜ عقد Fable لنطاق م5 — لسه.
- ⬜ الـWPs — لسه.

## الخطوة الجاية عند العودة
1. تأكّد من نتيجة سكاوت الطابور (أو أعِد سكاوت queue/encounter سريع).
2. **عقد Fable لنطاق م5** (زي م4): النطاق + الـWPs + DAG + القرارات.
3. تنفيذ WP-by-WP (native+Codex لكل WP، Fable لكل قرار).

## خطة م5 (من `topics/clinic-execution-phases.md`)
طابور حي (encounters + waited حقيقي + إلغاء/no-show + urgent + auto-close عند التوقيع) · **محطة القياسات** (worklist للتمريض، `clinic.vitals.record`) · **محطة الشيت** (المساعد، `clinic.history.record`) · **علامات جاهزية مشتقة** (✓قياسات ✓شيت على كارت الطابور) · إعداد `clinic.visit_stations` · «now serving» + drag-reorder.

## 🗺️ خريطة استكشاف المحطات (خلصت — للـFable)
**موجود وجاهز لإعادة الاستخدام (مفيش بناء):**
- **محرّك القياسات BE:** `VitalsController` (`GET/PATCH encounters/{e}/vitals`، perms `vitals.view`/`vitals.record`) + `VitalsService::upsert` (lock-check + BMI) + `ClinicalExamination` (جدول ثابت 1:1). WORKS.
- **محرّك الشيت BE (scope=encounter):** `EncounterHistoryController::show/upsert` (`GET/PUT encounters/{e}/history`، perms `history.view`/`history.record`) + `HistoryService::saveAnswers` + `HistoryScope` enum + `PatientHistoryAnswer` (scope_key=encounter_id??0). WORKS.
- **لوحات FE standalone:** `vitals-panel.component` (`@Input encounterId/locked` — مستقل تمامًا) · `history-panel.component` (`@Input encounterId/patientId/locked` — بيجمع شيت الزيارة + هيستوري المريض profile). الاتنين مستخدمين حاليًا **في `consultation.component` فقط**. reusable as-is.
- **الصلاحيات موجودة أصلًا (مش net-new):** `clinic.vitals.record` + `clinic.history.record` في الكتالوج + route middleware + `ClinicPermissionDependencies` (bundles جاهزة `[vitals.record, queue.view]` و`[history.record, queue.view]`). ⚠️ **الخطة افترضت إنها محتاجة إنشاء — غلط، موجودة.**

**net-new (شغل م5):**
- **شاشتا worklist للمحطات** (تمريض قياسات / مساعد شيت) — MISSING. thin wrappers بيجيبوا encounterId من طابور ويركّبوا اللوحات الموجودة. (قرار: شاشة الشيت تخفي أقسام هيستوري-المريض profile ولا تسيبها؟)
- **اشتقاق الجاهزية (✓vitals ✓sheet)** — MISSING تمامًا BE+FE. `QueueController` بيستعلم `Appointment` (arrived/in_consultation) بلا أعلام. الحل: `EXISTS(clinical_examinations WHERE encounter_id)` / `EXISTS(patient_history_answers WHERE encounter_id AND question.scope=encounter)` على `QueueEntryResource` + امتداد FE interface + كارت الطابور.
- **إعداد `clinic.visit_stations`** — MISSING من الـseeder. تعريف جديد (enum: merged/split زي `ordering_mode`) يتحكم في فصل/دمج المحطات.

## 🗺️ خريطة استكشاف الطابور/الزيارة (خلصت بعد الوقف — للـFable)
**نبني عليه:** آلة حالة الموعد (`TransitionAppointmentStatus`) · `MarkArrived`+`AssignQueueNumberListener` (queue_no شغّال، dept-letter+sequence per-branch/daily) · `EncounterService` دورة كاملة (open/markDone/sign/cancel) + `SyncAppointmentStatus` (arrived→in_consultation عند بدء الكشف) · DataScope branch filter شغّال في الطابورين.

**net-new / bugs (شغل م5):**
- 🔴 **أعلى أولوية — auto-close مفقود (bug):** توقيع/إلغاء الـEncounter **مابيحوّلش الموعد** لـdone/cancelled → الطابور يفضل يعرض «in consultation» للأبد. الحل: listener على `EncounterSigned`/`EncounterCancelled` (الأخير **مابيطلقش event حاليًا** — لازم يُضاف) يحوّل الموعد. **ده اللي يخلّي الطابور «حي» يفضّي نفسه.**
- **الطابور مصدره Appointment (مؤقت)** مش Encounter (docblock: «P4-WP-12 هيحوّل لـEncounter.queue_no» ماتعملش؛ `Encounter.queue_no` عمود ميت). القرار: نفضل على Appointment ولا نحوّل؟ (Fable).
- **نسختان FE للطابور:** (١) لوحة الداشبورد (`clinic-dashboard.component.html:81-124`، «Waited» hardcoded `—`، مفيش urgent) — دي اللي المستخدم شايفها. (٢) `VisitQueueComponent` (shared/visit-queue) **يتيمة تمامًا + field-shape mismatch** مع `QueueEntryResource` (patient object مش string، مفيش service، waited_since مش waited_minutes). القرار: نصلّح اليتيمة ونوصّلها ولا نمدّد لوحة الداشبورد؟ (Fable).
- **waited (وقت الانتظار):** net-new — مفيش حساب مدة؛ بس `waited_since` timestamp خام في الـresource غير المستخدَم.
- **urgent:** موجود end-to-end على Appointment/الحجز/القائمة بس **غير ظاهر ولا مؤثّر في ترتيب** أي طابور. لازم يظهر + priority sort.
- **no-show:** في الـenum بس **مايوصلش إلا من booked** (مش من arrived) — «واصل واختفى» محتاج مسار جديد/timeout.
- **now-serving/شاشة انتظار + drag-reorder:** net-new تمامًا (مفيش route/component/reorder endpoint).
- **فلتر dept/doctor على الطابور:** net-new (الطابورين مافيهمش، بعكس Appointment/Encounter controllers اللي عندهم). صلاحية `clinic.queue.view` موجودة.

## مراجع
الخطة: `topics/clinic-execution-phases.md` §م5 · المبدأ: `topics/clinic-principles.md` §المحطات الثلاث + §«يختار مش يكتب» · نقطة المديول: `plans/CLINIC-MODULE-FREEZE-RESUME.md`.
