configuration PK: id 10 required 4 unique

Description

Defines the four access levels in the system: Peer Mentor, Coordinator, Organization Administrator, and Global Administrator. Roles drive all permission checks, screen visibility, API authorization, and data scoping logic across the entire platform.

11
Attributes
3
Indexes
6
Validation Rules
19
CRUD Operations

Data Structure

Name Type Description Constraints
id uuid Immutable primary key for the role record, generated on system seed.
PKrequiredunique
slug enum Machine-readable role identifier used in JWT claims, API authorization checks, permission matrix lookups, and route guards throughout the platform.
requiredunique
name string Human-readable display name for the role, shown in user management screens and audit logs.
requiredunique
description text Prose description of the role's responsibilities and scope, used in admin panel tooltips and onboarding documentation.
-
hierarchy_level integer Numeric ordering that encodes privilege hierarchy: 1=peer_mentor, 2=coordinator, 3=org_admin, 4=global_admin. Used to prevent privilege escalation — admins may only assign roles with hierarchy_level strictly less than their own.
requiredunique
permission_matrix json Structured JSON object mapping permission keys to boolean grants. Keys follow the pattern '<resource>:<action>' (e.g., 'activity:create', 'report:export_bufdir', 'user:invite'). Consumed by role-guard-service for synchronous permission lookups and cached client-side in permissions-repository.
required
mobile_access boolean Whether this role grants access to the Flutter mobile app. False for global_admin (redirected to admin panel only).
required
admin_panel_access boolean Whether this role grants access to the Next.js admin panel. True for coordinator, org_admin, and global_admin.
required
data_scope enum Defines the data visibility boundary for this role. Controls how repositories and services scope SQL queries.
required
created_at datetime Timestamp when the role record was created (system seed time).
required
updated_at datetime Timestamp of the last permission_matrix or metadata update.
required

Database Indexes

idx_role_slug
btree unique

Columns: slug

idx_role_hierarchy_level
btree unique

Columns: hierarchy_level

idx_role_name
btree unique

Columns: name

Validation Rules

slug_must_be_valid_enum error

Validation failed

permission_matrix_valid_json error

Validation failed

hierarchy_level_in_range error

Validation failed

name_not_empty error

Validation failed

mobile_and_admin_panel_access_consistent error

Validation failed

jwt_role_claim_matches_slug error

Validation failed

Business Rules

system_seeded_immutable_set
always

Exactly four role records exist and are created exclusively by the database seed migration. No runtime API endpoint may create or delete role records. The set of valid slugs is closed: peer_mentor, coordinator, org_admin, global_admin.

no_privilege_escalation
on_create

An authenticated user may only assign roles with a hierarchy_level strictly lower than their own. A Coordinator (level 2) cannot grant Coordinator, Org Admin, or Global Admin roles. Enforced server-side on every invite and role-assignment operation.

global_admin_mobile_redirect
always

Users whose active role is global_admin must not be granted mobile app access. The No-Access Screen is displayed with a link to the admin panel. The JWT claims for global_admin users must set mobile_access=false.

data_scope_enforcement
always

Every data-fetching repository and service must apply the data_scope of the requesting user's role. peer_mentor sees only own records; coordinator sees their local_association; org_admin sees their full organization; global_admin sees all data.

permission_matrix_completeness
on_update

The permission_matrix JSON for each role must contain an explicit grant (true/false) for every registered permission key. Missing keys default to false, but a schema validator must warn on deployment if any permission key is absent from a role's matrix.

coordinator_requires_association_scope
always

Any coordinator-level operation (team reports, bulk registration, reimbursement approval) must be scoped to a specific local_association_id drawn from the user's user_organization_roles record. A coordinator may not access data for associations they are not assigned to.

permission_matrix_cached_on_login
always

After successful authentication, the client must fetch and cache the permission_matrix for the user's active role via the permissions-repository. Subsequent permission checks (route guards, UI visibility) are resolved synchronously from this cache without network round-trips.

Storage Configuration

Storage Type
lookup_table
Location
main_db
Partitioning
No Partitioning
Retention
Permanent Storage

Entity Relationships

user_organization_role
outgoing one_to_many

A role can be assigned to many users across organizations

required