feat: add per-doctor permissions management in clinics
- Implement DoctorPermissionsModal for managing doctor permissions in clinics. - Create usePermissions hook to handle user permissions context. - Add migration for clinic_doctor_permissions table with default permissions. - Develop ClinicDoctorPermissionController for handling permissions API. - Create ClinicDoctorPermission entity to manage permissions data. - Implement ClinicDoctorPermissionRepository for database interactions. - Add ClinicDoctorPermissionChecker for permission validation logic. - Write tests for clinic doctor permissions functionality.
This commit is contained in:
@@ -8,6 +8,8 @@ use App\Auth\Repository\UserActiveContextRepository;
|
||||
use App\Auth\Repository\UserRepository;
|
||||
use App\Auth\Service\OtpService;
|
||||
use App\Auth\Service\TokenService;
|
||||
use App\Clinic\Entity\ClinicDoctorPermission;
|
||||
use App\Clinic\Repository\ClinicDoctorPermissionRepository;
|
||||
use App\Clinic\Repository\ClinicRepository;
|
||||
use App\Doctor\Repository\DoctorRepository;
|
||||
use App\Secretary\Repository\DoctorSecretaryRepository;
|
||||
@@ -37,6 +39,7 @@ class AuthController extends BaseController
|
||||
private readonly RateLimiterFactory $passwordResetLimiter,
|
||||
private readonly DoctorRepository $doctorRepo,
|
||||
private readonly ClinicRepository $clinicRepo,
|
||||
private readonly ClinicDoctorPermissionRepository $clinicDoctorPermRepo,
|
||||
private readonly DoctorSecretaryRepository $secretaryRepo,
|
||||
private readonly UserActiveContextRepository $contextRepo,
|
||||
private readonly UserPasswordHasherInterface $hasher,
|
||||
@@ -703,11 +706,18 @@ class AuthController extends BaseController
|
||||
'name' => 'مطب شخصی ' . $doctor->getName(),
|
||||
'role' => 'doctor',
|
||||
];
|
||||
foreach ($this->clinicRepo->findByDoctor($doctor) as $clinic) {
|
||||
// پزشکِ عضو کلینیک «مالک» نیست؛ نقش doctor با scope کلینیک میگیرد تا
|
||||
// فقط نوبتهای خودش در آن کلینیک را ببیند، نه دسترسی کامل پنل کلینیک.
|
||||
$memberClinics = $this->clinicRepo->findByDoctor($doctor);
|
||||
$permMap = $this->clinicDoctorPermRepo->mapByClinicForDoctor(
|
||||
$doctor,
|
||||
array_map(fn($c) => $c->getId(), $memberClinics),
|
||||
);
|
||||
|
||||
foreach ($memberClinics as $clinic) {
|
||||
// پزشکِ عضو کلینیک «مالک» نیست؛ نقش doctor با scope کلینیک میگیرد و
|
||||
// دسترسیاش را مجوزهای همان کلینیک تعیین میکند، نه hardcode.
|
||||
// اگر همین پزشک مالک کلینیک باشد، نقش کامل clinic در بلوک مالک پایین ست میشود.
|
||||
$isOwner = $clinic->getUser()->getId() === $user->getId();
|
||||
$perm = $permMap[$clinic->getId()] ?? null;
|
||||
$contexts[] = [
|
||||
'type' => 'clinic',
|
||||
'db_uuid' => $clinic->getUuid(),
|
||||
@@ -715,6 +725,7 @@ class AuthController extends BaseController
|
||||
'role' => $isOwner ? 'clinic' : 'doctor',
|
||||
'scope' => $isOwner ? null : 'clinic',
|
||||
'doctor_uuid' => $doctor->getUuid(),
|
||||
'permissions' => $isOwner ? null : $this->contextPermissions($perm),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -764,6 +775,21 @@ class AuthController extends BaseController
|
||||
return $contexts;
|
||||
}
|
||||
|
||||
/**
|
||||
* مجوزی که به کلاینت داده میشود: نبودِ سطر یعنی عضویت قدیمی (پیشفرض)، و
|
||||
* سطر غیرفعال یعنی هیچ دسترسی.
|
||||
*/
|
||||
private function contextPermissions(?ClinicDoctorPermission $perm): array
|
||||
{
|
||||
if ($perm === null) {
|
||||
return ClinicDoctorPermission::DEFAULT_PERMISSIONS;
|
||||
}
|
||||
|
||||
return $perm->isActive()
|
||||
? $perm->getPermissions()
|
||||
: ['version' => 1, 'resources' => []];
|
||||
}
|
||||
|
||||
private function findContextByDbUuid(string $dbUuid, array $contexts): ?array
|
||||
{
|
||||
foreach ($contexts as $ctx) {
|
||||
|
||||
Reference in New Issue
Block a user