# Appointment API > **Prefix:** `/api/v1/appointment*` --- ## GET `/api/v1/appointment-slots` Get available appointment slots for a doctor on a specific date. **Permission:** `PUBLIC` ### 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`) | ### Response `200` ```json { "success": true, "data": { "doctor_uuid": "550e8400-...", "date": "2024-06-15", "slots": [ { "start": 1718438400, "end": 1718439600, "available": true }, { "start": 1718439600, "end": 1718440800, "available": false } ] } } ``` > All times are **Unix timestamps**. Slots are calculated from `WeeklySchedule` minus booked appointments, date overrides, and holidays. ### Errors | Code | HTTP | Description | |------|------|-------------| | `ERR_NOT_FOUND_001` | 404 | Doctor not found | | `ERR_VALIDATION_001` | 422 | Missing or invalid date/doctor_uuid | --- ## POST `/api/v1/appointment` Book an appointment slot. **Permission:** `AUTH` — any authenticated user ### Request Body (`application/json`) ```json { "doctor_uuid": "550e8400-e29b-41d4-a716-446655440000", "slot_start": 1718438400, "slot_end": 1718439600, "note": "لطفاً سریع ویزیت شوم" } ``` | Field | Type | Required | Description | |-------|------|----------|-------------| | `doctor_uuid` | string (UUID) | ✅ | Doctor UUID | | `slot_start` | integer | ✅ | Slot start (Unix timestamp) | | `slot_end` | integer | ✅ | Slot end (Unix timestamp) | | `note` | string | ❌ | Patient note | ### Response `201` ```json { "success": true, "data": { "uuid": "appt-uuid-...", "doctor": { "uuid": "...", "title": "دکتر علی احمدی" }, "user": { "uuid": "...", "real_name": "..." }, "slot_start": 1718438400, "slot_end": 1718439600, "status": "pending", "note": "...", "price": 500000, "created_at": 1717000000 } } ``` **Appointment Status Values:** | Value | Description | |-------|-------------| | `pending` | Awaiting payment | | `confirmed` | Paid and confirmed | | `cancelled` | Cancelled | | `completed` | Visit completed | | `no_show` | Patient did not show | ### Errors | Code | HTTP | Description | |------|------|-------------| | `ERR_AUTH_001` | 401 | Missing token | | `ERR_NOT_FOUND_001` | 404 | Doctor not found | | `ERR_CONFLICT_001` | 409 | Slot already booked | | `ERR_VALIDATION_001` | 422 | Invalid slot times | --- ## GET `/api/v1/appointment/{uuid}` Get appointment detail. **Permission:** `AUTH` — must be the patient, the doctor, or `ROLE_ADMIN` ### Path Parameters | Param | Type | Description | |-------|------|-------------| | `uuid` | string (UUID) | Appointment UUID | ### Response `200` ```json { "success": true, "data": { "uuid": "appt-uuid-...", "doctor": { "uuid": "...", "title": "دکتر علی احمدی", "image": "https://..." }, "user": { "uuid": "...", "real_name": "کاربر", "mobile_number": "09..." }, "slot_start": 1718438400, "slot_end": 1718439600, "status": "confirmed", "note": "...", "price": 500000, "payment_uuid": "pay-uuid-...", "created_at": 1717000000 } } ``` ### Errors | Code | HTTP | Description | |------|------|-------------| | `ERR_AUTH_001` | 401 | Missing token | | `ERR_FORBIDDEN_001` | 403 | Not the patient/doctor/admin | | `ERR_NOT_FOUND_001` | 404 | Appointment not found | --- ## GET `/api/v1/appointments/doctor/{doctorUuid}` Get all appointments for a specific doctor. **Permission:** `AUTH` — must be the doctor, their secretary, or `ROLE_ADMIN` ### Path Parameters | Param | Type | Description | |-------|------|-------------| | `doctorUuid` | string (UUID) | Doctor UUID | ### Query Parameters | Param | Type | Required | Description | |-------|------|----------|-------------| | `status` | string | ❌ | Filter: `pending`, `confirmed`, `cancelled`, `completed`, `no_show` | ### Response `200` ```json { "success": true, "data": [ { "uuid": "...", "user": { "uuid": "...", "real_name": "..." }, "slot_start": 1718438400, "slot_end": 1718439600, "status": "confirmed", "price": 500000 } ] } ``` ### Errors | Code | HTTP | Description | |------|------|-------------| | `ERR_AUTH_001` | 401 | Missing token | | `ERR_FORBIDDEN_001` | 403 | Not authorized to view this doctor's appointments | | `ERR_NOT_FOUND_001` | 404 | Doctor not found | --- ## GET `/api/v1/appointments/user` Get all appointments for the authenticated user. **Permission:** `AUTH` ### Query Parameters | Param | Type | Required | Description | |-------|------|----------|-------------| | `status` | string | ❌ | Filter by status | ### Response `200` ```json { "success": true, "data": [ { "uuid": "...", "doctor": { "uuid": "...", "title": "دکتر علی احمدی" }, "slot_start": 1718438400, "slot_end": 1718439600, "status": "confirmed", "price": 500000 } ] } ``` ### Errors | Code | HTTP | Description | |------|------|-------------| | `ERR_AUTH_001` | 401 | Missing token | --- ## PATCH `/api/v1/appointment/{uuid}/status` Change appointment status. **Permission:** `AUTH` — patient can cancel; doctor/secretary can confirm/complete/no_show; admin can do all ### Path Parameters | Param | Type | Description | |-------|------|-------------| | `uuid` | string (UUID) | Appointment UUID | ### Request Body ```json { "status": "cancelled", "version": 3 } ``` | Field | Type | Required | Description | |-------|------|----------|-------------| | `status` | string | ✅ | New status value | | `version` | integer | ❌ | Optimistic lock version (prevents double-submit) | **Allowed Transitions by Role:** | Actor | Allowed transitions | |-------|---------------------| | Patient | `pending → cancelled` | | Doctor / Secretary | `pending → confirmed`, `confirmed → completed`, `confirmed → no_show` | | Admin | Any transition | ### Response `200` Updated appointment object. ### Errors | Code | HTTP | Description | |------|------|-------------| | `ERR_AUTH_001` | 401 | Missing token | | `ERR_FORBIDDEN_001` | 403 | Not authorized for this transition | | `ERR_NOT_FOUND_001` | 404 | Appointment not found | | `ERR_CONFLICT_001` | 409 | Version mismatch (optimistic lock) | | `ERR_VALIDATION_001` | 422 | Invalid status value |