Files
clinicpro/docs/api/clinic.md
T

449 lines
11 KiB
Markdown

# Clinic API
> **Prefix:** `/api/v1/clinic`, `/api/v1/clinics`
---
## POST `/api/v1/clinic`
Create a new clinic.
**Permission:** `AUTH` — any authenticated user becomes the clinic owner
### Request Body (`application/json`)
```json
{
"name": "کلینیک الوند",
"info": "توضیحات کلینیک",
"address": "تهران، خیابان ولیعصر",
"telephone": "02112345678",
"working_days": "شنبه تا چهارشنبه",
"is_24_7": false,
"latitude": 35.6892,
"longitude": 51.3890,
"state": "تهران",
"city": "تهران",
"image_clinic": [
{ "url": "https://..." }
],
"clinic_logo": "https://...",
"doctors": ["uuid1", "uuid2"],
"specialties": [1, 2],
"doctor_services": [3, 4],
"insurance": [5, 6]
}
```
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `name` | string | ✅ | Clinic name |
| `info` | string | ❌ | Description |
| `address` | string | ❌ | Full address |
| `telephone` | string | ❌ | Contact number |
| `working_days` | string | ❌ | Working days description |
| `is_24_7` | boolean | ❌ | Open 24/7 flag |
| `latitude` | float | ❌ | Latitude for map |
| `longitude` | float | ❌ | Longitude for map |
| `state` | string | ❌ | Province name |
| `city` | string | ❌ | City name |
| `image_clinic` | object[] | ❌ | Gallery images `[{url: "..."}]` |
| `clinic_logo` | string | ❌ | Logo URL |
| `doctors` | string[] | ❌ | Doctor UUIDs to associate |
| `specialties` | integer[] | ❌ | Specialty IDs |
| `doctor_services` | integer[] | ❌ | Service IDs |
| `insurance` | integer[] | ❌ | Insurance IDs |
### Response `201`
```json
{
"success": true,
"data": {
"data": {
"uuid": "550e8400-...",
"name": "کلینیک الوند",
"info": "...",
"address": "...",
"telephone": "02112345678",
"working_days": "...",
"is_24_7": false,
"latitude": 35.6892,
"longitude": 51.3890,
"state": "تهران",
"city": "تهران",
"images_clinic": [{ "url": "https://..." }],
"clinic_logo": "https://...",
"is_active": true,
"doctors": [],
"specialties": [],
"doctor_services": [],
"insurance": [],
"tags": [],
"created_at": 1717000000
}
}
}
```
> ⚠️ **Double-nested:** Frontend extracts with `data?.data?.data`
### Errors
| Code | HTTP | Description |
|------|------|-------------|
| `ERR_AUTH_001` | 401 | Missing or invalid token |
---
## GET `/api/v1/clinic/{uuid}`
Get clinic detail.
**Permission:** `PUBLIC`
### Path Parameters
| Param | Type | Description |
|-------|------|-------------|
| `uuid` | string (UUID) | Clinic UUID |
### Response `200`
```json
{
"success": true,
"data": {
"data": {
"id": "233",
"uuid": "550e8400-...",
"name": "کلینیک الوند",
"title": "کلینیک الوند",
"is_active": true,
"phone": "02112345678",
"phone_number": "02112345678",
"logo": "/uploads/clinics/logo/...",
"clinic_logo": "/uploads/clinics/logo/...",
"images_clinic": [{ "url": "/uploads/clinics/gallery/..." }],
"caption": "توضیحات کلینیک",
"list_bime": [],
"specialties": [{ "uuid": "...", "id": "1", "name": "قلب", "parent": null }],
"services": [],
"clinic_specialty": [{ "uuid": "...", "id": "1", "name": "قلب", "parent": null }],
"doctors": 5,
"doctor_list": null,
"city": [{ "uuid": "...", "id": "132", "name": "یزد", "parent": "100" }],
"state": [{ "uuid": "...", "id": "100", "name": "یزد" }],
"location": "یزد، خیابان اصلی، پلاک 101",
"map": { "latitude": "31.868", "longitude": "54.330" },
"24_7": false,
"field_working_days": "شنبه تا پنجشنبه ۸ تا ۱۸"
}
}
}
```
> `city`/`state`/`map` are resolved from the clinic's **address** (`DoctorAddress` linked by `clinic_id`), not from columns on the clinic. Each is an array with a single object (or empty `[]` if the clinic has no address). `doctors` is a **count**; the actual doctor list comes from `GET /api/v1/clinic/doctor-list/{clinicUuid}` (`doctor_list` here is always `null`).
### Errors
| Code | HTTP | Description |
|------|------|-------------|
| `ERR_NOT_FOUND_001` | 404 | Clinic not found |
---
## PATCH `/api/v1/clinic/{uuid}`
Update a clinic.
**Permission:** `AUTH` — must be the clinic owner or `ROLE_ADMIN`
### Path Parameters
| Param | Type | Description |
|-------|------|-------------|
| `uuid` | string (UUID) | Clinic UUID |
### Request Body
Same fields as POST — all optional.
### Response `200`
Updated clinic object (same structure as GET).
### Errors
| Code | HTTP | Description |
|------|------|-------------|
| `ERR_AUTH_001` | 401 | Missing token |
| `ERR_FORBIDDEN_001` | 403 | Not the owner |
| `ERR_NOT_FOUND_001` | 404 | Clinic not found |
---
## GET `/api/v1/clinics`
List clinics with pagination.
**Permission:** `PUBLIC`
### Query Parameters
| Param | Type | Required | Description |
|-------|------|----------|-------------|
| `page` | integer | ❌ | Default: 1 |
| `limit` | integer | ❌ | Default: 20 |
| `name` | string | ❌ | Search by clinic name |
| `city` | integer | ❌ | City id — filters by the **clinic address's** city |
| `state` | integer | ❌ | Province id — filters by the **clinic address's** province |
| `specialty` | integer | ❌ | Specialty id |
> `city`/`state` are matched against the clinic's address (`DoctorAddress` linked by `clinic_id`), not a field on the clinic itself.
### Response `200`
```json
{
"success": true,
"data": [
{
"id": "3426",
"uuid": "...",
"name": "کلینیک الوند",
"title": "کلینیک الوند",
"phone": "02112345678",
"phone_number": "02112345678",
"logo": "/uploads/clinics/logo/...",
"clinic_logo": "/uploads/clinics/logo/...",
"images_clinic": [{ "url": "/uploads/clinics/gallery/..." }],
"doctors_count": 4,
"is_active": true,
"created_at": 1781762386,
"city": "تهران",
"state": "تهران",
"specialties": [{ "uuid": "...", "id": "7", "name": "..." }],
"24_7": false,
"field_working_days": "شنبه تا پنجشنبه ۸ تا ۲۰"
}
],
"meta": {
"totalRecords": 30,
"totalPages": 2,
"currentPage": 1
}
}
```
| Field | Type | Description |
|-------|------|-------------|
| `clinic_logo` / `logo` | string\|null | Logo path (relative `/uploads/...` or absolute URL) |
| `doctors_count` | integer | Number of doctors linked to the clinic |
| `city` | string\|null | City name, resolved from the clinic's address (`DoctorAddress`) |
| `state` | string\|null | Province name, resolved from the clinic's address (`DoctorAddress`) |
| `24_7` | boolean | Open 24/7 flag |
| `field_working_days` | string\|null | Working days/hours description |
---
## GET `/api/v1/clinic/doctor-list/{clinicUuid}`
Get doctors associated with a clinic.
**Permission:** `PUBLIC`
### Path Parameters
| Param | Type | Description |
|-------|------|-------------|
| `clinicUuid` | string (UUID) | Clinic UUID |
### Response `200`
```json
{
"success": true,
"data": [
{
"uuid": "...",
"title": "دکتر علی احمدی",
"degree": "متخصص",
"doctor_rate": 4.5,
"image": "https://..."
}
]
}
```
### Errors
| Code | HTTP | Description |
|------|------|-------------|
| `ERR_NOT_FOUND_001` | 404 | Clinic not found |
---
## POST `/file/upload/clinic_pro/clinic/field_clinic_logo`
Upload clinic logo.
**Permission:** `AUTH`
### Request
`Content-Type: multipart/form-data`
| Field | Type | Required | Max Size |
|-------|------|----------|----------|
| `file` | binary | ✅ | 5MB |
### Response `200`
```json
{
"success": true,
"data": {
"url": "https://clinic-pro.ddev.site/uploads/clinic/logo_abc.jpg",
"uuid": "...",
"filename": "logo_abc.jpg",
"filemime": "image/jpeg",
"filesize": 102400
}
}
```
### Errors
| Code | HTTP | Description |
|------|------|-------------|
| `ERR_FILE_001` | 422 | Invalid file type |
| `ERR_AUTH_001` | 401 | Missing token |
---
## POST `/file/upload/clinic_pro/clinic/field_image_clinic`
Upload clinic gallery image.
**Permission:** `AUTH`
### Request
`Content-Type: multipart/form-data`
| Field | Type | Required | Max Size |
|-------|------|----------|----------|
| `file` | binary | ✅ | 5MB |
### Response `200`
```json
{
"success": true,
"data": {
"url": "https://clinic-pro.ddev.site/uploads/clinic/gallery_abc.jpg",
"uuid": "...",
"filename": "gallery_abc.jpg",
"filemime": "image/jpeg",
"filesize": 307200
}
}
```
> After uploading, use the returned `url` inside `image_clinic: [{ "url": "..." }]` when calling PATCH clinic.
### Errors
| Code | HTTP | Description |
|------|------|-------------|
| `ERR_FILE_001` | 422 | Invalid file type |
| `ERR_AUTH_001` | 401 | Missing token |
---
## Clinic Address Management
### `GET /api/v1/clinic/{clinicUuid}/addresses`
**Permission:** Public
Returns all addresses registered for a clinic (type=clinic entries).
#### Response `200`
```json
{
"success": true,
"data": [
{
"id": "12",
"uuid": "abc-123",
"type": "clinic",
"clinic_id": "5",
"name": "شعبه مرکزی",
"address": "تهران، خیابان ولیعصر...",
"telephone": "02112345678",
"map": { "latitude": "35.699", "longitude": "51.337" },
"city": { "id": "1", "name": "تهران" },
"province": { "id": "8", "name": "تهران" }
}
]
}
```
---
### `POST /api/v1/clinic/{clinicUuid}/address`
**Permission:** Clinic owner or `ROLE_ADMIN`
Creates a new address for the clinic. The address will appear in `available-locations` for doctors belonging to this clinic.
#### Request
```json
{
"name": "شعبه مرکزی",
"address": "تهران، خیابان ولیعصر...",
"telephone": "02112345678",
"latitude": 35.699,
"longitude": 51.337,
"city_id": 123,
"province_id": 7
}
```
| Field | Type | Required |
|-------|------|----------|
| `name` | string | ❌ |
| `address` | string | ❌ |
| `telephone` | string | ❌ |
| `latitude` | float | ❌ |
| `longitude` | float | ❌ |
| `city_id` | integer | ❌ |
| `province_id` | integer | ❌ |
#### Response `201`
```json
{ "success": true, "data": { "id": "12", "uuid": "...", "type": "clinic", ... } }
```
#### Errors
| Code | HTTP | Description |
|------|------|-------------|
| `ERR_AUTH_006` | 403 | Not the clinic owner |
| `ERR_VALIDATION_002` | 404 | Clinic not found |
---
### `PATCH /api/v1/clinic/{clinicUuid}/address/{addressUuid}`
**Permission:** Clinic owner or `ROLE_ADMIN`
Updates an existing clinic address. Same body fields as POST (all optional).
#### Response `200`
```json
{ "success": true, "data": { ... } }
```
---
### `DELETE /api/v1/clinic/{clinicUuid}/address/{addressUuid}`
**Permission:** Clinic owner or `ROLE_ADMIN`
Deletes a clinic address.
> A clinic must retain at least one address — attempting to delete the last address returns `409`.
#### Errors
| Code | HTTP | Description |
|------|------|-------------|
| `ERR_CONFLICT_001` | 409 | Cannot delete the last address |
| `ERR_VALIDATION_002` | 404 | Address or clinic not found |
| `ERR_AUTH_006` | 403 | Not the clinic owner |
---
### Removed endpoint
`POST /api/v1/clinic-pro/doctor-address/from-clinic/{clinicUuid}`**removed**. Use clinic address management endpoints instead.