User Roles
Data Entity
Description
Defines the platform's role archetypes — Peer Mentor, Coordinator, Organization Administrator, and Global Administrator — each carrying a fixed permission set that governs screen access, API endpoint authorization, and data scoping across all three Meander products.
Data Structure
| Name | Type | Description | Constraints |
|---|---|---|---|
id |
uuid |
Unique identifier for the role definition | PKrequiredunique |
name |
string |
Human-readable role name displayed in UI and used in terminology overrides (e.g. 'Peer Mentor', 'Coordinator') | requiredunique |
slug |
string |
Machine-readable role identifier used in JWT claims, route guards, and API authorization (e.g. 'peer_mentor', 'coordinator', 'org_admin', 'global_admin') | requiredunique |
description |
text |
Detailed description of the role's purpose, responsibilities, and access boundaries | - |
scope |
enum |
Data visibility scope the role grants: 'local_association' for peer mentors, 'organization' for coordinators and org admins, 'global' for global admins | required |
hierarchy_level |
integer |
Numeric rank for escalation control — higher values represent broader authority (1=Peer Mentor, 2=Coordinator, 3=Org Admin, 4=Global Admin). Users cannot assign roles at or above their own level. | required |
permissions |
json |
JSON array of permission strings granted to this role (e.g. ['activity:create', 'activity:read_own', 'expense:submit', 'contact:read_assigned']). Evaluated by Role Guard Service and Permission Validation Middleware. | required |
allowed_products |
json |
JSON array of product identifiers this role can access (e.g. ['meander-mobile-app'] for Peer Mentor, ['meander-mobile-app', 'admin-web-portal'] for Coordinator) | required |
is_system_role |
boolean |
True for the four predefined platform roles that cannot be deleted or have their slug changed. False for any future custom roles. | required |
is_active |
boolean |
Soft-disable flag. Inactive roles cannot be assigned to new users but existing assignments remain until explicitly revoked. | required |
max_concurrent_roles |
integer |
Maximum number of additional roles a user holding this role may simultaneously hold. Null means no limit. Used to enforce single-role constraints if needed. | - |
created_at |
datetime |
Timestamp when the role was created | required |
updated_at |
datetime |
Timestamp of the last modification to the role definition | required |
Database Indexes
idx_user_roles_slug
Columns: slug
idx_user_roles_name
Columns: name
idx_user_roles_hierarchy_level
Columns: hierarchy_level
idx_user_roles_is_active
Columns: is_active
Validation Rules
slug_format
error
Validation failed
unique_slug
error
Validation failed
unique_name
error
Validation failed
valid_permissions_array
error
Validation failed
valid_allowed_products
error
Validation failed
hierarchy_level_positive
error
Validation failed
system_role_immutability
error
Validation failed
scope_consistency_with_products
warning
Validation failed
Business Rules
four_predefined_system_roles
The platform ships with exactly four system roles: Peer Mentor (hierarchy_level=1), Coordinator (hierarchy_level=2), Organization Administrator (hierarchy_level=3), and Global Administrator (hierarchy_level=4). System roles (is_system_role=true) cannot be deleted or have their slug modified.
escalation_prevention
A user can only assign roles with a hierarchy_level strictly lower than their own highest role. Coordinators cannot grant Org Admin; Org Admins cannot grant Global Admin. Global Admins can assign any role.
global_admin_no_org_context
Global Administrator role has scope='global' and is not bound to any organization. Global admins manage the system but do not have default access to organization operational data. Tenant separation is enforced.
peer_mentor_mobile_only
Peer Mentor role has allowed_products=['meander-mobile-app'] and cannot access the Admin Web Portal. If a Peer Mentor attempts to log into the admin portal, they are shown a no-access screen.
multi_role_support
Users may hold multiple roles simultaneously (e.g. a Coordinator who is also a Peer Mentor). The active role is tracked per session and can be switched without re-authentication. Role switching changes the data scope and available UI sections.
inactive_role_no_new_assignment
Roles with is_active=false cannot be assigned to new users via user_role_assignments. Existing assignments remain valid until explicitly revoked to avoid breaking active sessions.
role_change_invalidates_jwt
When a user's role assignments change, the roles_updated_at timestamp on the user record is updated. Existing JWTs issued before that timestamp are considered stale and the client must refresh to obtain updated role claims.
scope_determines_data_visibility
The role's scope attribute directly controls which data a user can see: local_association limits to assigned association contacts and activities, organization grants full org access, global grants cross-organization system access.