# PRD — ClinicPro Phase 2

**تاریخ:** ۲۴ خرداد ۱۴۰۵
**نسخه:** 1.2
**وضعیت:** Draft

---

## خلاصه اجرایی

فاز ۲ پلتفرم **ClinicPro** را از یک سیستم نوبت‌دهی ساده به یک سیستم مدیریت کلینیک کامل تبدیل می‌کند. شامل پنل‌های اشتراکی، مدیریت پرسنل، پرونده بیمار، سرویس‌های درمانی و پنل پیامکی اختصاصی برای هر کلینیک/مطب.

---

## وضعیت فعلی پروژه

| ماژول                                  | Backend                                          | API Doc                                              |
| -------------------------------------- | ------------------------------------------------ | ---------------------------------------------------- |
| Auth (OTP + JWT + switch-context)      | ✅ کامل                                          | `docs/api/auth.md`                                   |
| Doctor profile                         | ✅ کامل                                          | `docs/api/doctor.md`                                 |
| Clinic management                      | ✅ کامل                                          | `docs/api/clinic.md`                                 |
| Appointment booking + settings         | ✅ کامل                                          | `docs/api/appointment.md`, `appointment-settings.md` |
| Secretary (`DoctorSecretary` entity)   | ✅ entity + API موجود                            | `docs/api/secretary.md`                              |
| Payment gateway (Mellat, SEP)          | ✅ کامل — `Payment.type='subscription'` هم موجود | `docs/api/payment.md`                                |
| SMS log + template                     | ✅ زیرساخت موجود                                 | `docs/api/sms.md`                                    |
| Wallet / Settlement                    | ✅ کامل                                          | `docs/api/settlement.md`                             |
| SiteConfig (key-value store)           | ✅ موجود                                         | `docs/api/admin.md` §Settings                        |
| Dashboard (clinic/doctor/secretary)    | ✅ کامل                                          | `docs/api/dashboard.md`                              |
| Rating, Blog, Representation, Location | ✅ کامل                                          | فایل‌های مربوطه در `docs/api/`                       |
| **Staff (پرسنل)**                      | ❌ entity وجود ندارد                             | ❌ فایل doc وجود ندارد                               |
| **Subscription tiers**                 | ❌ entity وجود ندارد                             | ❌ فایل doc وجود ندارد                               |
| **Clinic services**                    | ❌ entity وجود ندارد                             | ❌ فایل doc وجود ندارد                               |
| **Patient records**                    | ❌ entity وجود ندارد                             | ❌ فایل doc وجود ندارد                               |
| **SMS wallet/settings per clinic**     | ❌ entity وجود ندارد                             | ❌ بخش در sms.md وجود ندارد                          |

---

## اپیک‌ها

---

### اپیک ۱ — پرسنل (Staff)

#### توضیح

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

#### نیازمندی‌های کارکردی

| کد   | نیازمندی                                                                             |
| ---- | ------------------------------------------------------------------------------------ |
| F1.1 | ایجاد / ویرایش / غیرفعال‌سازی پرسنل — **حذف سخت ممنوع** (تاریخچه حفظ شود)            |
| F1.2 | فیلدها: نام و نام‌خانوادگی (اجباری)، شماره تماس، عنوان شغل، آدرس، کد ملی، وضعیت فعال |
| F1.3 | پرسنل به `entity_type + entity_id` وابسته است (کلینیک یا مطب)                        |
| F1.4 | لیست پرسنل فقط در scope کلینیک/مطب کاربر جاری نمایش داده می‌شود                      |
| F1.5 | در ایجاد ServiceItem و SessionService از لیست پرسنل انتخاب می‌شود                    |

#### Entity جدید

```
clinic_staff:
  id, uuid
  entity_type: 'doctor' | 'clinic'
  entity_id: int
  full_name: string (required)
  phone: string|null
  job_title: string|null
  address: text|null
  national_code: string(10)|null
  active: bool = true
  created_at, updated_at: int (Unix)
```

#### API

| Method  | Path                          | توضیح                      |
| ------- | ----------------------------- | -------------------------- |
| `GET`   | `/api/v1/staff`               | لیست پرسنل کاربر جاری      |
| `POST`  | `/api/v1/staff`               | ایجاد پرسنل جدید           |
| `PATCH` | `/api/v1/staff/{uuid}`        | ویرایش اطلاعات             |
| `PATCH` | `/api/v1/staff/{uuid}/toggle` | فعال/غیرفعال (soft delete) |

#### Frontend

- `StaffPage.tsx` — DataTable + Modal ایجاد/ویرایش
- Sidebar: زیر «تنظیمات»

#### فایل‌های جدید

- `src/Staff/Entity/ClinicStaff.php`
- `src/Staff/Controller/StaffController.php`
- `src/Staff/Repository/ClinicStaffRepository.php`
- `docs/api/staff.md` ← **باید ایجاد شود**

---

### اپیک ۲ — پنل اشتراکی (Subscription Tiers)

#### توضیح

سه سطح پنل با قابلیت‌های متفاوت. ادمین برای هر پنل دوره‌های زمانی با قیمت مشخص تعریف می‌کند. کلینیک/دکتر دوره + پنل انتخاب کرده و پرداخت می‌کند.

#### سطوح پنل

| Level | Name         | منشی   | قابلیت‌های اضافه              |
| ----- | ------------ | ------ | ----------------------------- |
| 0     | Free         | ۱ منشی | نوبت‌دهی — رایگان، بدون انقضا |
| 1     | Basic        | ۲ منشی | پرونده بیمار + سرویس‌ها       |
| 2     | Professional | ۵ منشی | پرونده بیمار + سرویس‌ها       |

#### دوره‌های اشتراک (مثال — ادمین تنظیم می‌کند)

| نوع     | مدت    | قیمت                            |
| ------- | ------ | ------------------------------- |
| تریال   | ۱ ماه  | ۰ ریال — فقط برای Basic، یک‌بار |
| ۱ ماهه  | ۱ ماه  | ادمین تعیین می‌کند              |
| ۳ ماهه  | ۳ ماه  | ادمین تعیین می‌کند              |
| ۶ ماهه  | ۶ ماه  | ادمین تعیین می‌کند              |
| ۱۲ ماهه | ۱۲ ماه | ادمین تعیین می‌کند              |

#### قوانین تریال

- فقط برای پنل **Basic**
- هر کلینیک/دکتر **یک‌بار** — بعد از استفاده، دکمه تریال نمایش داده نمی‌شود
- بدون پرداخت — endpoint مستقل دارد
- بعد از انقضا → برگشت به Free (داده‌ها حفظ می‌شوند)
- ادمین می‌تواند تریال را کلاً غیرفعال کند (`trial_enabled` در SiteConfig)

#### نیازمندی‌های کارکردی

| کد   | نیازمندی                                                                     |
| ---- | ---------------------------------------------------------------------------- |
| F2.1 | ادمین قیمت هر ترکیب (پنل × دوره) را تعریف می‌کند                             |
| F2.2 | ادمین می‌تواند دوره‌های جدید اضافه یا غیرفعال کند                            |
| F2.3 | پرداخت از طریق gateway موجود (Mellat/SEP) — `Payment.type='subscription'` ✅ |
| F2.4 | پس از پرداخت موفق: `starts_at=now`, `expires_at=now + months*30*86400`       |
| F2.5 | تمدید از تاریخ انقضای قبلی محاسبه می‌شود (نه از now)                         |
| F2.6 | gate check: `hasFeature('patient_records')` — اشتراک فعال و منقضی نشده       |
| F2.7 | هشدار ۷ روز قبل از انقضا به کلینیک/دکتر                                      |
| F2.8 | گزارش فروش برای ادمین (تعداد، درآمد، بر اساس سطح و دوره)                     |

#### Entities جدید

```
subscription_plans:
  id, uuid
  name: 'free' | 'basic' | 'professional'
  level: int (0/1/2)
  max_secretaries: int (1/2/5)
  features: json { patient_records, services, sms_panel }
  active: bool
  created_at, updated_at

subscription_periods:
  id, uuid
  plan_id → subscription_plans
  label: string ('۶ ماهه', 'تریال ۱ ماهه')
  duration_months: int
  price_rials: int  ← 0 برای تریال
  is_trial: bool = false
  active: bool
  sort_order: int
  created_at, updated_at

clinic_subscriptions:
  id, uuid
  entity_type: 'doctor' | 'clinic'
  entity_id: int
  plan_id → subscription_plans
  period_id → subscription_periods
  payment_id → payments  ← nullable (تریال = null)
  is_trial: bool
  starts_at: int
  expires_at: int  ← null = بی‌نهایت (Free)
  created_at
```

#### API

| Method   | Path                                       | Permission    | توضیح                                    |
| -------- | ------------------------------------------ | ------------- | ---------------------------------------- |
| `GET`    | `/api/v1/subscription/plans`               | public        | لیست پنل‌ها با دوره‌ها و قیمت‌ها         |
| `GET`    | `/api/v1/subscription/my`                  | clinic/doctor | اشتراک فعال + `used_trial` + تاریخ انقضا |
| `POST`   | `/api/v1/subscription/trial`               | clinic/doctor | فعال‌سازی تریال (رایگان، یک‌بار)         |
| `POST`   | `/api/v1/subscription-payment`             | clinic/doctor | شروع پرداخت — body: `{ period_uuid }`    |
| `GET`    | `/api/v1/admin/subscription/plans`         | admin         | لیست پنل‌ها                              |
| `POST`   | `/api/v1/admin/subscription/plan`          | admin         | ایجاد پنل                                |
| `PATCH`  | `/api/v1/admin/subscription/plan/{uuid}`   | admin         | ویرایش پنل                               |
| `POST`   | `/api/v1/admin/subscription/period`        | admin         | افزودن دوره جدید                         |
| `PATCH`  | `/api/v1/admin/subscription/period/{uuid}` | admin         | ویرایش قیمت/مدت                          |
| `DELETE` | `/api/v1/admin/subscription/period/{uuid}` | admin         | غیرفعال‌سازی دوره                        |
| `GET`    | `/api/v1/admin/subscription/report`        | admin         | گزارش فروش + تریال‌ها                    |

#### Frontend

- `SubscriptionPage.tsx`:
    - بنر تریال اگر `used_trial=false`
    - وضعیت پنل فعال + تاریخ انقضا (شمسی) + badge «تریال»
    - جدول مقایسه پنل‌ها با انتخاب دوره
    - دکمه خرید → redirect به gateway
- `AdminSubscriptionPage.tsx`:
    - تب «پنل‌ها»: ویرایش دوره‌ها و قیمت‌ها
    - تب «گزارش»: فروش بر اساس بازه زمانی

#### فایل‌های جدید

- `src/Subscription/Entity/SubscriptionPlan.php`
- `src/Subscription/Entity/SubscriptionPeriod.php`
- `src/Subscription/Entity/ClinicSubscription.php`
- `src/Subscription/Controller/SubscriptionController.php`
- `src/Subscription/Service/SubscriptionService.php`
- `docs/api/subscription.md` ← **باید ایجاد شود**

---

### اپیک ۳ — منشی (Secretary) — تکمیل

#### توضیح

Entity `DoctorSecretary` و API کامل موجود است (`docs/api/secretary.md`). باید:

- محدودیت تعداد بر اساس پنل اعمال شود
- UI مدیریت permissions تکمیل شود

#### نیازمندی‌های کارکردی

| کد   | نیازمندی                                                                               |
| ---- | -------------------------------------------------------------------------------------- |
| F3.1 | بررسی سقف پنل قبل از ایجاد: Free→1، Basic→2، Pro→5                                     |
| F3.2 | UI لیست منشی ها + اضافه‌کردن + ویرایش + غیرفعال‌سازی                                   |
| F3.3 | ویرایشگر permissions: checkbox matrix (موجود در `DoctorSecretary.DEFAULT_PERMISSIONS`) |
| F3.4 | منشی هرگز حذف نمی‌شود — `active: false`                                                |

#### تغییرات مورد نیاز

- **Backend:** `SecretaryController::create()` — بررسی سقف پنل با `SubscriptionService`
- **Frontend:** Modal با checkbox matrix برای permissions در `SecretariesPage.tsx`

#### API موجود (نیاز به تغییر ندارند)

`GET /api/v1/secretaries/{doctorUuid}` | `POST /api/v1/secretary` | `PATCH /api/v1/secretary/{uuid}` | `DELETE /api/v1/secretary/{uuid}`

---

### اپیک ۴ — سرویس‌های کلینیک (Clinic Services)

#### توضیح

دسترسی فقط در پنل Basic+. سرویس‌ها در دو سطح: بخش (مثلاً «تزریقات») و زیربخش (مثلاً «سرم»).

#### نیازمندی‌های کارکردی

| کد   | نیازمندی                                                           |
| ---- | ------------------------------------------------------------------ |
| F4.1 | CRUD بخش‌ها (ServiceSection)                                       |
| F4.2 | CRUD زیربخش‌ها (ServiceItem) با انتخاب بخش + پرسنل انجام‌دهنده     |
| F4.3 | قیمت هر زیربخش قابل ویرایش                                         |
| F4.4 | gate: `hasFeature('services')` — بدون Basic+ → 403                 |
| F4.5 | لیست ServiceItems در ثبت سشن بیمار استفاده می‌شود (وابستگی اپیک ۶) |

#### Entities جدید

```
service_sections:
  id, uuid
  entity_type: 'doctor' | 'clinic'
  entity_id: int
  name: string
  active: bool
  created_at, updated_at

service_items:
  id, uuid
  section_id → service_sections
  staff_id → clinic_staff  ← nullable
  name: string
  price_rials: int
  active: bool
  created_at, updated_at
```

#### API

| Method   | Path                                  | توضیح                  |
| -------- | ------------------------------------- | ---------------------- |
| `GET`    | `/api/v1/service-sections`            | لیست بخش‌ها            |
| `POST`   | `/api/v1/service-section`             | ایجاد بخش (Basic+)     |
| `PATCH`  | `/api/v1/service-section/{uuid}`      | ویرایش                 |
| `DELETE` | `/api/v1/service-section/{uuid}`      | حذف                    |
| `GET`    | `/api/v1/service-items/{sectionUuid}` | لیست زیربخش‌های یک بخش |
| `POST`   | `/api/v1/service-item`                | ایجاد زیربخش (Basic+)  |
| `PATCH`  | `/api/v1/service-item/{uuid}`         | ویرایش                 |
| `DELETE` | `/api/v1/service-item/{uuid}`         | حذف                    |

#### Frontend

- `ServicesPage.tsx` — accordion دو سطحی: بخش‌ها ← زیربخش‌ها

#### فایل‌های جدید

- `src/ClinicService/Entity/ServiceSection.php`
- `src/ClinicService/Entity/ServiceItem.php`
- `src/ClinicService/Controller/ClinicServiceController.php`
- `docs/api/clinic-services.md` ← **باید ایجاد شود**

---

### اپیک ۵ — پنل پیامکی (SMS Panel)

#### توضیح

زیرساخت SMS موجود است (`SmsLog`, `SmsTemplate`, `SmsProvider` در `src/Sms/`). باید:

- کیف پول پیامک اختصاصی برای هر کلینیک/دکتر
- تنظیمات ارسال پیامک (یادآوری، بعد از ویزیت)
- گزارش لاگ برای کلینیک و ادمین

#### نیازمندی‌های کارکردی

| کد   | نیازمندی                                                               |
| ---- | ---------------------------------------------------------------------- |
| F5.1 | کیف پول پیامک جدا از کیف پول مالی                                      |
| F5.2 | شارژ از طریق gateway موجود                                             |
| F5.3 | ادمین تعرفه هر پیامک را تعیین می‌کند (`sms_price_rials` در SiteConfig) |
| F5.4 | کسر خودکار هزینه بعد از هر ارسال موفق                                  |
| F5.5 | تنظیمات: یادآوری نوبت (فعال/غیرفعال + چند ساعت قبل)                    |
| F5.6 | تنظیمات: پیام بعد از ویزیت (فعال/غیرفعال + متن)                        |
| F5.7 | گزارش لاگ پیامک‌های کلینیک/مطب                                         |
| F5.8 | گزارش ادمین: مصرف هر کلینیک + درآمد پیامکی                             |

#### Entities جدید

```
sms_wallets:
  id
  entity_type: 'doctor' | 'clinic'
  entity_id: int
  balance_rials: int = 0
  created_at, updated_at

sms_settings:
  id
  entity_type: 'doctor' | 'clinic'
  entity_id: int
  reminder_enabled: bool = false
  reminder_hours_before: int = 2
  post_visit_enabled: bool = false
  post_visit_text: text|null
  updated_at
```

#### API

| Method  | Path                              | Permission    | توضیح                                    |
| ------- | --------------------------------- | ------------- | ---------------------------------------- |
| `GET`   | `/api/v1/sms/wallet/balance`      | clinic/doctor | موجودی کیف پول پیامک                     |
| `POST`  | `/api/v1/sms/wallet/charge`       | clinic/doctor | شارژ — body: `{ gateway, amount_rials }` |
| `GET`   | `/api/v1/sms/wallet/logs`         | clinic/doctor | تاریخچه کسر/شارژ                         |
| `GET`   | `/api/v1/sms/settings`            | clinic/doctor | تنظیمات پیامک                            |
| `PATCH` | `/api/v1/sms/settings`            | clinic/doctor | ذخیره تنظیمات                            |
| `GET`   | `/api/v1/admin/sms/wallet-report` | admin         | گزارش مصرف و درآمد                       |

#### Frontend

- تب «پیامک» در صفحه تنظیمات کلینیک/دکتر
- نمایش موجودی + دکمه شارژ + لاگ + فرم تنظیمات

#### تأثیر بر فایل‌های موجود

- `docs/api/sms.md` ← **بخش جدید wallet/settings اضافه شود**

---

### اپیک ۶ — پرونده بیمار (Patient Records)

#### توضیح

دسترسی فقط در پنل Basic+. پرونده به صورت خودکار پس از تأیید نوبت ایجاد می‌شود یا دستی توسط منشی/دکتر. هر مراجعه یک سشن است که شامل ویزیت + سرویس‌ها است.

#### نیازمندی‌های کارکردی

| کد   | نیازمندی                                                                      |
| ---- | ----------------------------------------------------------------------------- |
| F6.1 | ایجاد خودکار `PatientRecord` بعد از تأیید appointment (اگر وجود نداشت)        |
| F6.2 | ایجاد دستی توسط منشی یا دکتر                                                  |
| F6.3 | ثبت سشن: بیمه پایه + مکمل، مبلغ ویزیت (پیش‌فرض یا دستی)، محاسبه خودکار کسورات |
| F6.4 | ثبت سرویس‌های انجام‌شده در سشن با پرسنل انجام‌دهنده                           |
| F6.5 | gate: `hasFeature('patient_records')` — بدون Basic+ → 403                     |
| F6.6 | تاریخچه کامل مراجعات یک بیمار                                                 |

#### محاسبه مبلغ نهایی سشن

```
visit_price_rials           ← ادمین/دکتر تعیین می‌کند
- base_insurance_discount%  ← بیمه پایه
- supplementary_discount%   ← بیمه مکمل
+ service_items total       ← مجموع سرویس‌های انجام‌شده
= final_price_rials
```

#### Entities جدید

```
patient_records:
  id, uuid
  entity_type: 'doctor' | 'clinic'
  entity_id: int
  user_id → users  ← بیمار
  created_by_type: 'doctor' | 'secretary' | 'system'
  created_by_id: int
  created_at

patient_sessions:
  id, uuid
  record_id → patient_records
  appointment_id → appointments  ← nullable
  insurance_base_id → categories (bundle='insurance_type')  ← nullable
  insurance_supplementary_id → categories  ← nullable
  visit_price_rials: int
  base_insurance_discount_percent: float = 0
  supplementary_discount_percent: float = 0
  final_price_rials: int
  payment_method: 'cash' | 'card' | 'insurance' | 'pending'
  notes: text|null
  created_at, updated_at

session_services:
  id, uuid
  session_id → patient_sessions
  service_item_id → service_items
  staff_id → clinic_staff  ← nullable
  price_rials: int  ← قیمت در زمان ارائه (کپی از service_item)
  created_at
```

#### API

| Method  | Path                              | Permission             | توضیح                 |
| ------- | --------------------------------- | ---------------------- | --------------------- |
| `GET`   | `/api/v1/patients`                | clinic/doctor (basic+) | لیست بیماران با جستجو |
| `POST`  | `/api/v1/patient`                 | clinic/doctor (basic+) | ایجاد پرونده دستی     |
| `GET`   | `/api/v1/patient/{uuid}`          | clinic/doctor          | جزئیات پرونده         |
| `GET`   | `/api/v1/patient/{uuid}/sessions` | clinic/doctor          | لیست مراجعات          |
| `POST`  | `/api/v1/patient/{uuid}/session`  | clinic/doctor          | ثبت مراجعه جدید       |
| `PATCH` | `/api/v1/session/{uuid}`          | clinic/doctor          | ویرایش مراجعه         |

#### Frontend

- `PatientsPage.tsx` — لیست بیماران + جستجو
- `PatientDetailPage.tsx` — پرونده + تاریخچه مراجعات
- Modal ثبت سشن جدید (بیمه + ویزیت + سرویس‌ها)

#### فایل‌های جدید

- `src/Patient/Entity/PatientRecord.php`
- `src/Patient/Entity/PatientSession.php`
- `src/Patient/Entity/SessionService.php`
- `src/Patient/Controller/PatientController.php`
- `docs/api/patient.md` ← **باید ایجاد شود**

---

### اپیک ۷ — داشبورد هوشمند (Smart Dashboard)

#### توضیح

داشبوردهای موجود (clinic/doctor/secretary در `docs/api/dashboard.md`) باید با چارت و فیلتر بازه زمانی تکمیل شوند.

#### نیازمندی‌های کارکردی

| کد   | نیازمندی                                                                |
| ---- | ----------------------------------------------------------------------- |
| F7.1 | داشبورد ادمین: چارت درآمد + چارت نوبت‌ها + گزارش فروش پنل‌ها            |
| F7.2 | داشبورد کلینیک/مطب: درآمد ماه جاری + بیماران منحصربه‌فرد + موجودی پیامک |
| F7.3 | فیلتر بازه زمانی: این هفته / این ماه / ۳ ماه / سفارشی                   |
| F7.4 | فیلتر نقش: منشی فقط نوبت‌ها را می‌بیند                                  |

#### API موجود (نیاز به endpoint جدید ندارد)

`GET /api/v1/admin/dashboard/stats` | `/charts` | `/recent`
`GET /api/v1/dashboard/clinic` | `/doctor` | `/secretary`

#### تغییر مورد نیاز

- backend: اضافه کردن پارامترهای `from` و `to` به endpoint های charts
- frontend: `DashboardPage.tsx` — افزودن date range selector + نمودارها (Recharts/Chart.js)

---

## اولویت‌بندی پیاده‌سازی

| اولویت | اپیک                     | وابستگی                       |
| ------ | ------------------------ | ----------------------------- |
| ۱      | اپیک ۱ — Staff           | پیش‌نیاز اپیک ۴ و ۶           |
| ۲      | اپیک ۲ — Subscription    | پیش‌نیاز gate در اپیک ۳، ۴، ۶ |
| ۳      | اپیک ۳ — Secretary تکمیل | وابسته به اپیک ۲              |
| ۴      | اپیک ۴ — Services        | وابسته به اپیک ۱ و ۲          |
| ۵      | اپیک ۵ — SMS Panel       | مستقل                         |
| ۶      | اپیک ۶ — Patient Records | وابسته به اپیک ۱، ۲، ۴        |
| ۷      | اپیک ۷ — Dashboard       | آخر — نیاز به داده واقعی      |

---

## نقشه Entity‌های جدید

```
clinic_staff ←──────────────── service_items ←─── session_services
     ↑                               ↑                     ↑
     │                         service_sections      patient_sessions
     │                               ↑                     ↑
     │                         entity_type/id        patient_records
     │                                                     ↑
subscription_plans ←── subscription_periods        entity_type/id
         └──────────── clinic_subscriptions
                              ↑
                        payment (موجود)

sms_wallets    sms_settings
(entity_type/id)
```

---

## زیرساخت موجود قابل استفاده

| زیرساخت                       | مسیر                               | استفاده در فاز ۲                      |
| ----------------------------- | ---------------------------------- | ------------------------------------- |
| Payment gateway               | `src/Payment/`                     | پرداخت subscription + شارژ SMS wallet |
| `Payment.type='subscription'` | `Payment::TYPE_SUBSCRIPTION`       | پرداخت پنل اشتراکی — موجود ✅         |
| SiteConfig (key-value)        | `src/Config/Entity/SiteConfig.php` | `sms_price_rials`, `trial_enabled`    |
| Categories (insurance)        | `bundle='insurance_type'`          | انتخاب بیمه در PatientSession         |
| DoctorSecretary               | `src/Secretary/Entity/`            | اضافه کردن gate check                 |
| SmsLog/SmsTemplate            | `src/Sms/Entity/`                  | ارسال پیامک‌های خودکار                |
| WalletTransaction             | `src/Settlement/Entity/`           | الگوی مشابه برای SmsWallet            |

---

## معماری مشترک

- همه entity‌های جدید: Unix timestamp (`int`) برای `created_at`, `updated_at`
- همه controller‌های جدید از `BaseController` ارث می‌برند
- پاسخ‌ها: `$this->success()` / `$this->paginated()` / `$this->error()`
- polymorphic pattern: `entity_type: 'doctor'|'clinic'` + `entity_id`
- gate check: `SubscriptionService::hasFeature(string $feature): bool`

---

## Definition of Done (هر اپیک)

- [ ] Migration ایجاد و اجرا شده
- [ ] Entity + Repository + Service نوشته شده
- [ ] Controller با همه endpoints کامل شده
- [ ] Type check frontend بدون خطا (`yarn dev`)
- [ ] API قابل تست در Swagger (`/api/doc`)
- [ ] فایل `docs/api/xxx.md` ایجاد یا بروزرسانی شده
