# Staff API مدیریت پرسنل مطب/کلینیک (بدون حذف — فقط toggle فعال/غیرفعال). **هر پرسنل حساب کاربری ورود دارد.** هنگام ایجاد/ویرایش، یک `User` با نقش `ROLE_STAFF` ساخته (یا کاربر موجودِ همان موبایل استفاده) و به ردیف پرسنل وصل می‌شود؛ بنابراین `phone` اجباری و معتبر (`^09\d{9}$`) است و همان **نام‌کاربری ورود** است. تغییر `phone` یعنی تغییر نام‌کاربری. چنین کاربری در `/admin` وارد می‌شود، ولی دسترسی‌اش به `GET /api/v1/dashboard/staff` و چند مسیر حساب کاربری محدود است (بقیهٔ `/api/v1/*` برای او ۴۰۳ است — رجوع به [dashboard.md](dashboard.md) و [auth.md](auth.md)). قطع دسترسی با `PATCH /api/v1/staff/{uuid}/toggle` انجام می‌شود، نه با حذف حساب. > ردیف‌های پرسنلِ ساخته‌شده پیش از این تغییر ممکن است `has_account: false` باشند؛ با اولین > ویرایش (که `phone` معتبر می‌خواهد) صاحب حساب می‌شوند. --- ## GET /api/v1/staff دریافت لیست پرسنل entity جاری (از JWT). **Permission:** `IS_AUTHENTICATED_FULLY` (ROLE_DOCTOR یا ROLE_CLINIC) **Response 200:** ```json { "success": true, "data": [ { "uuid": "a1b2c3d4-...", "entity_type": "clinic", "entity_id": 5, "full_name": "علی محمدی", "phone": "09121234567", "job_title": "منشی", "address": null, "national_code": "0012345678", "active": true, "has_account": false, "user_uuid": null, "created_at": 1718000000, "updated_at": 1718000000 } ] } ``` | فیلد | نوع | توضیح | |------|-----|-------| | has_account | bool | حساب ورود دارد یا نه — برای ردیف‌های جدید همیشه `true`؛ `false` فقط در ردیف‌های قدیمیِ پیش از این قابلیت | | user_uuid | string\|null | uuid کاربرِ متصل؛ `null` یعنی حساب ندارد | --- ## POST /api/v1/staff ایجاد پرسنل جدید. **Permission:** `IS_AUTHENTICATED_FULLY` (ROLE_DOCTOR یا ROLE_CLINIC) **Request Body:** ```json { "full_name": "محمد رحیمی", "phone": "09121110002", "job_title": "پرستار", "address": "تهران، خیابان ولیعصر", "national_code": "0012345678", "password": "Staff@1234" } ``` | فیلد | نوع | الزامی | |------|-----|--------| | full_name | string | ✅ | | phone | string — `^09\d{9}$`، ارقام فارسی به لاتین تبدیل می‌شوند | ✅ نام‌کاربری ورود | | job_title | string | ❌ | | address | string | ❌ | | national_code | string(15) — ارقام فارسی به لاتین تبدیل می‌شوند | ❌ | | password | string | ❌ — رمز ورود؛ خالی بگذارید تا کاربر با «فراموشی رمز» تعیینش کند. روی کاربر موجود، رمز فعلی پاک نمی‌شود | اگر موبایل قبلاً `User` داشته باشد، کاربر جدید ساخته نمی‌شود؛ فقط `ROLE_STAFF` به نقش‌هایش اضافه و به این ردیف پرسنل وصل می‌شود. **Response 201** (خروجی واقعی): ```json { "success": true, "data": { "uuid": "d64826bc-5e5d-4df6-83bb-3ddc70a99636", "entity_type": "doctor", "entity_id": 1, "full_name": "محمد رحیمی", "phone": "09121110002", "job_title": "پرستار", "address": null, "national_code": null, "active": true, "has_account": true, "user_uuid": "4d79b9b0-f330-4dea-9f02-e38fc716b115", "created_at": 1785393740, "updated_at": 1785393740 } } ``` **Errors:** | Code | HTTP | توضیح | |------|------|-------| | ERR_VALIDATION_001 | 422 | full_name خالی است | | ERR_STAFF_MOBILE_INVALID | 422 | شماره خالی/نامعتبر است یا شمارهٔ خودِ مالک محیط است (`field: "phone"`) | | ERR_STAFF_MOBILE_TAKEN | 409 | در همین محیط، پرسنل دیگری با این شماره ثبت شده است (`field: "phone"`) | | ERR_FORBIDDEN_001 | 403 | پروفایل doctor/clinic یافت نشد | خروجی واقعی خطاها: ```json {"success":false,"data":null,"errors":[{"code":"ERR_STAFF_MOBILE_INVALID","message":"شماره موبایل پرسنل معتبر نیست","field":"phone"}]} {"success":false,"data":null,"errors":[{"code":"ERR_STAFF_MOBILE_TAKEN","message":"برای این شماره قبلاً پرسنلی ثبت شده است","field":"phone"}]} ``` --- ## PATCH /api/v1/staff/{uuid} ویرایش اطلاعات پرسنل. **Permission:** `IS_AUTHENTICATED_FULLY` — فقط owner یا ROLE_ADMIN **Request Body (همه فیلدها اختیاری):** ```json { "full_name": "علی محمدی ویرایش‌شده", "phone": "09129999999", "job_title": "منشی ارشد", "address": null, "national_code": null, "password": "NewPass@123" } ``` ویرایش هم حساب را می‌سازد/به‌روز می‌کند: اگر `phone` ارسال نشود، شمارهٔ فعلی همان ردیف استفاده می‌شود؛ اگر شمارهٔ جدید بیاید، نام‌کاربری ورود عوض می‌شود. `password` خالی رمز فعلی را پاک نمی‌کند. **Response 200:** همان ساختار staff object **Errors:** | Code | HTTP | توضیح | |------|------|-------| | ERR_STAFF_NOT_FOUND | 404 | پرسنل یافت نشد | | ERR_STAFF_MOBILE_INVALID | 422 | شمارهٔ نامعتبر یا شمارهٔ مالک محیط | | ERR_STAFF_MOBILE_TAKEN | 409 | شماره در همین محیط قبلاً ثبت شده | | ERR_FORBIDDEN_001 | 403 | دسترسی ندارید | --- ## PATCH /api/v1/staff/{uuid}/toggle تغییر وضعیت فعال/غیرفعال پرسنل (soft toggle — هیچ حذفی انجام نمی‌شود). **Permission:** `IS_AUTHENTICATED_FULLY` — فقط owner یا ROLE_ADMIN **Response 200:** ```json { "success": true, "data": { "uuid": "a1b2c3d4-...", "active": false, ... } } ``` **Errors:** | Code | HTTP | توضیح | |------|------|-------| | ERR_STAFF_NOT_FOUND | 404 | پرسنل یافت نشد | | ERR_FORBIDDEN_001 | 403 | دسترسی ندارید |