# Doctor API

> **Prefix:** `/api/v1/doctor`, `/api/v1/doctors`, `/api/v1/clinic-pro/doctor-address*`

---

## POST `/api/v1/doctor`

Create a doctor profile for the authenticated user.

**Permission:** `AUTH` — any authenticated user

### Request Body (`application/json`)
```json
{
  "title": "دکتر علی احمدی",
  "gender": "male",
  "medical_system_code": "12345",
  "degree": "متخصص",
  "info": "توضیحات درباره پزشک",
  "specialties": [1, 2],
  "doctor_services": [3, 4]
}
```

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `title` | string | ✅ | Full name with title |
| `gender` | string | ❌ | `"male"` or `"female"` |
| `medical_system_code` | string | ❌ | Nظام پزشکی code |
| `degree` | string | ❌ | Academic degree |
| `info` | string | ❌ | Bio/description |
| `specialties` | integer[] | ❌ | Array of specialty IDs |
| `doctor_services` | integer[] | ❌ | Array of doctor service IDs |

### Response `201`
```json
{
  "success": true,
  "data": {
    "uuid": "550e8400-e29b-41d4-a716-446655440000",
    "title": "دکتر علی احمدی",
    "gender": "male",
    "medical_system_code": "12345",
    "degree": "متخصص",
    "info": "...",
    "doctor_rate": null,
    "active_doctor_appointment": false,
    "specialties": [],
    "doctor_services": [],
    "created_at": 1717000000
  }
}
```

### Errors
| Code | HTTP | Description |
|------|------|-------------|
| `ERR_AUTH_001` | 401 | Missing or invalid token |
| `ERR_CONFLICT_001` | 409 | Doctor profile already exists for this user |
| `ERR_VALIDATION_002` | 422 | Missing required field |

---

## GET `/api/v1/doctor/{uuid}`

Get doctor detail with clinics.

**Permission:** `PUBLIC`

### Path Parameters
| Param | Type | Description |
|-------|------|-------------|
| `uuid` | string (UUID) | Doctor UUID |

### Response `200`
```json
{
  "success": true,
  "data": {
    "data": {
      "uuid": "550e8400-...",
      "name": "دکتر علی احمدی",
      "gender": "man",
      "medical_system_code": "12345",
      "degree": "specialist",
      "detail": "...",
      "img": [],
      "satisfaction": "60",
      "point": "3.5",
      "free_turn": "دوشنبه 09:00–13:00",
      "hours_of_work": "شنبه: 09:00–13:00 و 14:00–18:00 | یکشنبه: 09:00–13:00",
      "active": true,
      "specialties": [{ "uuid": "...", "id": "1", "name": "قلب و عروق", "parent_id": null }],
      "expertise": [{ "uuid": "...", "id": "3", "name": "نوار قلب" }],
      "address": [],
      "state": [],
      "city": [],
      "clinics": [{ "uuid": "...", "name": "کلینیک الوند", "address": "...", "telephone": "..." }]
    }
  }
}
```

> ⚠️ **Double-nested:** Frontend extracts with `data?.data?.data`

### Errors
| Code | HTTP | Description |
|------|------|-------------|
| `ERR_NOT_FOUND_001` | 404 | Doctor not found |

---

## GET `/api/v1/clinic/my-doctor/{doctorUuid}`

Get doctor detail for clinic owner — only doctors who are members of the authenticated clinic.

**Permission:** `ROLE_CLINIC`

### Path Parameters
| Param | Type | Description |
|-------|------|-------------|
| `doctorUuid` | string (UUID) | Doctor UUID |

### Response `200`
```json
{
  "success": true,
  "data": {
    "data": {
      "uuid": "...",
      "title": "دکتر علی احمدی",
      "specialties": [...],
      "clinics": [{ "uuid": "...", "name": "کلینیک نور", "address": "...", "telephone": "..." }]
    }
  }
}
```

> ⚠️ **Double-nested:** Frontend extracts with `data?.data?.data`

> **Side note:** Returns only the authenticated clinic's data in the `clinics` array (not all clinics of the doctor).

### Errors
| Code | HTTP | Description |
|------|------|-------------|
| `ERR_VALIDATION_002` | 404 | Clinic or doctor not found |
| `ERR_AUTH_006` | 403 | Doctor is not a member of this clinic |

---

### Schedule Fields Notes

| Field | When schedule exists | When no schedule |
|-------|---------------------|-----------------|
| `free_turn` | نزدیک‌ترین روز/ساعت کاری از امروز (مثلاً «دوشنبه ۹:۰۰–۱۳:۰۰») | «نوبت آزادی موجود نیست» |
| `hours_of_work` | خلاصه ساعت‌های روزهای فعال با `\|` جداشده | «برنامه کاری تنظیم نشده» |
| `active` | `activeDoctorAppointment && has_active_sessions` | `false` — نوبت‌دهی غیرفعال |

---

## GET `/api/v1/doctors`

List doctors with pagination and filters.

**Permission:** `PUBLIC`

### Query Parameters
| Param | Type | Required | Description |
|-------|------|----------|-------------|
| `page` | integer | ❌ | Default: 1 |
| `limit` | integer | ❌ | Default: 20 |
| `search` | string | ❌ | Search in title |
| `specialty_id` | integer | ❌ | Filter by specialty |
| `city_id` | integer | ❌ | Filter by city |
| `state_id` | integer | ❌ | Filter by province |

### Response `200`
```json
{
  "success": true,
  "data": [
    {
      "uuid": "...",
      "name": "دکتر علی احمدی",
      "gender": "man",
      "degree": "specialist",
      "img": [],
      "specialties": [{ "uuid": "...", "id": "1", "name": "قلب و عروق" }],
      "satisfaction": "60",
      "point": "3.5",
      "free_turn": "دوشنبه 09:00–13:00",
      "hours_of_work": "شنبه: 09:00–13:00 و 14:00–18:00 | یکشنبه: 09:00–13:00",
      "active": true
    }
  ],
  "meta": {
    "totalRecords": 50,
    "totalPages": 3,
    "currentPage": 1
  }
}
```

---

## PATCH `/api/v1/doctor/{uuid}`

Update doctor profile.

**Permission:** `AUTH` — must be the owner (or `ROLE_ADMIN`)

### Path Parameters
| Param | Type | Description |
|-------|------|-------------|
| `uuid` | string (UUID) | Doctor UUID |

### Request Body (`application/json`)
Same fields as POST — all optional.

### Response `200`
Updated doctor object (same structure as GET single).

### Errors
| Code | HTTP | Description |
|------|------|-------------|
| `ERR_AUTH_001` | 401 | Missing token |
| `ERR_FORBIDDEN_001` | 403 | Not the owner |
| `ERR_NOT_FOUND_001` | 404 | Doctor not found |

---

## DELETE `/api/v1/doctor/{uuid}`

Delete a doctor profile.

**Permission:** `ROLE_ADMIN`

### Path Parameters
| Param | Type | Description |
|-------|------|-------------|
| `uuid` | string (UUID) | Doctor UUID |

### Response `200`
```json
{
  "success": true,
  "data": { "message": "پزشک با موفقیت حذف شد" }
}
```

### Errors
| Code | HTTP | Description |
|------|------|-------------|
| `ERR_AUTH_001` | 401 | Missing token |
| `ERR_AUTH_006` | 403 | Not admin |
| `ERR_NOT_FOUND_001` | 404 | Doctor not found |

---

## POST `/file/upload/clinic_pro/doctor/field_image`

Upload doctor profile image.

**Permission:** `AUTH`

### Request
`Content-Type: multipart/form-data`

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `file` | binary | ✅ | Image file (max 5MB) |

### Response `200`
```json
{
  "success": true,
  "data": {
    "url": "https://clinic-pro.ddev.site/uploads/doctor/abc123.jpg",
    "uuid": "...",
    "filename": "abc123.jpg",
    "filemime": "image/jpeg",
    "filesize": 204800
  }
}
```

### Errors
| Code | HTTP | Description |
|------|------|-------------|
| `ERR_FILE_001` | 422 | Invalid file type |
| `ERR_AUTH_001` | 401 | Missing token |

---

## GET `/api/v1/clinic-pro/doctor-addresses/{doctorId}`

Get all practice addresses for a doctor, including addresses of clinics the doctor is a member of.

**Permission:** `PUBLIC`

### Path Parameters
| Param | Type | Description |
|-------|------|-------------|
| `doctorId` | integer | Doctor's numeric ID |

### Response `200`
```json
{
  "success": true,
  "data": [
    {
      "id": "1",
      "uuid": "...",
      "type": "personal",
      "clinic_id": null,
      "clinic_name": null,
      "name": "مطب تهران",
      "address": "تهران، خیابان...",
      "telephone": "02112345678",
      "map": { "latitude": "35.6892", "longitude": "51.3890" },
      "city": { "id": "1", "name": "تهران" },
      "province": { "id": "1", "name": "تهران" }
    },
    {
      "id": "5",
      "uuid": "...",
      "type": "clinic",
      "clinic_id": 12,
      "clinic_name": "کلینیک الوند",
      "name": null,
      "address": "اصفهان، خیابان...",
      "telephone": "03112345678",
      "map": { "latitude": null, "longitude": null },
      "city": { "id": "3", "name": "اصفهان" },
      "province": { "id": "2", "name": "اصفهان" }
    }
  ]
}
```

> **نکته:** آدرس‌های با `type: "clinic"` از کلینیک‌هایی که پزشک عضو آن‌هاست می‌آیند و `clinic_name` نام کلینیک را نشان می‌دهد.

---

## POST `/api/v1/clinic-pro/doctor-address`

Add a new practice address.

**Permission:** `AUTH` — must own the doctor profile

### Request Body
```json
{
  "name": "مطب تهران",
  "address": "تهران، خیابان ولیعصر",
  "telephone": "02112345678",
  "province_id": 1,
  "city_id": 3,
  "latitude": 35.6892,
  "longitude": 51.3890
}
```

| Field | Type | Required |
|-------|------|----------|
| `name` | string | ❌ |
| `address` | string | ✅ (frontend validation) |
| `telephone` | string | ✅ (frontend validation) |
| `province_id` | integer | ✅ (frontend validation) |
| `city_id` | integer | ✅ (frontend validation) |
| `latitude` | float | ❌ |
| `longitude` | float | ❌ |

### Response `201`
```json
{
  "success": true,
  "data": {
    "id": 1,
    "name": "مطب تهران",
    "address": "تهران، خیابان ولیعصر",
    "telephone": "02112345678",
    "latitude": 35.6892,
    "longitude": 51.3890
  }
}
```

### Errors
| Code | HTTP | Description |
|------|------|-------------|
| `ERR_AUTH_001` | 401 | Missing token |
| `ERR_FORBIDDEN_001` | 403 | Not the doctor owner |
| `ERR_NOT_FOUND_001` | 404 | Doctor not found |

---

## PATCH `/api/v1/clinic-pro/doctor-address/{id}`

Update a practice address.

**Permission:** `AUTH` — must own the doctor profile

### Path Parameters
| Param | Type | Description |
|-------|------|-------------|
| `id` | integer | Address ID |

### Request Body
Same fields as POST — all optional.

### Response `200`
Updated address object.

### Errors
| Code | HTTP | Description |
|------|------|-------------|
| `ERR_AUTH_001` | 401 | Missing token |
| `ERR_FORBIDDEN_001` | 403 | Not the owner |
| `ERR_NOT_FOUND_001` | 404 | Address not found |

---

## DELETE `/api/v1/clinic-pro/doctor-address/{id}`

Delete a practice address.

**Permission:** `AUTH` — must own the doctor profile

### Response `200`
```json
{ "success": true, "data": { "message": "آدرس حذف شد" } }
```

### Errors
| Code | HTTP | Description |
|------|------|-------------|
| `ERR_AUTH_001` | 401 | Missing token |
| `ERR_FORBIDDEN_001` | 403 | Not the owner |
| `ERR_NOT_FOUND_001` | 404 | Address not found |

---

## POST `/api/v1/clinic-pro/doctor-address/from-clinic/{clinicUuid}`

Create a doctor address automatically from a clinic's location.

**Permission:** `AUTH` — must own the doctor profile and be associated with the clinic

### Path Parameters
| Param | Type | Description |
|-------|------|-------------|
| `clinicUuid` | string (UUID) | Clinic UUID |

### Response `201`
Address object created from clinic data.

### Errors
| Code | HTTP | Description |
|------|------|-------------|
| `ERR_FORBIDDEN_001` | 403 | Not associated with this clinic |
| `ERR_NOT_FOUND_001` | 404 | Clinic not found |
