feat(doctors): enhance doctor listing with bookable sorting and filtering, add JSON_EXTRACT DQL function

This commit is contained in:
hamed
2026-07-14 11:25:39 +03:30
parent d2372d4d21
commit 34d8a400b7
6 changed files with 189 additions and 7 deletions
+15 -1
View File
@@ -180,7 +180,7 @@ Get doctor detail for clinic owner — only doctors who are members of the authe
| `hours_of_work` | خلاصه ساعت‌های روزهای فعال با `\|` جداشده | «برنامه کاری تنظیم نشده» |
| `active` | `online_booking_enabled && has_active_sessions` | `false` — نوبت‌دهی غیرفعال |
> **نوبت‌دهی آنلاین غیرفعال:** منبعِ فعال/غیرفعال بودن نوبت‌دهی آنلاین، فیلد `meta.online_booking_enabled` در `WeeklySchedule` پزشک است. اگر `false` باشد، صرف‌نظر از سشن‌های برنامه‌ی هفتگی، `free_turn` همیشه `"نوبت‌دهی آنلاین غیرفعال است"` و `active` برابر `false` برمی‌گردد؛ `hours_of_work` در صورت وجود برنامه حفظ می‌شود. چنین پزشکی در لیست عمومی `GET /api/v1/doctors` (پیش‌فرض `active=true`) نمایش داده نمی‌شود، ولی صفحه‌ی تکی `GET /api/v1/doctor/{slug}` همچنان قابل دسترسی است.
> **نوبت‌دهی آنلاین غیرفعال:** منبعِ فعال/غیرفعال بودن نوبت‌دهی آنلاین، فیلد `meta.online_booking_enabled` در `WeeklySchedule` پزشک است. اگر `false` باشد، صرف‌نظر از سشن‌های برنامه‌ی هفتگی، `free_turn` همیشه `"نوبت‌دهی آنلاین غیرفعال است"` و `active` برابر `false` برمی‌گردد؛ `hours_of_work` در صورت وجود برنامه حفظ می‌شود. چنین پزشکی در لیست عمومی `GET /api/v1/doctors` نمایش داده می‌شود ولی پایین‌تر از پزشکان دارای نوبت قرار می‌گیرد و با فیلتر `active=1` حذف می‌شود؛ صفحه‌ی تکی `GET /api/v1/doctor/{slug}` همچنان قابل دسترسی است.
---
@@ -200,6 +200,20 @@ List doctors with pagination and filters.
| `city_id` | integer | ❌ | Filter by city ID — شامل دکترهایی که آدرس شخصی‌شان (`doctor_addresses.city_id`, با `doctor_id` مقداردار) در آن شهر است یا از طریق کلینیکی که آدرس آن در آن شهر است (`doctor_addresses.clinic_id`) |
| `state_id` | integer | ❌ | Filter by province ID — بر اساس آدرس شخصی پزشک (`doctor_addresses.province_id`) یا آدرس کلینیک |
| `domain` | string | ❌ | دامنه‌ی سایتِ درخواست‌کننده. اگر دامنه‌ی یک **نماینده سراسری** باشد، فقط پزشکانِ همان نماینده برمی‌گردند و `city_id`/`state_id` نادیده گرفته می‌شوند؛ دامنه شهری/ناشناخته اثری ندارد |
| `gender` | string | ❌ | `man` یا `woman` |
| `degree` | string | ❌ | `expert`, `general`, `specialist`, `subspecialistplus` |
| `name` | string | ❌ | جستجوی `LIKE` روی نام پزشک |
| `sort` | string | ❌ | `ASC` یا `DESC` (پیش‌فرض `DESC`) — مرتب‌سازی ثانویه بر اساس `doctorRate` |
| `active` | `0`/`1` | ❌ | `1` → فقط پزشکان **دارای نوبت** (تعریف پایین). `0` → فقط پزشکانی که فلگ `active_doctor_appointment` آن‌ها خاموش است (کاربرد ادمین). بدون این پارامتر → **همه** پزشکان برمی‌گردند |
### مرتب‌سازی و تعریف «دارای نوبت»
پزشک **دارای نوبت** یعنی هر سه شرط برقرار باشد (همان تعریفی که فیلد `active` هر آیتم پاسخ را می‌سازد):
1. فلگ `active_doctor_appointment` روشن،
2. `WeeklySchedule` ثبت‌شده با حداقل یک سشن `active: true`،
3. `meta.online_booking_enabled` برابر `false` نباشد.
لیست همیشه اول پزشکان دارای نوبت را نشان می‌دهد و بعد بقیه را؛ داخل هر گروه بر اساس `doctorRate` و پارامتر `sort` مرتب می‌شود.
### Response `200`
```json