6.9 KiB
رفع باگ تغییر محیط کاری — primaryRole آپدیت نمیشود
زمینه
دکتری که عضو چند کلینیک است، در صفحه «انتخاب محیط کاری» میتواند بین مطب شخصی و کلینیکهای مختلف سوئیچ کند. اما بعد از سوئیچ، primaryRole در authStore تغییر نمیکند — هنوز 'doctor' میماند. نتیجه: وقتی به /admin/profile میرود، کد uuid = dbUuid (که حالا uuid کلینیک است) را به GET /api/v1/doctor/{clinicUuid} میفرستد → 404.
مشکل / هدف
وقتی switchContext صدا زده میشود:
dbUuidدر store تغییر میکند (به uuid کلینیک)- اما
primaryRoleتغییر نمیکند (هنوز'doctor'میماند) context.roleدر store ذخیره میشود اما از آن برای آپدیتprimaryRoleاستفاده نمیشود
فایلهای مرتبط
| فایل | نقش |
|---|---|
src/Auth/Controller/AuthController.php |
switchContext endpoint — خط 571 |
assets/admin/stores/authStore.ts |
switchContext action — خط 105 |
assets/admin/pages/DoctorDetailPage.tsx |
uuid = isOwnProfile ? dbUuid : paramUuid — خط 2162 |
assets/admin/pages/SelectContextPage.tsx |
handleSelect — خط 23 |
وضعیت فعلی
Backend — switchContext response (خط 595-599)
return $this->success([
'db_uuid' => $dbUuid,
'db_key' => $this->buildDbKey($dbUuid),
'context' => $matched,
]);
$matched از buildAvailableContexts() میآید و دارای فیلد role است:
// برای context کلینیکهایی که دکتر در آنها عضو است:
$contexts[] = [
'type' => 'clinic',
'db_uuid' => $clinic->getUuid(),
'name' => $clinic->getName() ?? '',
'role' => 'doctor', // ← نه 'clinic'، چون دکتر است نه صاحب کلینیک
];
// برای context مطب شخصی:
$contexts[] = [
'type' => 'doctor',
'db_uuid' => $doctor->getUuid(),
'name' => 'مطب شخصی ...',
'role' => 'doctor',
];
پس context.role موجود است اما backend آن را به عنوان primary_role جداگانه برنمیگرداند.
Frontend — switchContext در authStore (خط 105-117)
switchContext: async (dbUuid: string) => {
const res = await apiFetch('/api/v1/auth/switch-context', {
method: 'POST',
body: JSON.stringify({ db_uuid: dbUuid }),
});
if (res.success) {
set({
dbUuid: res.data.db_uuid,
dbKey: res.data.db_key,
context: res.data.context,
// ← primaryRole آپدیت نمیشود!
});
}
},
Frontend — DoctorDetailPage (خط 2162)
const uuid = isOwnProfile ? (dbUuid ?? undefined) : paramUuid;
// وقتی context کلینیک است، dbUuid = uuid کلینیک است
// اما primaryRole هنوز 'doctor' است
// پس GET /api/v1/doctor/{clinicUuid} → 404
وظایف
۱. Frontend — آپدیت primaryRole در switchContext
در assets/admin/stores/authStore.ts، خط 110-115، primaryRole را از res.data.context.role بخوان و set کن:
switchContext: async (dbUuid: string) => {
const res = await apiFetch('/api/v1/auth/switch-context', {
method: 'POST',
body: JSON.stringify({ db_uuid: dbUuid }),
});
if (res.success) {
set({
dbUuid: res.data.db_uuid,
dbKey: res.data.db_key,
context: res.data.context,
primaryRole: res.data.context?.role ?? null, // ← اضافه شود
});
}
},
۲. Backend — بررسی role در context کلینیکهای عضو دکتر
در buildAvailableContexts() (خط 626-633)، وقتی دکتر به context یک کلینیک سوئیچ میکند، role باید 'clinic' باشد نه 'doctor' — چون در آن محیط باید به عنوان نماینده کلینیک عمل کند:
foreach ($this->clinicRepo->findByDoctor($doctor) as $clinic) {
$contexts[] = [
'type' => 'clinic',
'db_uuid' => $clinic->getUuid(),
'name' => $clinic->getName() ?? '',
'role' => 'clinic', // ← از 'doctor' به 'clinic' تغییر دهید
];
}
نکته مهم: این تغییر باعث میشود وقتی دکتر در context کلینیک است، primaryRole === 'clinic' شود. در DoctorDetailPage این رفتار درست است — read-only view کلینیک فعال میشود و از GET /api/v1/clinic/my-doctor/{uuid} استفاده میکند.
۳. رفع مشکل /admin/profile برای context کلینیک
در DoctorDetailPage.tsx خط 2162:
const uuid = isOwnProfile ? (dbUuid ?? undefined) : paramUuid;
وقتی isOwnProfile = true و primaryRole === 'clinic'، صفحه profile پزشک منطقی نیست — دکتر در حال مشاهده به عنوان نماینده کلینیک است. دو گزینه:
گزینه A (توصیهشده): در DoctorProfilePage.tsx و route /admin/profile، وقتی primaryRole === 'clinic'، به dashboard هدایت کن:
// assets/admin/pages/DoctorProfilePage.tsx
export default function DoctorProfilePage() {
const primaryRole = useAuthStore(s => s.primaryRole);
const navigate = useNavigate();
useEffect(() => {
if (primaryRole === 'clinic') navigate('/admin/dashboard', { replace: true });
}, [primaryRole, navigate]);
return <DoctorDetailPage isOwnProfile />;
}
گزینه B: در App.tsx route profile را فقط به role doctor محدود کن:
// App.tsx — خط 142
<Route path="profile" element={<RoleRoute roles={['doctor']}><DoctorProfilePage /></RoleRoute>} />
// این از قبل هست — مشکل این است که primaryRole درست آپدیت نمیشود
گزینه B کافی است اگر وظیفه ۱ و ۲ درست اجرا شوند — بعد از switch، primaryRole === 'clinic' میشود و RoleRoute کاربر را به dashboard redirect میکند.
نکات مهم
- migration لازم نیست — هیچ entity تغییر نمیکند
context.roleاز قبل در response موجود است — backend فقط نیاز به بررسی مقدار دارد، endpoint تغییر نمیکند- بعد از اصلاح، context کلینیکهای عضو دکتر
role: 'clinic'خواهند داشت — این با guard هایprimaryRole === 'clinic'در DoctorDetailPage سازگار است cache:clearبعد از تغییر backend لازم استyarn devبعد از تغییر frontend لازم است- مستندات:
docs/api/auth.md— توضیح رفتارcontext.roleدرswitch-contextresponse بهروزرسانی شود