feat: Enhance appointment management by decoupling online booking toggle for admin context

- Introduced management mode for appointment slots, allowing doctors, admins, and clinic managers to view and book slots regardless of the online booking status.
- Updated SlotCalculatorService to accept a management context parameter, bypassing online booking restrictions.
- Modified appointment-related endpoints to handle management context and ensure proper authorization checks.
- Added tests to verify that management users can access slots even when online booking is disabled, while public users are still restricted.
- Improved documentation for API endpoints to reflect new management parameters and behaviors.
This commit is contained in:
hamed
2026-07-22 16:43:56 +03:30
parent 5507b42fd8
commit ed516c81a8
16 changed files with 658 additions and 83 deletions
+15 -3
View File
@@ -8,13 +8,19 @@
Get all appointment slots (available and booked) for a doctor on a specific date.
**Permission:** `PUBLIC`
**Permission:** `PUBLIC` (anonymous), plus an authenticated **management** mode — see `management` below.
### Query Parameters
| Param | Type | Required | Description |
|-------|------|----------|-------------|
| `doctor_uuid` | string (UUID) | ✅ | Doctor UUID |
| `date` | string | ✅ | Date in `Y-m-d` format (e.g. `2024-06-15`) |
| `clinic_uuid` | string (UUID) | ❌ | Booking context; omitted = doctor's personal office |
| `management` | `1` | ❌ | Management mode — see note |
> **Management mode (`management=1`).** Turning off online booking (`online_booking_enabled=false`) or the advance booking-window limit are **public-site rules only**. When the request carries a **valid JWT** of a user who may manage this doctor/clinic's appointments (admin, the doctor themself, a clinic manager/secretary with the `appointments` permission), passing `management=1` bypasses those two gates so the panel always shows slots. Past dates are still rejected. If the token is missing or the user is not authorized, `management` is ignored and the endpoint behaves as public (fail-safe). Same flag applies to `/appointment-service-slots`, `/appointment-booking-locations/{doctorUuid}`, and `/appointment-settings/month-availability/{doctorUuid}`.
>
> These four routes moved from the `security: false` firewall onto the JWT firewall so a bearer token can be authenticated on them; anonymous callers still reach them via the `PUBLIC_ACCESS` access-control rules.
### Response `200`
```json
@@ -79,6 +85,7 @@ Get all appointment slots (available and booked) for a doctor on a specific date
| `date` | string `Y-m-d` | ✅ | |
| `service_item_uuids[]` | string[] | ✅ | یک یا چند UUID سرویسِ bookable |
| `durations[<service_uuid>]` | int | ❌ | override مدت (دقیقه) برای همان سرویس — فقط در این محاسبه استفاده می‌شود و مقدار پیش‌فرضِ سرویس در تنظیمات تغییر نمی‌کند. برای نوبت‌دهیِ منشی که مدت را برای یک نوبت تغییر می‌دهد. مقدار ≤ 0 یا غایب ⇒ مدت پیش‌فرض سرویس |
| `management` | `1` | ❌ | حالت مدیریت — با JWTِ مجاز، توگلِ نوبت‌دهی آنلاین و سقف بازهٔ رزرو دور زده می‌شود (رجوع به توضیح `/appointment-slots`) |
### Response `200`
```json
@@ -148,6 +155,8 @@ Which days of a month are bookable — used by the public calendar to grey out u
|-------|------|----------|-------------|
| `year` | integer | ✅ | **Gregorian** year (e.g. `2026`) |
| `month` | integer | ✅ | Gregorian month `1``12` |
| `clinic_uuid` | string (UUID) | ❌ | Booking context; omitted = personal office |
| `management` | `1` | ❌ | حالت مدیریت — با JWTِ مجاز، توگلِ نوبت‌دهی آنلاین دور زده می‌شود (رجوع به `/appointment-slots`) |
> Input is Gregorian. A Jalali (Shamsi) front-end must convert the displayed month to the Gregorian month(s) it spans before calling.
@@ -897,8 +906,11 @@ once per-context schedules existed.
### GET `/api/v1/appointment-booking-locations/{doctorUuid}`
**Permission:** public — whitelisted in `config/packages/security.yaml` (both the
`public_endpoints` firewall pattern and an `access_control` entry).
**Permission:** public (anonymous via the `PUBLIC_ACCESS` `access_control` entry). This route runs on
the JWT firewall, so a valid bearer + `management=1` enables management mode (`next_available_at` /
`available_on_date` ignore the online-booking toggle) — see the note under `/appointment-slots`.
**Query:** `date` (optional, `Y-m-d`), `management` (optional, `1`).
Lists every place the doctor can be booked at. The site should show **all** of them, grouped by
location — picking one and hiding the rest removes real capacity from the doctor.