Skip to main content
BarberApp implements a role-based access control system with four distinct user roles, each with specific capabilities and access levels.

Available roles

The system defines four user roles:
user-roles.enum.ts:1-6
export enum UserRoles {
  ADMIN = 'admin',
  CLIENT = 'client',
  SPECIALIST = 'specialist',
  USER = 'user', // Default role for general users
}

Role overview

Client

Book appointments, view history, rate services, and manage profile

Specialist

Manage schedule, view client appointments, add diagnoses, and handle bookings

Admin

Full system access including user management and system configuration

User

Default role for general users with basic access

User base model

All users share a common base model:
user-base.model.ts:3-17
export interface UserBase {
  id: string;
  firstName: string;
  lastName: string;
  dni: string;
  sex: Sex;
  birthDate: Date;
  email: string;
  password?: string;
  phone?: string;
  profilePictureUrl: string;
  registrationDate: Date;
  role: UserRoles;
  status: UserStatus;
}

Client role

Clients are users who book appointments and receive services.

Client model

client.model.ts:3-7
export interface Client extends UserBase {
  // medicalRecordId: string;
  height?: number;
  weight?: number;
}

Client capabilities

Clients can request new appointments by selecting a specialty, specialist, and preferred time slot.
Access to all past, current, and upcoming appointments with full details.
Cancel pending appointments with the option to provide a cancellation reason.
After completion, clients can rate appointments on a scale of 1-5 and leave comments.
Update personal information, profile picture, height, and weight.

Client dashboard access

Clients are redirected to /dashboard/client after login:
auth.facade.ts:188-190
case UserRoles.CLIENT:
  this.router.navigate(['/dashboard/client']);
  break;

Specialist role

Specialists provide services and manage their schedules.

Specialist model

specialist.model.ts:3-8
export interface Specialist extends UserBase {
  specialties: Specialty[];
  availability: Availability[];
  availabilityName: string; // From "AVAILABILITY_PRESETS_OPTIONS"
}

Specialist capabilities

View all appointments, filter by status (pending, completed, canceled), and update appointment details.
Configure working hours and available time slots using preset schedules or custom availability.
Record diagnosis details and annotations for completed appointments.
Access completed appointment history for returning clients.
Cancel appointments with clients, providing a reason for cancellation.
Specialists can have multiple specialties (e.g., haircut, beard trim, coloring).

Specialist dashboard access

Specialists are redirected to /dashboard/specialist after login:
auth.facade.ts:191-193
case UserRoles.SPECIALIST:
  this.router.navigate(['/dashboard/specialist']);
  break;

Admin role

Administrators have full system access and management capabilities.

Admin capabilities

  • Manage all users (clients and specialists)
  • View system-wide appointment data
  • Configure specialties and services
  • Access all dashboards and features
  • Monitor system health and activity

Admin dashboard access

Admins currently use the specialist dashboard:
auth.facade.ts:194-196
case UserRoles.ADMIN:
  this.router.navigate(['/dashboard/specialist']);
  break;
Admin users have access to specialist features plus additional administrative capabilities.

Route guards

BarberApp uses two types of guards to protect routes:

Authentication guard

The authGuard ensures users are authenticated:
auth.guard.ts:5-21
export const authGuard = async () => {
  const authFacade = inject(AuthFacade);
  const router = inject(Router);

  while (authFacade.isCheckingAuth()) {
    await new Promise((resolve) => setTimeout(resolve, 10));
  }

  const isAuthenticated = authFacade.isAuthenticated();
  console.log(isAuthenticated)
  if (isAuthenticated) {
    return true;
  } else {
    router.navigate(['/auth/login']);
    return false;
  }
};

Role guard

The roleGuard restricts access based on user roles:
role.guard.ts:6-41
export const roleGuard = (allowedRoles: UserRoles[]) => {
  return async () => {
    const authFacade = inject(AuthFacade);
    const router = inject(Router);

    while (authFacade.isCheckingAuth()) {
      await new Promise(resolve => setTimeout(resolve, 10));
    }

    const user = authFacade.user();
    if (!user) {
      router.navigate(['/auth/login']);
      return false;
    }

    if (allowedRoles.includes(user.role)) {
      return true;
    } else {
      // Redirect to the corresponding dashboard according to the user's role
      switch (user.role) {
        case UserRoles.CLIENT:
          router.navigate(['/dashboard/client']);
          break;
        case UserRoles.SPECIALIST:
          router.navigate(['/dashboard/specialist']);
          break;
        case UserRoles.ADMIN:
          router.navigate(['/dashboard/specialist']);
          break;
        default:
          router.navigate(['/dashboard/client']);
      }
      return false;
    }
  };
};

Using role guards

Apply role guards to routes that should only be accessible by specific roles:
const routes: Routes = [
  {
    path: 'client',
    component: ClientPageComponent,
    canActivate: [roleGuard([UserRoles.CLIENT])]
  },
  {
    path: 'specialist',
    component: SpecialistPageComponent,
    canActivate: [roleGuard([UserRoles.SPECIALIST, UserRoles.ADMIN])]
  }
];

Registration with roles

During registration, users select their role (Client or Specialist):
register-form.component.ts:62-63
// Signal for Current mode (Client or Specialist)
readonly userMode: WritableSignal<UserMode> = signal<UserMode>(R.CLIENT);
The form adapts based on the selected role:
register-form.component.ts:180-187
toggleMode(): void {
  if (this.showSpecialtyModal()) this.closeModal();
  const newMode = this.userMode() === R.CLIENT ? R.SPECIALIST : R.CLIENT;
  this.userMode.set(newMode);
  this.clearModeFields();
  this.updateModeValidators();
}
Role assignment happens during registration and cannot be changed by users. Contact an administrator to modify user roles.

User status

In addition to roles, users have a status that determines if they can access the system:
export enum UserStatus {
  ACTIVE = 'active',
  INACTIVE = 'inactive',
  SUSPENDED = 'suspended'
}
Only users with ACTIVE status can log in and use the system.

Next steps

Client Dashboard

Explore client-specific features and capabilities

Specialist Dashboard

Learn about specialist tools and workflows

Build docs developers (and LLMs) love