6.6 KiB
افزودن فیلد شبکههای اجتماعی به 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 برمیگرداند الگو گرفت:
// 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
// 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 ذخیرهشده:
{
"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
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 اضافه شود:
'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 پزشک باید شامل شود:
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).