User Roles & Access
User accounts and employee records are managed together from the Employees page. This page covers the role system and how access works.
User management was previously on a separate Users page. All user management — invitations, role changes, and access control — is now integrated into the Employees page. If you have a bookmark to the old Users page, it will automatically redirect to Employees.
User Roles
There are five roles. The first four (Employee → Supervisor → Manager → Company Admin) form a strict hierarchy: each inherits everything from the role below. Accounting sits off to the side — it has its own specialized access focused on payroll, independent of the Supervisor/Manager track.
| Role | What they can do |
|---|---|
| Employee | View their own schedule and shifts, clock in/out, request leave, swap shifts with colleagues, view their own pay (My Pay), submit app feedback. |
| Supervisor | All Employee permissions, plus: view the employee list, create and edit shifts, build draft rosters, approve/reject timesheets and leave requests, manage tasks and announcements, view the staff calendar and compliance warnings. Cannot publish rosters — that requires Manager. |
| Manager | All Supervisor permissions, plus: publish roster windows, lock roster windows, create and edit wage tables, manage custom allowances, public holidays, organization settings, locations/departments, compliance screens, budgets, pulse (Shift Pulse), audit logs, view per-employee experience data, run payroll, and send user invitations. |
| Company Admin | All Manager permissions, plus the actions that affect billing, compliance, or bulk state: revoke an exported payroll period, run the bulk experience recomputation, import employees via CSV, configure Bradford thresholds, configure booking sources (webhooks), and manage the admin feedback inbox. |
| Accounting | A payroll specialist with no general management access. Can: approve, reject, and mark exported payroll periods, perform Netvisor export operations, view the employee list, and access payroll reports. Cannot manage shifts, employees, wage tables, audit logs, or general settings. |
:::info Where does each permission actually come from?
Permissions are enforced in the API by role groups defined in apps/api/src/modules/auth/auth.constants.ts:
SUPERVISOR_AND_ABOVE→ Supervisor, Manager, Company AdminMANAGEMENT_ROLES→ Manager, Company AdminADMIN_ROLES→ Company Admin onlyACCOUNTING_ROLES→ Accounting, Company AdminPAYROLL_ROLES→ Manager, Company Admin, AccountingEMPLOYEES_LIST_ROLES→ Supervisor, Manager, Company Admin, Accounting
Individual API endpoints declare which group they require with @Roles(...). If a reality here disagrees with this article, the code is authoritative — please file a docs fix.
:::
How Employees Get App Access
When you create an employee, an invitation email is automatically sent to their email address. The employee clicks the link to set their password and create their login account. The system automatically links the user account to the employee record.
Access Status
The employee list shows an Access column indicating each person's app access status:
| Status | Meaning |
|---|---|
| Active | The employee has a user account and can log in. |
| Invited | An invitation has been sent but not yet accepted. |
| No access | No invitation has been sent and no user account exists. |
| Disabled | The employee has been archived and cannot log in. |
Changing a User's Role
Managers and company admins can change a user's role directly from the employee list:
- Navigate to Employees.
- Click the actions menu (⋮) on the employee's row.
- Select Change Role.
- Choose the new role from the dropdown.
- Click Save.
After a role change, the user is logged out and must log in again to receive updated permissions.
Who can assign which role
The API enforces a hierarchy when assigning roles. A user can assign any role at or below their own level:
Employee (0) < Accounting (1) < Supervisor (2) < Manager (3) < Company Admin (4)
| Your role | Roles you can assign |
|---|---|
| Employee | Employee |
| Accounting | Employee, Accounting |
| Supervisor | Employee, Accounting, Supervisor |
| Manager | Employee, Accounting, Supervisor, Manager — but not Company Admin |
| Company Admin | Any role, including Company Admin |
In practice, only users with Manager or Company Admin can access the employee list and so are the only ones who open the Change Role dialog. Supervisor and Accounting rows are shown here for completeness.
- You cannot change your own role — even if the hierarchy would permit it. This is a separate safeguard on top of the hierarchy check.
- When a role changes, the affected user's refresh tokens are invalidated, forcing re-login with the new permissions.
Sending Invitations
If an employee doesn't have app access yet, you can send an invitation manually:
- Click the actions menu (⋮) on the employee's row.
- Select Send Invitation.
- Choose a role for the user.
- Click Send.
The invitation expires after 7 days. If it expires, send a new one using Resend Invitation from the actions menu.
Important Notes
- Each user must have a unique email address.
- After accepting an invitation, the user sets their own name and password.
- Archiving an employee automatically disables their user account (see Managing Employees).
- Disabled users cannot log in but their historical data (shifts, worklogs, payroll) is preserved.
Source of truth — The role definitions and assignment hierarchy in this article are enforced in code. When roles or their capabilities change, the authoritative files are:
packages/shared/src/types/enums.ts— theUserRoleenumapps/api/src/modules/auth/auth.constants.ts— role groups (MANAGEMENT_ROLES,ADMIN_ROLES,ACCOUNTING_ROLES,SUPERVISOR_AND_ABOVE,PAYROLL_ROLES,EMPLOYEES_LIST_ROLES)apps/api/src/modules/auth/role-escalation.ts— the numeric hierarchy and theassertCanAssignRolecheck
Per-endpoint role requirements live on each controller as @Roles(...) decorators under apps/api/src/modules/.