Extend POST /api/v1/patient to resolve user by uuid or mobile, and create a new ROLE_USER (name + optional national code, no password) when no user exists. Admin modal shows a new-patient form on lookup miss. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
83 lines
5.1 KiB
Markdown
83 lines
5.1 KiB
Markdown
# تعریف بیمار جدید بدون ثبتنام قبلی در سایت
|
||
|
||
## پروژه
|
||
|
||
`clinicpro` (backend + admin frontend)
|
||
|
||
## زمینه
|
||
|
||
در حال حاضر برای ایجاد پروندهی بیمار، کاربر باید **از قبل در سیستم ثبتنام کرده باشد**: مودال «ایجاد پرونده بیمار» با شماره موبایل جستجو میکند و اگر `User` پیدا نشد، خطا میدهد.
|
||
|
||
```php
|
||
// src/Patient/Controller/PatientController.php — searchUser
|
||
$patient = $this->userRepo->findByMobile($mobile);
|
||
if ($patient === null) {
|
||
return $this->error(ErrorCodes::ERR_NOT_FOUND_001, 'کاربری با این شماره یافت نشد', 404);
|
||
}
|
||
```
|
||
|
||
و `create` فقط با `user_uuid` کار میکند:
|
||
|
||
```php
|
||
$userUuid = trim($data['user_uuid'] ?? '');
|
||
$patient = $this->userRepo->findByUuid($userUuid);
|
||
```
|
||
|
||
## مشکل / هدف
|
||
|
||
کلینیک/مطب باید بتواند بیمار جدیدی تعریف کند که **هرگز در سایت ثبتنام نکرده**. یعنی اگر با شماره موبایل کاربری پیدا نشد، بهجای خطا، امکان ساخت `User` جدید (بههمراه پروفایل پایه: نام، کد ملی، جنسیت و …) و سپس ساخت `PatientRecord` فراهم شود.
|
||
|
||
## فایلهای مرتبط
|
||
|
||
| فایل | نقش |
|
||
|------|-----|
|
||
| `src/Patient/Controller/PatientController.php` | `searchUser` + `create` |
|
||
| `src/Patient/Service/PatientService.php` | منطق ساخت پرونده |
|
||
| `src/Auth/Entity/User.php` | کاربر؛ دارای `nationalCode`, `realName`, `mobileNumber` |
|
||
| `src/UserProfile/Entity/UserProfile.php` | پروفایل کامل بیمار (family, gender, dateOfBirth, insurance ids و …) |
|
||
| `src/Auth/Repository/UserRepository.php` | `findByMobile`, `findByUuid`, `save` |
|
||
| `assets/admin/pages/MyPatientsPage.tsx` | مودال «ایجاد پرونده بیمار» (state: `createRecordOpen`, `searchMobile`, `foundUser`) |
|
||
| `docs/api/patient.md` | مستندات API بیمار |
|
||
|
||
## وضعیت فعلی
|
||
|
||
- مودال فعلی: شماره موبایل میگیرد → `GET /api/v1/patient/search-user?mobile=` → اگر یافت شد کارت نتیجه + دکمهی «ایجاد پرونده» (`POST /api/v1/patient` با `user_uuid`).
|
||
- اگر یافت نشد: فقط پیغام خطا «کاربری با این شماره یافت نشد»؛ راهی برای ساخت بیمار جدید نیست.
|
||
- `User` ساختنی است با `new User($mobileNumber)` و `setRealName`, `setNationalCode`.
|
||
- `UserProfile` فیلدهای دموگرافیک کامل دارد (`family`, `gender`, `dateOfBirth`, `basicInsuranceId`, `supplementaryInsuranceId` …).
|
||
|
||
## وظایف
|
||
|
||
### ۱. Backend — endpoint ساخت بیمار جدید
|
||
|
||
دو رویکرد ممکن (یکی را انتخاب و توضیح بده):
|
||
|
||
- **الف)** گسترش `POST /api/v1/patient`: اگر `user_uuid` نبود ولی `mobile` + `name` (+ فیلدهای اختیاری پروفایل) آمد، `User` جدید بساز (با نقش `ROLE_USER`)، در صورت نیاز `UserProfile` بساز، سپس `PatientRecord`.
|
||
- **ب)** endpoint جدا `POST /api/v1/patient/new-user`.
|
||
|
||
> توصیه: رویکرد الف. در `create`: اول با `user_uuid`؛ اگر نبود، با `mobile` جستجو کن؛ اگر `User` نبود و `name` آمده بود، بساز.
|
||
|
||
نکات:
|
||
- اگر شماره موبایل قبلاً وجود دارد (کاربر ثبتنامکرده)، همان `User` استفاده شود (نه duplicate).
|
||
- validation: موبایل `^09\d{9}$`, کد ملی در صورت ارسال `^\d{10}$`.
|
||
- فیلدهای پروفایل اختیاری ذخیره شوند (در `User` یا `UserProfile` طبق مدل واقعی).
|
||
|
||
### ۲. Admin Frontend — مودال
|
||
|
||
مودال «ایجاد پرونده بیمار» را گسترش بده:
|
||
|
||
- بعد از جستجو، اگر کاربر **یافت نشد**، بهجای خطای صرف، یک فرم «ساخت بیمار جدید» نشان بده (نام، کد ملی، جنسیت، و فیلدهای پایه) با موبایل از پیش پرشده.
|
||
- دکمهی «ایجاد پرونده» این بار `User` جدید را هم میسازد.
|
||
- اگر یافت شد، رفتار فعلی حفظ شود.
|
||
|
||
### ۳. مستندات
|
||
|
||
`docs/api/patient.md` را با تغییر `POST /api/v1/patient` (یا endpoint جدید) بهروز کن: body جدید، حالتهای یافتشد/ساخت جدید، error codeها.
|
||
|
||
## نکات مهم
|
||
|
||
- entity owner از `#[CurrentUser]` resolve میشود (`PatientController::resolveEntity`).
|
||
- duplicate موبایل را مدیریت کن.
|
||
- این پرامپت با `patient-record-profile-binding.md` همپوشانی دارد (هر دو روی پروفایل بیمار کار میکنند)؛ اگر آن اجرا شده، از همان ساختار `UserProfile` استفاده کن.
|
||
- بیمار ساختهشده بدون رمز عبور است (بعداً میتواند با OTP وارد شود)؛ مطمئن شو ساخت `User` بدون `passwordHash` مجاز است (هست — `nullable: true`).
|