Files
clinicpro/.claude/prompt/fix-doctor-city-via-clinic.md
T

5.0 KiB

فیکس نمایش دکتر در شهر از طریق کلینیک

پروژه

clinicpro (backend)

زمینه

دکتری که هیچ آدرس و city مستقیمی ندارد اما به یک کلینیک وصل است، در سایت عمومی (nobat724_front) در شهر آن کلینیک نمایش داده نمی‌شود. علت: query فیلتر city فقط روی d.cities (جدول doctor_cities) کار می‌کند و Clinic.cityId را نادیده می‌گیرد.

مشکل

DoctorRepository::findWithFilters() فیلتر city:

// 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 باشد، از نتایج حذف می‌شود.

ساختار مرتبط

// 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

وضعیت فعلی

// 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 را پوشش دهد:

$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 مشابه

// فعلی:
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 اضافه کن:

use App\Clinic\Entity\Clinic;
use Doctrine\ORM\Query\Expr\Join;

(اگر Join از قبل import نشده)

۴. تست

ddev exec php bin/console debug:router | grep "api/v1/doctors"
# endpoint: GET /api/v1/doctors?city=<city_id>
# تست: یک دکتر که فقط از طریق کلینیک در شهر 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 تغییر کرده).