feat: add social media links field to Doctor entity and update API documentation

This commit is contained in:
hamed
2026-06-21 12:35:22 +03:30
parent 943784b64a
commit 3f1b2de971
6 changed files with 236 additions and 1 deletions
+105
View File
@@ -0,0 +1,105 @@
# افزودن فیلد شبکه‌های اجتماعی به Doctor
## پروژه
`clinicpro` (Backend) — این تغییر پیش‌نیاز پرامپت همتا در frontend است: `nobat724_front/.claude/prompt/doctor-seo-schema-knowledge-panel.md`. آن پرامپت برای Knowledge Panel گوگل به `sameAs` در JSON-LD نیاز دارد که باید از همین فیلد جدید پر شود.
## زمینه
برای فعال‌سازی Knowledge Panel گوگل برای صفحه‌ی هر پزشک (هدف نهایی در `nobat724_front`)، schema.org نیاز به آرایه‌ی `sameAs` دارد که لینک پروفایل‌های شبکه‌های اجتماعی پزشک (اینستاگرام، تلگرام، آپارات، یوتیوب، لینکدین) را به گوگل معرفی می‌کند. بررسی `src/Doctor/Entity/Doctor.php` و `docs/api/doctor.md` نشان داد این داده هیچ‌جا در API موجود نیست — نه در پاسخ `GET /api/v1/doctor/{uuid}` و نه در فرم ادمین (`assets/admin/pages/DoctorFormPage.tsx`).
نکته‌ی مهم: برخلاف انتظار اولیه، `DoctorAddress` (`src/Doctor/Entity/DoctorAddress.php`) از قبل `latitude`/`longitude` دارد و در `toArray()` به‌صورت `map: { latitude, longitude }` برمی‌گرداند — یعنی GeoCoordinates برای LocalBusiness schema نیازی به تغییر backend ندارد. فقط شبکه‌های اجتماعی پزشک باقی می‌ماند.
## مشکل / هدف
به `Doctor` entity یک فیلد JSON برای ذخیره‌ی لینک شبکه‌های اجتماعی (اینستاگرام، تلگرام، آپارات، یوتیوب، لینکدین، توییتر/X) اضافه شود، در پاسخ API برگردانده شود، و در فرم ادمین برای ویرایش در دسترس باشد.
## فایل‌های مرتبط
| فایل | نقش |
|------|-----|
| `src/Doctor/Entity/Doctor.php` | باید فیلد `socialMedia` (JSON nullable) اضافه شود |
| `src/Doctor/Controller/DoctorController.php` | پاسخ `GET /api/v1/doctor/{uuid}` باید `social_media` را برگرداند؛ متد update باید آن را بپذیرد |
| `migrations/` | migration جدید برای ستون `social_media` روی جدول `doctors` |
| `assets/admin/pages/DoctorFormPage.tsx` | فیلدهای ورودی لینک‌های اجتماعی به فرم اضافه شود |
| `assets/admin/types/index.ts` | type پزشک باید `socialMedia` را شامل شود |
| `docs/api/doctor.md` | باید فیلد جدید مستند شود |
## وضعیت فعلی
`src/Doctor/Entity/Doctor.php` فیلدهای پایه دارد (نام، تخصص، آدرس‌ها) اما هیچ فیلد JSON برای داده‌ی نیمه‌ساخت‌یافته ندارد. الگوی مشابه را می‌توان از `DoctorAddress::toArray()` که `map` را به‌صورت nested object برمی‌گرداند الگو گرفت:
```php
// src/Doctor/Entity/DoctorAddress.php — الگوی موجود برای nested object در toArray()
'map' => [
'latitude' => $this->latitude !== null ? (string) $this->latitude : null,
'longitude' => $this->longitude !== null ? (string) $this->longitude : null,
],
```
## وظایف
### ۱. افزودن فیلد `socialMedia` به `Doctor` entity
```php
// src/Doctor/Entity/Doctor.php
#[ORM\Column(name: 'social_media', type: 'json', nullable: true)]
private ?array $socialMedia = null;
public function getSocialMedia(): ?array { return $this->socialMedia; }
public function setSocialMedia(?array $v): self { $this->socialMedia = $v; $this->touch(); return $this; }
```
ساختار JSON ذخیره‌شده:
```json
{
"instagram": "https://instagram.com/dr.example",
"telegram": "https://t.me/dr_example",
"aparat": "https://aparat.com/dr.example",
"youtube": "https://youtube.com/@dr.example",
"linkedin": "https://linkedin.com/in/dr-example"
}
```
هر کلید nullable است — پزشک ممکن است فقط بعضی شبکه‌ها را داشته باشد. کلیدهای خالی/null باید در پاسخ API هم `null` بمانند (نه حذف شوند) تا frontend به‌سادگی چک کند.
### ۲. Migration
```bash
ddev exec php bin/console doctrine:migrations:diff --no-interaction
ddev exec php bin/console doctrine:migrations:migrate --no-interaction
```
### ۳. بازگرداندن فیلد در پاسخ API
در `src/Doctor/Controller/DoctorController.php`، هرجا `toArray()`-مانند برای پزشک ساخته می‌شود (GET تکی، GET لیست)، کلید `social_media` اضافه شود:
```php
'social_media' => $doctor->getSocialMedia(),
```
و در متد update، فیلد جدید از request body خوانده و validate شود (فقط باید URL معتبر یا null باشد برای هر کلید — از `InputValidator` یا یک Assert ساده استفاده کن، الگوی موجود validation در همان کنترلر را دنبال کن).
### ۴. فرم ادمین
در `assets/admin/pages/DoctorFormPage.tsx`، یک بخش جدید «شبکه‌های اجتماعی» با ۵ فیلد متنی (اینستاگرام، تلگرام، آپارات، یوتیوب، لینکدین) اضافه شود. الگوی `Field()` موجود در همین فایل (خط ۵۲) را برای ساخت input استفاده کن. مقدار اولیه از `doctor.socialMedia` پر شود، در submit به همان شکل JSON ارسال شود.
در `assets/admin/types/index.ts`، interface پزشک باید شامل شود:
```ts
socialMedia?: {
instagram?: string | null;
telegram?: string | null;
aparat?: string | null;
youtube?: string | null;
linkedin?: string | null;
} | null;
```
## نکات مهم
- این فیلد باید **nullable** کامل باشد — پزشکانی که شبکه اجتماعی ندارند نباید خطا بگیرند.
- مقادیر باید URL کامل (با `https://`) ذخیره شوند، نه فقط username — frontend مستقیماً این مقدار را در `sameAs` آرایه‌ی JSON-LD قرار می‌دهد بدون پردازش اضافی.
- بعد از این تغییر، `docs/api/doctor.md` را طبق قانون پروژه (به‌روزرسانی مستندات هم‌زمان با تغییر API) ویرایش کن — هم در نمونه‌ی JSON پاسخ `GET /api/v1/doctor/{uuid}` و هم در بخش فیلدهای قابل ویرایش.
- migration را قبل از merge باید روی دیتابیس dev واقعی تست کنی (`ddev exec php bin/console doctrine:migrations:migrate --no-interaction`).