Add API documentation for Representation, Secretary, Settlement, SMS, Specialty, Tag, and User Profile endpoints
This commit is contained in:
@@ -0,0 +1,312 @@
|
||||
# Clinic Doctor Invitation API
|
||||
|
||||
> **Prefix:** `/api/v1/admin/clinic/...` (admin) and `/api/v1/clinic-invitation/...` (public)
|
||||
|
||||
Admins invite doctors to clinics via SMS. The doctor receives a secure 96-char token link valid for 72 hours.
|
||||
|
||||
---
|
||||
|
||||
## POST `/api/v1/admin/clinic/{uuid}/invite-doctor`
|
||||
|
||||
Send an invitation to a doctor (by mobile number) to join a clinic.
|
||||
|
||||
**Permission:** `ROLE_ADMIN`
|
||||
|
||||
### Path Parameters
|
||||
| Param | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `uuid` | string (UUID) | Clinic UUID |
|
||||
|
||||
### Request Body (`application/json`)
|
||||
```json
|
||||
{
|
||||
"mobile": "09123456789",
|
||||
"name": "دکتر علی احمدی",
|
||||
"specialty": "قلب و عروق"
|
||||
}
|
||||
```
|
||||
|
||||
| Field | Type | Required | Validation |
|
||||
|-------|------|----------|------------|
|
||||
| `mobile` | string | ✅ | Format: `09XXXXXXXXX` |
|
||||
| `name` | string | ❌ | Doctor's display name |
|
||||
| `specialty` | string | ❌ | Specialty label for SMS |
|
||||
|
||||
### Response `201`
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"uuid": "inv-uuid-...",
|
||||
"mobile": "09123456789",
|
||||
"invited_name": "دکتر علی احمدی",
|
||||
"invited_specialty": "قلب و عروق",
|
||||
"status": "pending",
|
||||
"invited_at": 1717000000,
|
||||
"expires_at": 1717259200,
|
||||
"token_used": false,
|
||||
"clinic": { "uuid": "...", "name": "کلینیک الوند" }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> SMS is dispatched **asynchronously** via Symfony Messenger → Redis queue.
|
||||
> SMS text: `"دکتر گرامی، کلینیک {name} شما را برای همکاری دعوت کرده است.\nبرای بررسی: {link}\nاین لینک تا ۷۲ ساعت معتبر است."`
|
||||
|
||||
### Errors
|
||||
| Code | HTTP | Description |
|
||||
|------|------|-------------|
|
||||
| `ERR_AUTH_001` | 401 | Missing or invalid token |
|
||||
| `ERR_AUTH_006` | 403 | Not admin |
|
||||
| `ERR_NOT_FOUND_001` | 404 | Clinic not found |
|
||||
| `ERR_VALIDATION_001` | 422 | Invalid mobile format |
|
||||
|
||||
---
|
||||
|
||||
## GET `/api/v1/admin/clinic/{uuid}/invitations`
|
||||
|
||||
List all invitations for a clinic.
|
||||
|
||||
**Permission:** `ROLE_ADMIN`
|
||||
|
||||
### Path Parameters
|
||||
| Param | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `uuid` | string (UUID) | Clinic UUID |
|
||||
|
||||
### Query Parameters
|
||||
| Param | Type | Required | Default |
|
||||
|-------|------|----------|---------|
|
||||
| `page` | integer | ❌ | 1 |
|
||||
| `limit` | integer | ❌ | 50 |
|
||||
|
||||
### Response `200`
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": [
|
||||
{
|
||||
"uuid": "...",
|
||||
"mobile": "09123456789",
|
||||
"invited_name": "دکتر علی احمدی",
|
||||
"invited_specialty": "قلب و عروق",
|
||||
"status": "pending",
|
||||
"invited_at": 1717000000,
|
||||
"expires_at": 1717259200,
|
||||
"responded_at": null,
|
||||
"token_used": false,
|
||||
"doctor": null
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"totalRecords": 5,
|
||||
"totalPages": 1,
|
||||
"currentPage": 1
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Invitation Status Values:**
|
||||
| Value | Description |
|
||||
|-------|-------------|
|
||||
| `pending` | Sent, awaiting response |
|
||||
| `accepted` | Doctor accepted |
|
||||
| `rejected` | Doctor rejected |
|
||||
| `suspended` | Suspended by admin |
|
||||
| `removed` | Removed |
|
||||
|
||||
### Errors
|
||||
| Code | HTTP | Description |
|
||||
|------|------|-------------|
|
||||
| `ERR_AUTH_001` | 401 | Missing token |
|
||||
| `ERR_AUTH_006` | 403 | Not admin |
|
||||
| `ERR_NOT_FOUND_001` | 404 | Clinic not found |
|
||||
|
||||
---
|
||||
|
||||
## POST `/api/v1/admin/clinic/invitation/{invUuid}/resend`
|
||||
|
||||
Resend the invitation SMS with a fresh token and reset expiry to +72 hours.
|
||||
|
||||
**Permission:** `ROLE_ADMIN`
|
||||
|
||||
### Path Parameters
|
||||
| Param | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `invUuid` | string (UUID) | Invitation 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 | Invitation not found |
|
||||
|
||||
---
|
||||
|
||||
## PATCH `/api/v1/admin/clinic/invitation/{invUuid}/status`
|
||||
|
||||
Change the status of an invitation (e.g., suspend or remove).
|
||||
|
||||
**Permission:** `ROLE_ADMIN`
|
||||
|
||||
### Path Parameters
|
||||
| Param | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `invUuid` | string (UUID) | Invitation UUID |
|
||||
|
||||
### Request Body
|
||||
```json
|
||||
{
|
||||
"status": "suspended"
|
||||
}
|
||||
```
|
||||
|
||||
| Field | Type | Required | Allowed Values |
|
||||
|-------|------|----------|----------------|
|
||||
| `status` | string | ✅ | `pending`, `suspended`, `removed` |
|
||||
|
||||
### Response `200`
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": { "status": "suspended" }
|
||||
}
|
||||
```
|
||||
|
||||
### Errors
|
||||
| Code | HTTP | Description |
|
||||
|------|------|-------------|
|
||||
| `ERR_AUTH_001` | 401 | Missing token |
|
||||
| `ERR_AUTH_006` | 403 | Not admin |
|
||||
| `ERR_NOT_FOUND_001` | 404 | Invitation not found |
|
||||
| `ERR_VALIDATION_001` | 422 | Invalid status value |
|
||||
|
||||
---
|
||||
|
||||
## DELETE `/api/v1/admin/clinic/invitation/{invUuid}`
|
||||
|
||||
Delete an invitation.
|
||||
|
||||
**Permission:** `ROLE_ADMIN`
|
||||
|
||||
### Path Parameters
|
||||
| Param | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `invUuid` | string (UUID) | Invitation UUID |
|
||||
|
||||
### Response `204`
|
||||
Empty body.
|
||||
|
||||
### Errors
|
||||
| Code | HTTP | Description |
|
||||
|------|------|-------------|
|
||||
| `ERR_AUTH_001` | 401 | Missing token |
|
||||
| `ERR_AUTH_006` | 403 | Not admin |
|
||||
| `ERR_NOT_FOUND_001` | 404 | Invitation not found |
|
||||
|
||||
---
|
||||
|
||||
## GET `/api/v1/clinic-invitation/{token}`
|
||||
|
||||
View invitation details by token (used on the doctor-facing landing page).
|
||||
|
||||
**Permission:** `PUBLIC`
|
||||
|
||||
### Path Parameters
|
||||
| Param | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `token` | string | 96-char hex token from SMS link |
|
||||
|
||||
### Response `200`
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"invitation": {
|
||||
"uuid": "...",
|
||||
"mobile": "09123456789",
|
||||
"invited_name": "دکتر علی احمدی",
|
||||
"invited_specialty": "قلب و عروق",
|
||||
"status": "pending",
|
||||
"expires_at": 1717259200
|
||||
},
|
||||
"clinic": {
|
||||
"uuid": "...",
|
||||
"name": "کلینیک الوند",
|
||||
"city": "تهران",
|
||||
"clinic_logo": "https://..."
|
||||
},
|
||||
"is_usable": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> `is_usable: false` when: token already used, expired, or status is not `pending`
|
||||
|
||||
### Errors
|
||||
| Code | HTTP | Description |
|
||||
|------|------|-------------|
|
||||
| `ERR_NOT_FOUND_001` | 404 | Token not found |
|
||||
|
||||
---
|
||||
|
||||
## POST `/api/v1/clinic-invitation/{token}/accept`
|
||||
|
||||
Doctor accepts the invitation. If a doctor profile exists for this mobile, they are automatically linked to the clinic.
|
||||
|
||||
**Permission:** `PUBLIC`
|
||||
|
||||
### Path Parameters
|
||||
| Param | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `token` | string | 96-char hex token |
|
||||
|
||||
### Response `200`
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": { "message": "دعوتنامه پذیرفته شد" }
|
||||
}
|
||||
```
|
||||
|
||||
### Errors
|
||||
| Code | HTTP | Description |
|
||||
|------|------|-------------|
|
||||
| `ERR_NOT_FOUND_001` | 404 | Token not found |
|
||||
| `ERR_VALIDATION_001` | 422 | Token expired or already used |
|
||||
|
||||
---
|
||||
|
||||
## POST `/api/v1/clinic-invitation/{token}/reject`
|
||||
|
||||
Doctor rejects the invitation.
|
||||
|
||||
**Permission:** `PUBLIC`
|
||||
|
||||
### Path Parameters
|
||||
| Param | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `token` | string | 96-char hex token |
|
||||
|
||||
### Response `200`
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": { "message": "دعوتنامه رد شد" }
|
||||
}
|
||||
```
|
||||
|
||||
### Errors
|
||||
| Code | HTTP | Description |
|
||||
|------|------|-------------|
|
||||
| `ERR_NOT_FOUND_001` | 404 | Token not found |
|
||||
| `ERR_VALIDATION_001` | 422 | Token expired or already used |
|
||||
Reference in New Issue
Block a user