# فیکس نمایش دکتر در شهر از طریق کلینیک ## پروژه `clinicpro` (backend) ## زمینه دکتری که هیچ آدرس و city مستقیمی ندارد اما به یک کلینیک وصل است، در سایت عمومی (`nobat724_front`) در شهر آن کلینیک نمایش داده نمی‌شود. علت: query فیلتر city فقط روی `d.cities` (جدول `doctor_cities`) کار می‌کند و `Clinic.cityId` را نادیده می‌گیرد. ## مشکل `DoctorRepository::findWithFilters()` فیلتر city: ```php // clinicpro/src/Doctor/Repository/DoctorRepository.php خط ۵۶-۵۸ if (!empty($filters['city'])) { $qb->andWhere('ci.id = :city')->setParameter('city', (int) $filters['city']); } ``` `ci` از `leftJoin('d.cities', 'ci')` می‌آید — جدول `doctor_cities`. اگر دکتر در این جدول ردیفی نداشته باشد (یعنی هیچ city مستقیم ندارد)، حتی اگر عضو کلینیکی با همان city باشد، از نتایج حذف می‌شود. ## ساختار مرتبط ```php // Doctor Entity #[ORM\ManyToMany(targetEntity: City::class)] #[ORM\JoinTable(name: 'doctor_cities')] private Collection $cities; // جدول doctor_cities // Clinic Entity #[ORM\Column(name: 'city_id', type: 'integer', nullable: true)] private ?int $cityId = null; // FK به categories.id #[ORM\ManyToMany(targetEntity: Doctor::class)] #[ORM\JoinTable(name: 'clinic_doctors')] private Collection $doctors; // جدول clinic_doctors ``` ## فایل‌های مرتبط | فایل | نقش | |------|-----| | `clinicpro/src/Doctor/Repository/DoctorRepository.php` | `findWithFilters()` — باید تغییر کند | | `clinicpro/src/Doctor/Controller/DoctorController.php` | صدا زننده `findWithFilters` | | `clinicpro/src/Clinic/Entity/Clinic.php` | `cityId` و `doctors` collection | | `clinicpro/src/Doctor/Entity/Doctor.php` | `cities` collection | ## وضعیت فعلی ```php // DoctorRepository.php — findWithFilters() $qb = $this->createQueryBuilder('d') ->leftJoin('d.specialties', 's') ->leftJoin('d.provinces', 'pr') ->leftJoin('d.cities', 'ci') ->distinct(); // ... if (!empty($filters['city'])) { $qb->andWhere('ci.id = :city')->setParameter('city', (int) $filters['city']); } ``` ## وظایف ### ۱. گسترش فیلتر city به clinic city در `findWithFilters()` join کلینیک را اضافه کن و شرط city را تغییر بده تا هم `doctor_cities` هم `clinic.city_id` را پوشش دهد: ```php $qb = $this->createQueryBuilder('d') ->leftJoin('d.specialties', 's') ->leftJoin('d.provinces', 'pr') ->leftJoin('d.cities', 'ci') ->leftJoin(Clinic::class, 'cl', Join::WITH, 'd MEMBER OF cl.doctors') // ← اضافه ->distinct(); // ... if (!empty($filters['city'])) { $qb->andWhere('ci.id = :city OR cl.cityId = :city') ->setParameter('city', (int) $filters['city']); } ``` همچنین فیلتر `state` را هم بررسی کن — اگر `d.provinces` هم خالی باشد، باید از استان کلینیک گرفته شود. اما برای این باگ، city اولویت دارد. ### ۲. بررسی فیلتر state مشابه ```php // فعلی: if (!empty($filters['state'])) { $qb->andWhere('pr.id = :state')->setParameter('state', (int) $filters['state']); } // باید: // اگر کلینیک دارد، province آن کلینیک را هم در نظر بگیر // اما Clinic فقط cityId دارد، نه provinceId مستقیم // → از category join برای گرفتن province شهر کلینیک استفاده کن یا فعلاً فقط city را فیکس کن ``` ### ۳. import لازم در بالای `DoctorRepository.php` اضافه کن: ```php use App\Clinic\Entity\Clinic; use Doctrine\ORM\Query\Expr\Join; ``` (اگر `Join` از قبل import نشده) ### ۴. تست ```bash ddev exec php bin/console debug:router | grep "api/v1/doctors" # endpoint: GET /api/v1/doctors?city= # تست: یک دکتر که فقط از طریق کلینیک در شهر X است را با ?city=X جستجو کن # باید در نتایج ظاهر شود ``` ## نکات مهم - `Clinic.cityId` یک integer FK است به `categories.id` (جدول categories با bundle='city') — نه یک relation object. پس `cl.cityId = :city` درست است (نه `cl.city.id`). - `leftJoin` برای کلینیک لازم است نه `innerJoin` — دکتری که اصلاً عضو هیچ کلینیکی نیست هم باید در نتایج بماند (اگر city مستقیم دارد). - `OR cl.cityId = :city` ممکن است با `DISTINCT` مشکل ایجاد کند — اگر دکتر هم city مستقیم دارد هم عضو کلینیک در همان city است، `DISTINCT` آن را یک‌بار نمایش می‌دهد. - migration لازم نیست — فقط query تغییر می‌کند. - بعد از تغییر، `docs/api/doctor.md` را update کن (رفتار فیلتر city تغییر کرده).