branches->pair($user); } public function address(User $user, string $addressUuid): DoctorAddress { return $this->branches->resolve($user, $addressUuid); } public function type(User $user, string $uuid): ResourceType { return $this->owned($user, $this->types->findByUuid($uuid), 'نوع منبع یافت نشد'); } /** * پزشکِ ناظرِ منبع. * * `Doctor` تحت `TenantOwnedTrait` نیست (پزشک می‌تواند هم‌زمان عضو چند کلینیک باشد)، * پس مالکیت با عضویت سنجیده می‌شود: در محیط کلینیک باید پزشکِ همان کلینیک باشد، و در * مطب شخصی باید خودِ همان پزشک. بدون این، منشیِ یک کلینیک می‌توانست دستگاهش را زیر * نظر پزشک کلینیک دیگری ببرد. */ public function supervisor(User $user, string $uuid): Doctor { $doctor = $this->doctors->findByUuid($uuid); if ($doctor === null) { throw new AppException(ErrorCodes::ERR_NOT_FOUND_001, 'پزشک ناظر یافت نشد', 404); } [$entityType, $entityId] = $this->pair($user); // رابطه از سمت کلینیک تعریف شده (`Clinic::$doctors`)، پس عضویت را خودِ کلینیک // جواب می‌دهد — `Clinic::hasDoctor()`؛ کوئری تازه‌ای لازم نیست. $clinic = $entityType === 'clinic' ? $this->clinics->find($entityId) : null; $belongs = $entityType === 'clinic' ? ($clinic !== null && $clinic->hasDoctor($doctor)) : (int) $doctor->getId() === $entityId; if (!$belongs) { throw new AppException(ErrorCodes::ERR_NOT_FOUND_001, 'پزشک ناظر یافت نشد', 404); } return $doctor; } public function resource(User $user, string $uuid): ClinicResource { return $this->owned($user, $this->resources->findByUuid($uuid), 'منبع یافت نشد'); } public function skill(User $user, string $uuid): Skill { return $this->owned($user, $this->skills->findByUuid($uuid), 'مهارت یافت نشد'); } public function pool(User $user, string $uuid): ResourcePool { return $this->owned($user, $this->pools->findByUuid($uuid), 'استخر منابع یافت نشد'); } /** * @template T of object * @param T|null $entity * @return T */ private function owned(User $user, ?object $entity, string $message): object { [$entityType, $entityId] = $this->pair($user); if ($entity === null || !$this->ownership->belongsToPair($entityType, $entityId, $entity)) { throw new AppException(ErrorCodes::ERR_NOT_FOUND_001, $message, 404); } return $entity; } }