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

229 lines
8.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# رفع باگ پروفایل دکتر در 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)
```php
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)
```php
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)
```ts
interface AuthState {
dbUuid: string | null; // ← فقط یک uuid — در context کلینیک، uuid کلینیک است
// ← doctorUuid وجود ندارد
}
// fetchMe:
set({
dbUuid: d.db_uuid ?? null, // ← uuid کلینیک یا دکتر بسته به context
// ← doctorUuid set نمی‌شود
});
```
### Frontend — `DoctorDetailPage.tsx` (خط 2162)
```tsx
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` را اضافه کن:
```php
$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 های کلینیک اضافه کن:
```php
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):**
```ts
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):**
```ts
interface AuthState {
// ...
dbUuid: string | null;
doctorUuid: string | null; // ← اضافه شود — همیشه uuid دکتر، بدون توجه به context
// ...
}
```
**ج) مقدار اولیه (خط 62):**
```ts
dbUuid: null,
doctorUuid: null, // ← اضافه شود
```
**د) `logout` (خط 72):**
```ts
doctorUuid: null, // ← اضافه شود
```
**ه) `fetchMe` (خط 91):**
```ts
set({
dbUuid: d.db_uuid ?? null,
doctorUuid: d.doctor_uuid ?? null, // ← اضافه شود
// ...
});
```
**و) `switchContext` (خط 111):**
```ts
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):**
```ts
partialize: (s) => ({
// ...
doctorUuid: s.doctorUuid, // ← اضافه شود
// ...
})
```
### ۳. Frontend — استفاده از `doctorUuid` در `DoctorDetailPage`
در `assets/admin/pages/DoctorDetailPage.tsx` خط 2160-2162:
```tsx
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`