Files
clinicpro/.claude/prompt/fix-invitation-accept.md
T

4.3 KiB
Raw Blame History

Fix: پذیرفتن دعوتنامه کلینیک، پزشک را به clinic_doctors اضافه نمی‌کند

مشکل

وقتی پزشک دعوتنامه کلینیک را می‌پذیرد (از طریق پنل پزشک یا لینک SMS)، فقط وضعیت دعوتنامه به accepted تغییر می‌کند — اما پزشک به جدول clinic_doctors اضافه نمی‌شود.

ریشه باگ

src/ClinicInvitation/Service/ClinicInvitationService.php — متد accept():

public function accept(ClinicDoctorInvitation $inv): void
{
    if (!$inv->isUsable()) {
        throw new AppException('ERR_NOT_FOUND_001', 'دعوتنامه منقضی یا غیرمعتبر است', 410);
    }
    $inv->setStatus(ClinicDoctorInvitation::STATUS_ACCEPTED);
    $inv->markUsed();
    $this->em->flush();   // ← فقط status عوض می‌شود، هیچ رابطه‌ای ثبت نمی‌شود
}

باید بعد از accept، پزشک به $clinic->getDoctors() اضافه شود. رابطه در Clinic::$doctors (ManyToMany → جدول clinic_doctors) تعریف شده است.

فایل‌های مرتبط

فایل نقش
src/ClinicInvitation/Service/ClinicInvitationService.php متد accept() — جای اصلی باگ
src/ClinicInvitation/Entity/ClinicDoctorInvitation.php entity دعوتنامه — دارای getClinic() و getDoctor()
src/Clinic/Entity/Clinic.php دارای getDoctors(): Collection و رابطه ManyToMany

وضعیت فعلی

  • ClinicDoctorInvitation::$doctor وقتی پزشک در سیستم وجود دارد، set می‌شود (در invite())
  • ClinicDoctorInvitation::$doctor ممکن است null باشد (پزشک هنوز ثبت‌نام نکرده)
  • پذیرش از دو مسیر اتفاق می‌افتد:
    1. لینک SMSPOST /api/v1/clinic-invitation/{token}/accept (بدون احراز هویت)
    2. پنل پزشکPOST /api/v1/doctor/invitation/{invUuid}/respond با action=accept

وظایف

۱. رفع باگ در ClinicInvitationService::accept()

public function accept(ClinicDoctorInvitation $inv): void
{
    if (!$inv->isUsable()) {
        throw new AppException('ERR_NOT_FOUND_001', 'دعوتنامه منقضی یا غیرمعتبر است', 410);
    }

    $inv->setStatus(ClinicDoctorInvitation::STATUS_ACCEPTED);
    $inv->markUsed();

    // اضافه کردن پزشک به کلینیک
    $doctor = $inv->getDoctor();
    if ($doctor !== null) {
        $clinic = $inv->getClinic();
        if (!$clinic->getDoctors()->contains($doctor)) {
            $clinic->getDoctors()->add($doctor);
        }
    }

    $this->em->flush();
}

۲. بررسی حالت لبه‌ای: پزشک null است

اگر $inv->getDoctor() در زمان accept هنوز null باشد (پزشک بعداً ثبت‌نام کرده)، باید با موبایل در DoctorRepository جستجو کرد و doctor را set و اضافه کرد:

if ($doctor === null) {
    $doctor = $this->doctorRepo->findOneByMobile($inv->getMobile());
    if ($doctor !== null) {
        $inv->setDoctor($doctor);
    }
}

۳. تست

بعد از رفع:

ddev exec php -l src/ClinicInvitation/Service/ClinicInvitationService.php
ddev exec php bin/console cache:clear
ddev exec yarn dev

تست دستی:

  • یک دعوتنامه ارسال کن
  • پزشک از پنل داشبورد دعوت را بپذیرد
  • در صفحه کلینیک بررسی کن که پزشک در لیست پزشکان کلینیک ظاهر شده

۴. مستندات

فایل docs/api/clinic-invitation.md را به‌روزرسانی کن:

  • اضافه کن: هنگام accept، پزشک به clinic_doctors اضافه می‌شود
  • edge case: اگر doctor هنگام دعوت ثبت‌نام نکرده بود، هنگام accept با موبایل match می‌شود

نکات مهم

  • هر دو مسیر (لینک SMS و پنل پزشک) از همان $invitationService->accept() استفاده می‌کنند — رفع باگ در یک جا کافی است
  • $clinic->getDoctors()->contains($doctor) را چک کن تا duplicate نشود
  • بعد از flush نیازی به migration نیست — جدول clinic_doctors از قبل وجود دارد