- Updated authStore to include 'representation' role. - Modified DoctorFormPage and DoctorsPage to handle different endpoints based on user role. - Created new RepresentationActionController for handling doctor and clinic creation by representatives. - Added new API endpoints for representatives to manage doctors, clinics, and view appointments. - Updated documentation to reflect new role and API changes.
9.1 KiB
Representation (Agent) API
Prefix:
/api/v1/representation
Representations are sales agents who earn commission on appointments booked through their referral.
POST /api/v1/representation
Create a new representation.
Permission: ROLE_ADMIN
Request Body (application/json)
{
"full_name": "علی احمدی",
"mobile_number": "09123456789",
"city_id": 42,
"commission_percent": 10,
"bank_account": {
"iban": "IR...",
"account_number": "1234567890",
"bank_name": "بانک ملت",
"owner_name": "علی احمدی"
}
}
| Field | Type | Required | Description |
|---|---|---|---|
full_name |
string | ✅ | Agent full name |
mobile_number |
string | ✅ | Login mobile (creates a User account) |
city_id |
integer | ❌ | City ID (FK to categories where bundle=city) |
commission_percent |
float | ❌ | Commission rate (0–100) |
bank_account |
object | ❌ | Bank details for settlements |
Response 201
{
"success": true,
"data": {
"uuid": "rep-uuid-...",
"full_name": "علی احمدی",
"mobile_number": "09123456789",
"city_id": 42,
"commission_percent": 10,
"active": true,
"bank_account": { ... },
"created_at": 1717000000
}
}
Errors
| Code | HTTP | Description |
|---|---|---|
ERR_AUTH_001 |
401 | Missing token |
ERR_AUTH_006 |
403 | Not admin |
ERR_CONFLICT_001 |
409 | Mobile number already in use |
ERR_VALIDATION_001 |
422 | Invalid input |
GET /api/v1/representation/{uuid}
Get representation detail.
Permission: AUTH — must be the representation's user or ROLE_ADMIN
Path Parameters
| Param | Type | Description |
|---|---|---|
uuid |
string (UUID) | Representation UUID |
Response 200
{
"success": true,
"data": {
"uuid": "...",
"full_name": "علی احمدی",
"mobile_number": "09123456789",
"city_id": 42,
"city_name": "تهران",
"commission_percent": 10,
"active": true,
"bank_account": { ... },
"created_at": 1717000000
}
}
Errors
| Code | HTTP | Description |
|---|---|---|
ERR_AUTH_001 |
401 | Missing token |
ERR_FORBIDDEN_001 |
403 | Not owner or admin |
ERR_NOT_FOUND_001 |
404 | Representation not found |
PATCH /api/v1/representation/{uuid}
Update representation.
Permission: AUTH — must be the representation's user or ROLE_ADMIN
Request Body (application/json)
{
"full_name": "علی احمدی جدید",
"city_id": 50,
"commission_percent": 12,
"bank_account": { ... },
"active": true
}
All fields optional.
Response 200
Updated representation object.
Errors
| Code | HTTP | Description |
|---|---|---|
ERR_AUTH_001 |
401 | Missing token |
ERR_FORBIDDEN_001 |
403 | Not owner or admin |
ERR_NOT_FOUND_001 |
404 | Representation not found |
DELETE /api/v1/representation/{uuid}
Delete a representation.
Permission: ROLE_ADMIN
Response 200
{ "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 | Representation not found |
GET /api/v1/representation/{uuid}/dashboard/monthly
Get monthly earnings dashboard for a representation.
Permission: AUTH — must be the representation's user or ROLE_ADMIN
Path Parameters
| Param | Type | Description |
|---|---|---|
uuid |
string (UUID) | Representation UUID |
Query Parameters
| Param | Type | Required | Description |
|---|---|---|---|
year |
integer | ✅ | e.g. 2024 |
month |
integer | ✅ | 1–12 |
Response 200
{
"success": true,
"data": {
"period": { "year": 2024, "month": 6 },
"stats": {
"total_appointments": 15,
"total_revenue_rials": 7500000,
"commission_rials": 750000,
"daily": [
{ "date": "2024-06-01", "appointments": 2, "revenue": 1000000, "commission": 100000 }
]
}
}
}
Errors
| Code | HTTP | Description |
|---|---|---|
ERR_AUTH_001 |
401 | Missing token |
ERR_FORBIDDEN_001 |
403 | Not owner or admin |
ERR_NOT_FOUND_001 |
404 | Representation not found |
GET /api/v1/representation/{uuid}/dashboard/yearly
Get yearly earnings dashboard for a representation.
Permission: AUTH — must be the representation's user or ROLE_ADMIN
Query Parameters
| Param | Type | Required | Description |
|---|---|---|---|
year |
integer | ✅ | e.g. 2024 |
Response 200
{
"success": true,
"data": {
"period": { "year": 2024 },
"months": [
{ "month": 1, "appointments": 10, "revenue_rials": 5000000, "commission_rials": 500000 },
{ "month": 2, "appointments": 8, "revenue_rials": 4000000, "commission_rials": 400000 }
],
"totals": {
"appointments": 97,
"revenue_rials": 48500000,
"commission_rials": 4850000
}
}
}
پنل نماینده (ROLE_REPRESENTATION)
این endpointها برای کاربرِ دارای نقش ROLE_REPRESENTATION در پنل ادمین (/admin) هستند. مالکیت همیشه از کاربر جاری (#[CurrentUser] + findByUser) تعیین میشود؛ هیچ uuid/id ورودی برای تعیین مالکیت پذیرفته نمیشود.
Permission (همهی این بخش):
ROLE_REPRESENTATION
GET /api/v1/representation/me
پروفایل نمایندهی کاربر جاری.
Response 200
{
"success": true,
"data": {
"data": {
"uuid": "...",
"full_name": "حامد حسینی",
"mobile_number": "09120671756",
"city_id": 132,
"commission_percent": "10.00",
"bank_account": null,
"active": true,
"created_at": 1718000000
}
}
}
double-nested: مقدار با
data.dataاستخراج میشود.
Errors
| Code | HTTP | Description |
|---|---|---|
ERR_NOT_FOUND_001 |
404 | کاربر جاری نماینده نیست |
POST /api/v1/representation/doctor
افزودن پزشک توسط نماینده. representation_id پزشک بهصورت خودکار روی نمایندهی کاربر جاری ست میشود.
Request Body
{ "mobile": "0935...", "name": "دکتر ...", "gender": "man", "degree": "...", "medical_system_code": "...", "specialties": [1,2] }
| Field | Type | Required |
|---|---|---|
mobile |
string | ✅ |
name |
string | ✅ |
gender / degree / medical_system_code / info |
string | ❌ |
specialties |
integer[] | ❌ |
Response 201
{ "success": true, "data": { "uuid": "..." } }
Errors
| Code | HTTP | Description |
|---|---|---|
ERR_VALIDATION_002 |
422 | موبایل یا نام خالی |
ERR_CONFLICT_001 |
409 | این کاربر قبلاً پزشک است |
POST /api/v1/representation/clinic
افزودن کلینیک توسط نماینده.
Request Body
{ "owner_mobile": "0935...", "name": "کلینیک ...", "telephone": "...", "address": "..." }
| Field | Type | Required |
|---|---|---|
owner_mobile |
string | ✅ |
name |
string | ✅ |
telephone / address / info |
string | ❌ |
Response 200
{ "success": true, "data": { "uuid": "...", "name": "...", "is_active": true } }
Errors
| Code | HTTP | Description |
|---|---|---|
ERR_VALIDATION_002 |
422 | موبایل یا نام خالی |
GET /api/v1/representation/appointments
نوبتهای همهی پزشکانی که representation_id آنها = نمایندهی کاربر جاری است (paginated، با شکل آیتمِ یکسان با /api/v1/admin/appointments).
Query Parameters
| Param | Type | Required | Description |
|---|---|---|---|
page |
integer | ❌ | پیشفرض 1 |
limit |
integer | ❌ | پیشفرض 15، حداکثر 500 |
status |
string | ❌ | فیلتر وضعیت |
date |
string (YYYY-MM-DD) | ❌ | فیلتر تاریخِ نوبت |
search |
string | ❌ | جستجو در موبایل/نام بیمار یا نام پزشک |
Response 200
{
"success": true,
"data": [
{
"uuid": "...",
"patient_name": "...",
"patient_mobile": "0912...",
"doctor_uuid": "...",
"doctor_name": "دکتر ...",
"slot_start": 1718000000,
"slot_end": 1718001800,
"appointment_date": "2025-06-15",
"appointment_time": "10:00",
"end_time": "10:30",
"status": "confirmed",
"created_at": 1717900000
}
],
"meta": { "totalRecords": 12, "totalPages": 1, "currentPage": 1 }
}
Errors
| Code | HTTP | Description |
|---|---|---|
ERR_NOT_FOUND_001 |
404 | کاربر جاری نماینده نیست |