92 lines
5.4 KiB
Markdown
92 lines
5.4 KiB
Markdown
# پروفایل unclaimed پزشک — حذف امتیاز پیشفرض جعلی از پاسخ API
|
||
|
||
## پروژه
|
||
|
||
`clinicpro` (backend) — **cross-repo**. پرامپت همتای frontend:
|
||
`nobat724_front/.claude/prompt/unclaimed-doctor-public-page.md`
|
||
این تغییر backend باید **اول** انجام شود؛ سایت عمومی و پنل ادمین و tauri همگی همین پاسخ را مصرف میکنند.
|
||
|
||
## زمینه
|
||
|
||
پزشکانِ ایمپورتشده از نظام پزشکی (IRIMC) با `owner_status = 'unclaimed'` ساخته میشوند و هیچگاه فیلد امتیاز ست نمیشود؛ پس مقادیر پیشفرضِ انتیتی (`doctor_rate = 3.5`, `doctor_rate_percentage = 60`) بهعنوان امتیاز واقعی در پاسخ عمومی برمیگردند. سایت اینها را بهصورت «امتیاز: ۳.۵» و «۶۰٪ رضایت» و در JSON-LD بهصورت `AggregateRating` نشان میدهد — در حالی که تعداد نظرات واقعی صفر است.
|
||
|
||
## مشکل / هدف
|
||
|
||
- **بحرانی:** دادهی امتیاز جعلی برای پروفایل بدون صاحب. هم گمراهکننده، هم نقض دستورالعمل structured data گوگل (ریویوی جعلی) و ریسک جریمه.
|
||
- هدف: تا وقتی پروفایل `claimed` نشده، فیلدهای امتیاز در پاسخ عمومی **null** برگردند (نه مقدار پیشفرض). بعد از claim، رفتار عادی برگردد (بدون تغییر، چون آنموقع `owner_status='claimed'`).
|
||
|
||
## فایلهای مرتبط
|
||
|
||
| فایل | نقش |
|
||
|------|-----|
|
||
| `src/Doctor/Entity/Doctor.php` | `toDetailArray()` (L530–576) و `toListArray()` (L506–528) — سریالسازی `satisfaction`/`point`/`owner_status` |
|
||
| `src/Doctor/Controller/DoctorController.php` | `show()` L149–173 (public `GET /api/v1/doctor/{uuid}`)، `list()` L244–260 (public `GET /api/v1/doctors`) — بدون تغییر، فقط مصرفکننده |
|
||
| `docs/api/doctor.md` | باید بهروز شود |
|
||
|
||
## وضعیت فعلی
|
||
|
||
فیلدهای انتیتی (`src/Doctor/Entity/Doctor.php`):
|
||
|
||
```php
|
||
#[ORM\Column(name: 'doctor_rate', type: 'float')]
|
||
private float $doctorRate = 3.5; // L67–68
|
||
|
||
#[ORM\Column(name: 'doctor_rate_percentage', type: 'float')]
|
||
private float $doctorRatePercentage = 60.0; // L70–71
|
||
|
||
// owner_status enum: claimed | unclaimed | pending_transfer (L83)
|
||
#[ORM\Column(name: 'owner_status', type: 'string', length: 20)]
|
||
private string $ownerStatus = 'claimed'; // L84–85
|
||
```
|
||
|
||
سریالسازی فعلی (هر دو آرایه امتیاز را همیشه برمیگردانند):
|
||
|
||
```php
|
||
// toDetailArray() L557–559
|
||
'satisfaction' => (string) $this->doctorRatePercentage,
|
||
'point' => (string) $this->doctorRate,
|
||
'owner_status' => $this->ownerStatus,
|
||
|
||
// toListArray() L521–526 — همان دو کلید + owner_status
|
||
```
|
||
|
||
## وظایف
|
||
|
||
### ۱. helper برای «آیا امتیاز واقعی نمایش داده شود؟»
|
||
|
||
در `Doctor.php` یک متد کوچک اضافه کن (منبع واحد منطق):
|
||
|
||
```php
|
||
/** امتیاز فقط برای پروفایل claimed معتبر است؛ unclaimed/pending_transfer مقدار پیشفرض جعلی دارد. */
|
||
public function hasPublicRating(): bool
|
||
{
|
||
return $this->ownerStatus === 'claimed';
|
||
}
|
||
```
|
||
|
||
### ۲. null کردن امتیاز در `toDetailArray()` و `toListArray()`
|
||
|
||
در هر دو متد، بهجای مقدار مستقیم:
|
||
|
||
```php
|
||
'satisfaction' => $this->hasPublicRating() ? (string) $this->doctorRatePercentage : null,
|
||
'point' => $this->hasPublicRating() ? (string) $this->doctorRate : null,
|
||
```
|
||
|
||
`owner_status` بدون تغییر بماند (frontend به آن نیاز دارد). کلیدها **حذف نشوند**، فقط مقدارشان `null` شود تا شکل پاسخ نشکند.
|
||
|
||
### ۳. مستندسازی
|
||
|
||
`docs/api/doctor.md` را بهروز کن:
|
||
- در توضیح فیلدهای پاسخ single (L83–118) و list (L196–222) ذکر کن: `point` و `satisfaction` برای `owner_status !== 'claimed'` مقدار `null` دارند.
|
||
- یک خط در header note اضافه کن که امتیاز پیشفرض فقط برای پروفایل claimed منتشر میشود.
|
||
|
||
## نکات مهم
|
||
|
||
- **پاسخ double-nested است**: `show()` از `$this->success(['data' => array_merge($doctor->toDetailArray($schedule), [...])])` استفاده میکند → frontend با `data.data.data` میخواند. شکل را تغییر نده، فقط مقدار دو کلید.
|
||
- **بعد از claim خودکار درست میشود**: `DoctorClaimService::finalize()` وضعیت را به `'claimed'` میبرد → `hasPublicRating()` صحیح میشود → امتیاز واقعی برمیگردد. نیازی به منطق اضافه برای «برگشت به حالت عادی» نیست.
|
||
- `pending_transfer` هم مثل `unclaimed` امتیاز نداشته باشد (فقط `claimed` امتیاز دارد).
|
||
- تست موجود اگر روی `toDetailArray`/`toListArray` هست را چک کن (مقدار `point`/`satisfaction` ممکن است اکنون `null` شود). `ddev exec php bin/phpunit`.
|
||
- migration لازم **نیست** (فقط منطق سریالسازی، نه تغییر schema).
|
||
- بعد از تغییر: `ddev exec php vendor/bin/phpstan analyse` و `graphify update .`.
|