feat: add staff role functionality with dashboard access and service management

- Implemented SidebarStaff component tests to ensure staff users see only their dashboard and services.
- Created StaffMyServicesPage to display assigned services for staff users.
- Added migration to link clinic staff rows to user accounts for ROLE_STAFF access.
- Defined StaffPermissions class for static permissions related to staff role.
- Introduced StaffRouteGuardSubscriber to restrict API access for staff users.
- Developed StaffAccountService for managing staff user accounts and linking them to clinic staff.
- Added comprehensive tests for StaffAccountService to validate user creation, mobile number handling, and account attachment.
- Implemented tests for staff dashboard access to ensure proper permissions and access control.
- Created tests for staff login context to verify correct environment visibility based on user roles.
This commit is contained in:
hamed
2026-07-30 10:18:41 +03:30
parent 6ec011e3ad
commit 57aeb40934
28 changed files with 1960 additions and 29 deletions
@@ -2,6 +2,7 @@
namespace App\Staff\Repository;
use App\Auth\Entity\User;
use App\Staff\Entity\ClinicStaff;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
@@ -34,6 +35,42 @@ class ClinicStaffRepository extends ServiceEntityRepository
return $qb->getQuery()->getResult();
}
/**
* ردیف‌های فعالِ این کاربر در همهٔ محیط‌ها — یک نفر می‌تواند پرسنل چند کلینیک/مطب باشد.
*
* @return ClinicStaff[]
*/
public function findActiveByUser(User $user): array
{
return $this->createQueryBuilder('s')
->where('s.user = :user')
->andWhere('s.active = true')
->setParameter('user', $user)
->orderBy('s.fullName', 'ASC')
->getQuery()
->getResult();
}
public function findActiveByUserAndEntity(User $user, string $entityType, int $entityId): ?ClinicStaff
{
return $this->findOneBy([
'user' => $user,
'entityType' => $entityType,
'entityId' => $entityId,
'active' => true,
]);
}
/** برای جلوگیری از ثبت دو پرسنل با یک شماره در یک محیط. */
public function findByEntityAndPhone(string $entityType, int $entityId, string $phone): ?ClinicStaff
{
return $this->findOneBy([
'entityType' => $entityType,
'entityId' => $entityId,
'phone' => $phone,
]);
}
public function save(ClinicStaff $staff): void
{
$this->getEntityManager()->persist($staff);