- Implemented SidebarStaff component tests to ensure staff users see only their dashboard and services. - Created StaffMyServicesPage to display assigned services for staff users. - Added migration to link clinic staff rows to user accounts for ROLE_STAFF access. - Defined StaffPermissions class for static permissions related to staff role. - Introduced StaffRouteGuardSubscriber to restrict API access for staff users. - Developed StaffAccountService for managing staff user accounts and linking them to clinic staff. - Added comprehensive tests for StaffAccountService to validate user creation, mobile number handling, and account attachment. - Implemented tests for staff dashboard access to ensure proper permissions and access control. - Created tests for staff login context to verify correct environment visibility based on user roles.
6.4 KiB
Staff API
مدیریت پرسنل مطب/کلینیک (بدون حذف — فقط toggle فعال/غیرفعال).
هر پرسنل حساب کاربری ورود دارد. هنگام ایجاد/ویرایش، یک User با نقش ROLE_STAFF ساخته
(یا کاربر موجودِ همان موبایل استفاده) و به ردیف پرسنل وصل میشود؛ بنابراین phone اجباری و
معتبر (^09\d{9}$) است و همان نامکاربری ورود است. تغییر phone یعنی تغییر نامکاربری.
چنین کاربری در /admin وارد میشود، ولی دسترسیاش به GET /api/v1/dashboard/staff و چند
مسیر حساب کاربری محدود است (بقیهٔ /api/v1/* برای او ۴۰۳ است — رجوع به
dashboard.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:
{
"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:
{
"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 (خروجی واقعی):
{
"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 یافت نشد |
خروجی واقعی خطاها:
{"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 (همه فیلدها اختیاری):
{
"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:
{
"success": true,
"data": {
"uuid": "a1b2c3d4-...",
"active": false,
...
}
}
Errors:
| Code | HTTP | توضیح |
|---|---|---|
| ERR_STAFF_NOT_FOUND | 404 | پرسنل یافت نشد |
| ERR_FORBIDDEN_001 | 403 | دسترسی ندارید |