# فاز ۵ — پریو، لابراتوار، استریلیزاسیون، مواد مصرفی و تصاویر

> پیش‌نیاز: فاز ۱ تا ۴.
> خروجی قابل تست: شاخص‌های هزینه و کیفیت، و ثبت بالینی کامل‌تر.

این فاز چهار موضوع مستقل دارد.
هرکدام جداگانه قابل اجراست و ترتیبشان اجباری نیست.

---

## ۱. مواد مصرفی — عمدتاً موجود است

`Inventory` و `SessionConsumable` از قبل هستند.

| موجودیت | مسیر |
|---|---|
| `InventoryItem` | `src/Inventory/Entity/InventoryItem.php` |
| `InventoryPackage` و `InventoryPackageItem` | همان پوشه |
| `SessionConsumable` | `src/Patient/Entity/SessionConsumable.php` |
| `ServiceItemConsumable` | `src/ClinicService/Entity/ServiceItemConsumable.php` |

قیمت در `SessionConsumable` اسنپ‌شات می‌شود، مثل `SessionService`.
`ServiceItem` هم می‌تواند به یک بستهٔ مصرفی وصل شود.

**پس کار این فاز فقط این است:**

- بستهٔ پیش‌فرض دندانپزشکی به `DentalPreset` اضافه شود: کامپوزیت، ماده بی‌حسی، فایل روتاری، سوزن، ماسک، دستکش.
- شاخص `consumable_cost_ratio` به `DentalMetricProvider` اضافه شود.

هیچ موجودیت تازه‌ای لازم نیست.
اگر کسی جدول مصرف مواد دندانپزشکی جدا ساخت، منبع حقیقت دوم ساخته است.

### تسک‌ها

| کد | تسک | معیار پذیرش |
|---|---|---|
| DM5-01 | بستهٔ مصرفی دندانپزشکی در قالب پیش‌فرض | نصب دوم چیزی تکرار نمی‌کند |
| DM5-02 | شاخص `consumable_cost_ratio` | مخرج صفر، `null` می‌دهد |

---

## ۲. لابراتوار — تازه است

### مدل داده

`Lab` — جدول `dental_labs`

| ستون | نوع |
|---|---|
| `id`, `uuid` | |
| `entity_type`, `entity_id` | جفت محیط |
| `title` | string 150 |
| `phone` | string 20, nullable |
| `active` | bool |
| `created_at`, `updated_at` | int |

`LabOrder` — جدول `dental_lab_orders`

| ستون | نوع | توضیح |
|---|---|---|
| `id`, `uuid` | | |
| `entity_type`, `entity_id` | | |
| `lab_id` | int | |
| `patient_record_id` | int | |
| `estimate_item_id` | int, nullable | ردیف برآوردی که این سفارش برایش است |
| `tooth_numbers` | json | دندان‌های درگیر |
| `description` | string 500 | |
| `status` | string 20 | |
| `cost_rials` | int | |
| `sent_at`, `due_at`, `received_at` | int, nullable | |
| `created_at`, `updated_at` | int | |

### ماشین حالت

```
draft ─▶ sent ─▶ in_lab ─▶ ready ─▶ received ─▶ delivered
                   └────▶ returned_for_fix ─▶ in_lab
```

`due_at` مبنای هشدار تأخیر است.
یک job روزانه سفارش‌های گذشته از موعد و در حالت غیرنهایی را برای داشبورد علامت می‌زند.

اتصال به `estimate_item_id` اختیاری است ولی توصیه‌شده.
بدون آن، بهای تمام‌شدهٔ آن ردیف قابل محاسبه نیست و شاخص حاشیهٔ سود بی‌معنا می‌شود.

### API

```
GET    /api/v1/dental/labs
POST   /api/v1/dental/lab
PATCH  /api/v1/dental/lab/{uuid}

GET    /api/v1/dental/lab-orders?status=&overdue=
POST   /api/v1/dental/lab-order
PATCH  /api/v1/dental/lab-order/{uuid}
POST   /api/v1/dental/lab-order/{uuid}/transition
```

دسترسی: هر چهار نقش می‌بینند و ثبت می‌کنند. لابراتوار کار مشترک درمانگاه است.

### شاخص‌ها

| کلید | تعریف |
|---|---|
| `lab_cost_ratio` | جمع هزینهٔ لابراتوار تقسیم بر تولید |
| `lab_overdue_count` | تعداد سفارش گذشته از موعد |
| `lab_turnaround_days` | میانگین فاصلهٔ ارسال تا دریافت |

### تسک‌ها

| کد | تسک | معیار پذیرش |
|---|---|---|
| DM5-03 | موجودیت `Lab` و مخزن | یکتایی نام در محیط |
| DM5-04 | موجودیت `LabOrder` و ماشین حالت | گذار غیرمجاز `AppException` |
| DM5-05 | اندپوینت‌های لابراتوار | همهٔ حالت‌های دسترسی |
| DM5-06 | job هشدار تأخیر | سفارش نهایی‌شده علامت نمی‌خورد |
| DM5-07 | سه شاخص لابراتوار | مخرج صفر |
| DM5-08 | صفحهٔ لابراتوار در پنل | فیلتر وضعیت و تأخیر |

---

## ۳. چارت پریودنتال — تازه است

### مدل داده

`PeriodontalExam` — جدول `dental_periodontal_exams`

| ستون | نوع |
|---|---|
| `id`, `uuid` | |
| `chart_id` | int |
| `examined_at` | int |
| `examined_by_user_id` | int, nullable |
| `note` | string 500, nullable |

`PeriodontalMeasurement` — جدول `dental_periodontal_measurements`

| ستون | نوع | توضیح |
|---|---|---|
| `exam_id` | int | `ON DELETE CASCADE` |
| `tooth_number` | smallint | |
| `site` | smallint | ۱ تا ۶ |
| `pocket_depth` | smallint | میلی‌متر |
| `recession` | smallint | |
| `bleeding_on_probing` | bool | |
| `mobility` | smallint | ۰ تا ۳ |

**چرا معاینه جدا از اندازه‌گیری:**
پریو دنباله‌ای است. مقایسهٔ معاینهٔ امروز با شش ماه پیش تمام ارزش این چارت است.
اگر اندازه‌ها روی خود دندان بازنویسی شوند، آن مقایسه از بین می‌رود.
این دقیقاً قرینهٔ `ToothStatus` است که عمداً فقط وضعیت جاری را نگه می‌دارد.

ثبت کامل یک معاینه ۱۹۲ عدد است.
پس فرم باید صفحه‌کلیدمحور باشد و با `Tab` پیش برود، وگرنه کسی استفاده‌اش نمی‌کند.

### تسک‌ها

| کد | تسک | معیار پذیرش |
|---|---|---|
| DM5-09 | دو موجودیت پریو | یکتایی دندان و سایت در معاینه |
| DM5-10 | اندپوینت ثبت و خواندن معاینه | ثبت دسته‌ای در یک درخواست |
| DM5-11 | فرم پریو صفحه‌کلیدمحور | حرکت با `Tab` بین سایت‌ها |
| DM5-12 | نمای مقایسهٔ دو معاینه | اختلاف با رنگ نشان داده می‌شود |

---

## ۴. استریلیزاسیون — تازه است

### مدل داده

`SterilizationCycle` — جدول `dental_sterilization_cycles`

| ستون | نوع |
|---|---|
| `id`, `uuid` | |
| `entity_type`, `entity_id` | |
| `device_resource_id` | int, nullable |
| `program` | string 50 |
| `started_at`, `finished_at` | int |
| `chemical_indicator_ok` | bool |
| `biological_test_at` | int, nullable |
| `result` | string 20 |
| `operator_user_id` | int, nullable |
| `note` | string 500, nullable |

اتوکلاو به‌عنوان `ClinicResource` تعریف می‌شود، نه یک جدول دستگاه تازه.
دلیل: نوع منبع از قبل قابل تعریف است و تقویم و دسترسی‌اش هم همان‌جاست.

در این فاز، سیکل استریل به گردش کار درمان گره نمی‌خورد.
فقط ثبت و گزارش است.
گره‌زدن ست ابزار به جلسهٔ درمان کار بزرگی است و باید جدا تصمیم‌گیری شود.

### تسک‌ها

| کد | تسک | معیار پذیرش |
|---|---|---|
| DM5-13 | موجودیت سیکل استریل | ثبت بدون دستگاه هم ممکن است |
| DM5-14 | اندپوینت ثبت و فهرست | فیلتر بازه و نتیجه |
| DM5-15 | یادآور تست بیولوژیک هفتگی | نبود تست در هفته، هشدار داشبورد |
| DM5-16 | صفحهٔ استریلیزاسیون در پنل | گزارش قابل چاپ |

---

## ۵. تصاویر بالینی — روی سیستم موجود

`PatientAttachment` از قبل هست و به پرونده وصل است.

کار این بخش فقط افزودن دو ستون اختیاری است:

```
tooth_numbers  json      nullable
image_type     string 20 nullable    periapical | bitewing | opg | cbct | photo
```

**چرا ستون روی همان جدول و نه جدول دندانی جدا:**
برخلاف ویژگی خدمت که تنظیمات مشترک همهٔ حوزه‌هاست، ضمیمه سند خود پرونده است و هر حوزه‌ای می‌تواند تصویر داشته باشد.
جدول جدا یعنی یک ضمیمه در دو جا و دو مسیر آپلود.

### تسک‌ها

| کد | تسک | معیار پذیرش |
|---|---|---|
| DM5-17 | دو ستون روی `PatientAttachment` | ضمیمهٔ بدون دندان مثل قبل کار می‌کند |
| DM5-18 | فیلتر ضمیمه بر اساس دندان در تب چارت | کلیک روی دندان، تصاویرش را نشان می‌دهد |

---

## ۶. رضایت آگاهانه — خارج از این سند

فرم رضایت آگاهانه در همهٔ حوزه‌ها لازم است، نه فقط دندانپزشکی.
ساختنش داخل ماژول دندانپزشکی یعنی حوزهٔ بعدی باید دوباره بسازدش.
پیشنهاد: سند جدا، در سطح پرونده بیمار.
