Files
clinicpro/.claude/prompt/fix-profile-in-clinic-context.md

8.2 KiB
Raw Permalink Blame History

رفع باگ پروفایل دکتر در context کلینیک — doctor_uuid با clinic_uuid اشتباه گرفته می‌شود

زمینه

دکتری که عضو چند کلینیک است، در صفحه «انتخاب محیط کاری» می‌تواند به context کلینیک سوئیچ کند. بعد از سوئیچ، dbUuid در authStore برابر uuid کلینیک می‌شود. وقتی دکتر به /admin/profile می‌رود، DoctorProfilePage از dbUuid به عنوان uuid دکتر استفاده می‌کند و همه API callها با uuid اشتباه صدا زده می‌شوند:

  • GET /api/v1/doctor/c9c6a393-... (uuid کلینیک) → 404
  • GET /api/v1/appointment-slots?doctor_uuid=c9c6a393-... → 404

کاربر تست: 09123456783 — دکتر 8b066a5e-3742-4bf7-8087-0b1f8d98de08 (uuid دکتر) که عضو کلینیک c9c6a393-9182-4388-8cdc-6423026eeb54 است.

مشکل / هدف

dbUuid دو معنی متفاوت دارد:

  • در context مطب شخصی: uuid دکتر ✓
  • در context کلینیک: uuid کلینیک ✗ (اما DoctorProfilePage آن را uuid دکتر فرض می‌کند)

راه‌حل: doctor_uuid را به عنوان فیلد جداگانه در userinfo و switch-context response اضافه کن و در store ذخیره کن. DoctorProfilePage باید از doctorUuid استفاده کند نه dbUuid.

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

فایل نقش
src/Auth/Controller/AuthController.php userInfo() خط 516، switchContext() خط 571
assets/admin/stores/authStore.ts fetchMe() و switchContext() — خط 86 و 105
assets/admin/pages/DoctorDetailPage.tsx uuid = isOwnProfile ? (dbUuid ?? undefined) : paramUuid — خط 2162
assets/admin/pages/DoctorProfilePage.tsx wrapper که isOwnProfile را به DoctorDetailPage پاس می‌دهد

وضعیت فعلی

Backend — userInfo() response (خط 536-548)

return $this->success([
    'uuid'               => $user->getUuid(),
    'primary_role'       => $primaryRole,
    'db_uuid'            => $dbUuid,     // ← وقتی context کلینیک است، این uuid کلینیک است
    'context'            => $context,
    'available_contexts' => $availableContexts,
    // ← doctor_uuid وجود ندارد
]);

Backend — buildAvailableContexts() (خط 614-661)

if ($doctor = $this->doctorRepo->findByUser($user)) {
    $contexts[] = [
        'type'    => 'doctor',
        'db_uuid' => $doctor->getUuid(),   // ← uuid دکتر در این context
        'role'    => 'doctor',
    ];
    foreach ($this->clinicRepo->findByDoctor($doctor) as $clinic) {
        $contexts[] = [
            'type'    => 'clinic',
            'db_uuid' => $clinic->getUuid(),  // ← uuid کلینیک در این context
            'role'    => 'clinic',
            // ← doctor_uuid ندارد
        ];
    }
}

Frontend — authStore.ts (خط 19، 94-95)

interface AuthState {
  dbUuid: string | null;  // ← فقط یک uuid — در context کلینیک، uuid کلینیک است
  // ← doctorUuid وجود ندارد
}

// fetchMe:
set({
  dbUuid:  d.db_uuid ?? null,  // ← uuid کلینیک یا دکتر بسته به context
  // ← doctorUuid set نمی‌شود
});

Frontend — DoctorDetailPage.tsx (خط 2162)

const uuid = isOwnProfile ? (dbUuid ?? undefined) : paramUuid;
// ← وقتی context کلینیک است: uuid = uuid کلینیک → همه API ها با uuid اشتباه صدا زده می‌شوند

وظایف

۱. Backend — اضافه کردن doctor_uuid به response های auth

در src/Auth/Controller/AuthController.php:

الف) userInfo() (خط 536): فیلد doctor_uuid را اضافه کن:

$doctor = $this->doctorRepo->findByUser($user);

return $this->success([
    'id'                 => $user->getId(),
    'uuid'               => $user->getUuid(),
    'mobile_number'      => $user->getMobileNumber(),
    'realName'           => $user->getRealName(),
    'status'             => $user->getStatus(),
    'roles'              => $user->getRoles(),
    'primary_role'       => $primaryRole,
    'db_uuid'            => $dbUuid,
    'db_key'             => $dbKey,
    'doctor_uuid'        => $doctor?->getUuid(),  // ← اضافه شود
    'context'            => $context,
    'available_contexts' => $availableContexts,
]);

ب) buildAvailableContexts() (خط 626): doctor_uuid را به context های کلینیک اضافه کن:

foreach ($this->clinicRepo->findByDoctor($doctor) as $clinic) {
    $contexts[] = [
        'type'        => 'clinic',
        'db_uuid'     => $clinic->getUuid(),
        'name'        => $clinic->getName() ?? '',
        'role'        => 'clinic',
        'doctor_uuid' => $doctor->getUuid(),  // ← اضافه شود
    ];
}

ج) switchContext() response (خط 595): بدون تغییر — context کامل برمی‌گردد و شامل doctor_uuid خواهد بود.

۲. Frontend — اضافه کردن doctorUuid به authStore

در assets/admin/stores/authStore.ts:

الف) ContextItem interface (خط 4):

export interface ContextItem {
  type: 'doctor' | 'clinic';
  db_uuid: string;
  name: string;
  role: 'admin' | 'clinic' | 'doctor' | 'secretary' | 'user';
  doctor_uuid?: string;  // ← اضافه شود — فقط در context های کلینیک
  permissions?: Record<string, any>;
}

ب) AuthState interface (خط 12):

interface AuthState {
  // ...
  dbUuid: string | null;
  doctorUuid: string | null;  // ← اضافه شود — همیشه uuid دکتر، بدون توجه به context
  // ...
}

ج) مقدار اولیه (خط 62):

dbUuid: null,
doctorUuid: null,  // ← اضافه شود

د) logout (خط 72):

doctorUuid: null,  // ← اضافه شود

ه) fetchMe (خط 91):

set({
  dbUuid:       d.db_uuid ?? null,
  doctorUuid:   d.doctor_uuid ?? null,  // ← اضافه شود
  // ...
});

و) switchContext (خط 111):

set({
  dbUuid:      res.data.db_uuid,
  doctorUuid:  res.data.context?.doctor_uuid ?? get().doctorUuid,  // ← context کلینیک doctor_uuid دارد، بقیه همان قبلی
  dbKey:       res.data.db_key,
  context:     res.data.context,
  primaryRole: res.data.context?.role ?? null,
});

ز) partialize (خط 121):

partialize: (s) => ({
  // ...
  doctorUuid: s.doctorUuid,  // ← اضافه شود
  // ...
})

۳. Frontend — استفاده از doctorUuid در DoctorDetailPage

در assets/admin/pages/DoctorDetailPage.tsx خط 2160-2162:

const primaryRole = useAuthStore(s => s.primaryRole);
const dbUuid      = useAuthStore(s => s.dbUuid);
const doctorUuid  = useAuthStore(s => s.doctorUuid);  // ← اضافه شود

// تغییر خط 2162:
const uuid = isOwnProfile
  ? (doctorUuid ?? dbUuid ?? undefined)  // ← doctorUuid اولویت دارد
  : paramUuid;

این تضمین می‌کند که حتی در context کلینیک، uuid دکتر برای همه API callها استفاده شود.

نکات مهم

  • migration لازم نیست — هیچ entity تغییر نمی‌کند
  • doctorUuid فقط برای کاربرانی که role دکتر دارند پر می‌شود — برای admin و clinic-owner خالص null است
  • get().doctorUuid در switchContext — اگر context جدید doctor_uuid نداشت (مثلاً مطب شخصی که db_uuid خودش uuid دکتر است)، مقدار قبلی حفظ شود
  • وقتی context مطب شخصی دکتر است (type: 'doctor'db_uuid خودش uuid دکتر است — doctor_uuid جداگانه نیاز نیست اما خوب است همان مقدار ست شود
  • بعد از تغییر backend: cache:clear
  • بعد از تغییر frontend: yarn dev و TypeScript check
  • مستندات: docs/api/auth.md را با فیلد doctor_uuid در response های userinfo و switch-context به‌روزرسانی کن
  • کاربر تست: 09123456783 — doctor_uuid: 8b066a5e-3742-4bf7-8087-0b1f8d98de08