# رفع باگ تغییر محیط کاری — 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) ```php return $this->success([ 'db_uuid' => $dbUuid, 'db_key' => $this->buildDbKey($dbUuid), 'context' => $matched, ]); ``` `$matched` از `buildAvailableContexts()` می‌آید و دارای فیلد `role` است: ```php // برای 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) ```ts 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) ```tsx 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 کن: ```ts 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'` — چون در آن محیط باید به عنوان نماینده کلینیک عمل کند: ```php 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: ```tsx const uuid = isOwnProfile ? (dbUuid ?? undefined) : paramUuid; ``` وقتی `isOwnProfile = true` و `primaryRole === 'clinic'`، صفحه profile پزشک منطقی نیست — دکتر در حال مشاهده به عنوان نماینده کلینیک است. دو گزینه: **گزینه A (توصیه‌شده):** در `DoctorProfilePage.tsx` و route `/admin/profile`، وقتی `primaryRole === 'clinic'`، به dashboard هدایت کن: ```tsx // 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 ; } ``` **گزینه B:** در `App.tsx` route `profile` را فقط به role `doctor` محدود کن: ```tsx // App.tsx — خط 142 } /> // این از قبل هست — مشکل این است که 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-context` response به‌روزرسانی شود