# Secretary API > **Prefix:** `/api/v1/secretary`, `/api/v1/secretaries` ## مدل Scope هر رابطه منشی-پزشک دارای یک **scope** است که از تداخل بین محیط‌های مختلف جلوگیری می‌کند: | Scope | `owner_type` | تعریف‌کننده | دسترسی | |-------|-------------|-------------|---------| | مطب شخصی | `doctor` | خود پزشک | فقط نوبت‌ها و داده‌های مطب شخصی | | کلینیک | `clinic` | مدیر کلینیک | فقط نوبت‌ها و داده‌های کلینیک | - یک منشی می‌تواند هم در مطب شخصی یک دکتر و هم در کلینیک همان دکتر فعال باشد (دو ردیف مجزا) - منشی کلینیک می‌تواند به چند دکتر در همان کلینیک متصل باشد - scope فعال در runtime از جدول `user_active_context` (db_uuid) خوانده می‌شود Secretaries are linked to a doctor and have granular permissions controlling what they can do on behalf of the doctor. --- ## POST `/api/v1/secretary` Create a secretary for a doctor. **Permission:** `ROLE_DOCTOR` (must own the doctor — creates `owner_type='doctor'`) | `ROLE_CLINIC` (must have the doctor in its clinic — creates `owner_type='clinic'`) | `ROLE_ADMIN` ### Request Body (`application/json`) ```json { "doctor_uuid": "550e8400-...", "mobile_number": "09123456789", "password": "secretaryPass123", "permissions": { "version": 1, "resources": { "appointments": { "view": true, "create": true, "cancel": false, "update_status": true }, "addresses": { "view": true, "create": false, "update": false, "delete": false }, "clinic_info": { "view": true, "update": false }, "insurances": { "view": true, "create": false, "update": false, "delete": false } } } } ``` | Field | Type | Required | Description | |-------|------|----------|-------------| | `doctor_uuid` | string (UUID) | ✅ | Doctor to assign secretary to | | `mobile_number` | string | ✅ | Secretary's login mobile | | `password` | string | ❌ | Initial password (auto-generated if omitted) | | `permissions` | object | ❌ | Permission set (see structure below) | **Permissions Structure:** ```json { "version": 1, "resources": { "appointments": { "view": true, // Can view appointments list "create": true, // Can book appointments "cancel": false, // Can cancel appointments "update_status": true // Can mark as completed/no_show }, "addresses": { "view": true, "create": false, "update": false, "delete": false }, "clinic_info": { "view": true, "update": false }, "insurances": { "view": true, "create": false, "update": false, "delete": false } } } ``` ### Response `201` ```json { "success": true, "data": { "uuid": "sec-uuid-...", "user_name": "علی محمدی", "mobile_number": "09123456789", "doctor_name": "دکتر احمد رضایی", "doctor_uuid": "...", "owner_type": "doctor", "clinic_uuid": null, "is_active": true, "permissions": { ... }, "created_at": 1717000000 } } ``` **مقادیر `owner_type`:** | مقدار | معنی | |-------|------| | `doctor` | منشی توسط خود دکتر تعریف شده — فقط مطب شخصی | | `clinic` | منشی توسط مدیر کلینیک تعریف شده — فقط کلینیک | ### Errors | Code | HTTP | Description | |------|------|-------------| | `ERR_AUTH_001` | 401 | Missing token | | `ERR_AUTH_006` | 403 | Not the doctor owner / clinic owner / admin | | `ERR_NOT_FOUND_001` | 404 | Doctor not found | | `ERR_CONFLICT_001` | 409 | Secretary already added for this doctor | | `ERR_SECRETARY_001` | 422 | Plan limit for secretaries reached | --- ## GET `/api/v1/secretary/{uuid}` Get secretary detail. **Permission:** `AUTH` — must be the linked doctor or `ROLE_ADMIN` ### Path Parameters | Param | Type | Description | |-------|------|-------------| | `uuid` | string (UUID) | Secretary UUID | ### Response `200` ```json { "success": true, "data": { "uuid": "...", "mobile_number": "09123456789", "active": true, "permissions": { ... }, "doctor": { "uuid": "...", "title": "دکتر علی احمدی" }, "created_at": 1717000000 } } ``` ### Errors | Code | HTTP | Description | |------|------|-------------| | `ERR_AUTH_001` | 401 | Missing token | | `ERR_FORBIDDEN_001` | 403 | Not authorized | | `ERR_NOT_FOUND_001` | 404 | Secretary not found | --- ## PATCH `/api/v1/secretary/{uuid}` Update secretary active status or permissions. **Permission:** `ROLE_DOCTOR` — must be the linked doctor ### Request Body (`application/json`) ```json { "active": false, "permissions": { "version": 1, "resources": { "appointments": { "view": true, "create": false, "cancel": false, "update_status": false } } } } ``` | Field | Type | Required | Description | |-------|------|----------|-------------| | `active` | boolean | ❌ | Enable/disable secretary | | `permissions` | object | ❌ | New permissions object | ### Response `200` Updated secretary object. ### Errors | Code | HTTP | Description | |------|------|-------------| | `ERR_AUTH_001` | 401 | Missing token | | `ERR_FORBIDDEN_001` | 403 | Not the linked doctor | | `ERR_NOT_FOUND_001` | 404 | Secretary not found | --- ## DELETE `/api/v1/secretary/{uuid}` Delete a secretary. **Permission:** `ROLE_DOCTOR` — must be the linked doctor ### Response `200` ```json { "success": true, "data": { "message": "منشی حذف شد" } } ``` ### Errors | Code | HTTP | Description | |------|------|-------------| | `ERR_AUTH_001` | 401 | Missing token | | `ERR_FORBIDDEN_001` | 403 | Not the linked doctor | | `ERR_NOT_FOUND_001` | 404 | Secretary not found | --- ## GET `/api/v1/secretaries/{doctorUuid}` Get all secretaries for a specific doctor. **Permission:** `ROLE_DOCTOR` (must own doctor) | `ROLE_CLINIC` (must have doctor in clinic) | `ROLE_ADMIN` ### Path Parameters | Param | Type | Description | |-------|------|-------------| | `doctorUuid` | string (UUID) | Doctor UUID | ### Response `200` ```json { "success": true, "data": [ { "uuid": "...", "user_name": "علی محمدی", "mobile_number": "09...", "doctor_name": "دکتر احمد رضایی", "doctor_uuid": "...", "is_active": true, "permissions": { ... }, "created_at": 1717000000 } ] } ``` ### Errors | Code | HTTP | Description | |------|------|-------------| | `ERR_AUTH_001` | 401 | Missing token | | `ERR_FORBIDDEN_001` | 403 | Not authorized | | `ERR_NOT_FOUND_001` | 404 | Doctor not found | --- ## GET `/api/v1/secretaries/clinic/{clinicUuid}` Get all secretaries across **all doctors** of a clinic. **Permission:** `ROLE_CLINIC` (must own clinic) | `ROLE_ADMIN` ### Path Parameters | Param | Type | Description | |-------|------|-------------| | `clinicUuid` | string (UUID) | Clinic UUID | ### Response `200` ```json { "success": true, "data": [ { "uuid": "...", "user_name": "علی محمدی", "mobile_number": "09...", "doctor_name": "دکتر احمد رضایی", "doctor_uuid": "...", "is_active": true, "permissions": { ... }, "created_at": 1717000000 } ] } ``` ### Notes - این endpoint فقط منشیانی را برمی‌گرداند که با `owner_type='clinic'` تعریف شده‌اند - منشیانی که خود دکتر (با `owner_type='doctor'`) تعریف کرده از این لیست مخفی هستند - یک منشی می‌تواند به چند دکتر در همان کلینیک متصل باشد — در لیست چندبار ظاهر می‌شود (یک ردیف به ازای هر دکتر) ### Errors | Code | HTTP | Description | |------|------|-------------| | `ERR_AUTH_001` | 401 | Missing token | | `ERR_FORBIDDEN_001` | 403 | Not clinic owner | | `ERR_NOT_FOUND_001` | 404 | Clinic not found | --- ## محدودیت پنل اشتراکی تعداد منشی‌های مجاز بر اساس پنل فعال doctor تعیین می‌شود: | پنل | حداکثر منشی | |-----|-------------| | Free (بدون اشتراک) | ۱ | | Basic | ۳ | | Professional | ۱۰ | اگر تعداد منشی‌های فعال به حد مجاز رسیده باشد، ایجاد منشی جدید خطای زیر را برمی‌گرداند: ```json { "success": false, "errors": [ { "code": "ERR_SECRETARY_001", "message": "پلن فعلی اجازه منشی بیشتر را نمی‌دهد" } ] } ``` برای افزایش محدودیت، باید پنل را از `POST /api/v1/subscription/trial` (تریال) یا `POST /api/v1/subscription-payment` (پرداخت) ارتقاء داد.