Files
clinicpro/docs/api/user-profile.md
T

181 lines
5.6 KiB
Markdown

# User Profile API
> **Prefix:** `/api/v1/user-profile`
User medical profiles store health information that can be shared with doctors.
---
## POST `/api/v1/user-profile`
Create a medical profile for the authenticated user.
**Permission:** `AUTH`
### Request Body (`application/json`)
```json
{
"name": "علی",
"family": "احمدی",
"fathers_name": "محمد",
"national_code": "0012345678",
"gender": "male",
"blood_type": "A+",
"marital_status": "married",
"education": "لیسانس",
"job": "مهندس",
"address": "تهران، خیابان ولیعصر",
"home_phone": "02112345678",
"work_phone": "02198765432",
"insurance_id": 1,
"description": "توضیحات بیشتر",
"sharing_with_user": true,
"birthday": "1370-06-15",
"date_of_birth": 648172800,
"basic_insurance": "بیمه تأمین اجتماعی",
"supplementary_insurance": "بیمه ایران",
"other": {}
}
```
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `name` | string | ❌ | First name |
| `family` | string | ❌ | Last name |
| `fathers_name` | string | ❌ | Father's name |
| `national_code` | string | ❌ | National ID (10 digits) |
| `gender` | string | ❌ | `"male"` or `"female"` |
| `blood_type` | string | ❌ | `"A+"`, `"A-"`, `"B+"`, `"B-"`, `"AB+"`, `"AB-"`, `"O+"`, `"O-"` |
| `marital_status` | string | ❌ | `"single"` or `"married"` |
| `education` | string | ❌ | Education level |
| `job` | string | ❌ | Occupation |
| `address` | string | ❌ | Home address |
| `home_phone` | string | ❌ | Home phone number |
| `work_phone` | string | ❌ | Work phone number |
| `insurance_id` | integer | ❌ | Insurance ID |
| `description` | string | ❌ | Additional notes |
| `sharing_with_user` | boolean | ❌ | Allow doctors to view this profile |
| `birthday` | string | ❌ | Birthday in Jalali format `YYYY-MM-DD` |
| `date_of_birth` | integer | ❌ | Birthday as Unix timestamp |
| `basic_insurance` | string | ❌ | Basic insurance name |
| `supplementary_insurance` | string | ❌ | Supplementary insurance name |
| `other` | object | ❌ | Extra metadata |
### Response `201`
```json
{
"success": true,
"data": {
"uuid": "profile-uuid-...",
"name": "علی",
"family": "احمدی",
"gender": "male",
"blood_type": "A+",
"national_code": "0012345678",
"sharing_with_user": true,
"created_at": 1717000000
}
}
```
### Errors
| Code | HTTP | Description |
|------|------|-------------|
| `ERR_AUTH_001` | 401 | Missing token |
| `ERR_CONFLICT_001` | 409 | Profile already exists for this user |
---
## GET `/api/v1/user-profile/{uuid}`
Get a user profile.
**Permission:** `AUTH` — must be the profile owner, or a doctor if `sharing_with_user: true`, or `ROLE_ADMIN`
### Path Parameters
| Param | Type | Description |
|-------|------|-------------|
| `uuid` | string (UUID) | **Profile UUID or the owning User UUID** — both are accepted |
> **Auto-resolve & lazy-create:** `{uuid}` is first looked up as a profile uuid, then as a user uuid. If it is the **current user's own** uuid and they have **no profile yet**, an empty profile is created and returned (HTTP 200) — so a freshly registered user always gets an editable profile instead of a 404. An **admin** reading **another** user's missing profile gets `404` (no profile is created as a side effect of reading). The response includes both the profile `uuid` and `user_uuid`; keep the profile `uuid` for subsequent PATCHes.
### Response `200`
Full profile object including all fields (all `null` for a newly created empty profile). Response is double-nested: extract with `data.data`.
### Errors
| Code | HTTP | Description |
|------|------|-------------|
| `ERR_AUTH_001` | 401 | Missing token |
| `ERR_FORBIDDEN_001` | 403 | Not authorized to view this profile |
| `ERR_VALIDATION_002` | 404 | No profile or user matches the uuid |
---
## PATCH `/api/v1/user-profile/{uuid}`
Update a user profile.
**Permission:** `AUTH` — must be the profile owner
### Path Parameters
| Param | Type | Description |
|-------|------|-------------|
| `uuid` | string (UUID) | **Profile UUID or the owning User UUID** — both accepted; the profile is created if the current user has none yet |
### Request Body
Same fields as POST — all optional.
### Response `200`
Updated profile object.
### Errors
| Code | HTTP | Description |
|------|------|-------------|
| `ERR_AUTH_001` | 401 | Missing token |
| `ERR_FORBIDDEN_001` | 403 | Not the profile owner |
| `ERR_NOT_FOUND_001` | 404 | Profile not found |
---
## DELETE `/api/v1/user-profile/{uuid}`
Delete a user profile.
**Permission:** `ROLE_ADMIN`
### 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 | Profile not found |
---
## POST `/api/v1/user-profile/avatar`
Upload the current user's profile avatar. Creates the profile if it doesn't exist yet.
**Permission:** `IS_AUTHENTICATED_FULLY`
### Request
Raw file body with `Content-Disposition: filename="..."` and `Content-Type: application/octet-stream`.
### Response `200`
```json
{ "success": true, "data": { "avatar": "/uploads/avatars/2026-06/xxx.jpg", "url": "/uploads/avatars/2026-06/xxx.jpg" } }
```
The stored path is also returned as `avatar` in the profile GET/PATCH responses.
### Errors
| Code | HTTP | Description |
|------|------|-------------|
| `ERR_VALIDATION_001` | 422 | Missing or invalid file |
| `ERR_AUTH_001` | 401 | Missing token |