Skip to main content

User Roles & Permissions

CAFH Platform implements a hierarchical role-based access control (RBAC) system with five distinct roles. Each role has specific permissions and access levels throughout the platform.

Role Hierarchy

// types.ts:14-20
export enum UserRole {
  SUPER_ADMIN = 'SUPER_ADMIN',
  ADMIN = 'ADMIN',
  EDITOR = 'EDITOR',
  MEMBER = 'MEMBER',
  GUEST = 'GUEST'
}
Roles are hierarchical: higher roles inherit all permissions from lower roles.

Role Definitions

SUPER_ADMIN

Super Administrator

Highest privilege level - Full system access with no restrictions
Can Access:
  • All admin panel modules
  • System configuration and settings
  • User management (create/edit/delete admins)
  • Tenant-wide settings
  • Dangerous operations (bulk delete, data export)
Typical Use Cases:
  • Platform owner or technical administrator
  • Managing multiple tenants/organizations
  • System maintenance and troubleshooting
  • Initial platform setup and configuration
Example User (constants.ts:40-50):
{
  id: 'u_admin',
  name: 'Administrador Principal',
  email: '[email protected]',
  role: UserRole.SUPER_ADMIN,
  tenantId: 't_santiago_01'
}

ADMIN

Administrator

Full content and member management - Can manage all aspects except system settings
Can Access:
  • Dashboard with analytics
  • CRM & contact management
  • Email campaigns and automations
  • CMS (create/edit/delete pages)
  • Media library (upload/delete assets)
  • Event and activity calendar
  • Virtual meeting management
  • Member profiles and engagement data
Cannot Access:
  • System-level configuration
  • Creating other admin users (typically)
  • Tenant settings
Typical Use Cases:
  • Community managers
  • Content editors
  • Marketing coordinators
  • Event organizers
Route Protection (App.tsx:103-112):
<Route path="/admin" element={
  <ProtectedRoute allowedRoles={[UserRole.ADMIN, UserRole.SUPER_ADMIN]}>
    <AdminLayout><DashboardView /></AdminLayout>
  </ProtectedRoute>
} />

<Route path="/admin/crm" element={
  <ProtectedRoute allowedRoles={[UserRole.ADMIN, UserRole.SUPER_ADMIN]}>
    <AdminLayout><CRMView /></AdminLayout>
  </ProtectedRoute>
} />

EDITOR

Editor

Content creation and editing - Limited to CMS and media library
Can Access:
  • CMS page builder (create/edit pages)
  • Blog post creation and editing
  • Media library (upload only, no delete)
  • Content preview and publishing
Cannot Access:
  • CRM and contact data
  • Email campaigns
  • Analytics dashboard
  • User management
  • System settings
Typical Use Cases:
  • Content writers
  • Blog authors
  • Volunteer content managers
  • Guest contributors with limited access
The EDITOR role is defined in the type system but not yet implemented in the routing layer. This is a future enhancement.

MEMBER

Member

Registered user - Access to member portal and personalized content
Can Access:
  • Member dashboard at /member/dashboard
  • Personal profile and settings
  • Activity history and badges
  • Event registration and participation
  • Content library (member-only resources)
  • Virtual meeting lobby (when registered)
  • Feedback forms and surveys
Cannot Access:
  • Any admin panel routes (/admin/*)
  • Other members’ data
  • Contact lists
  • System configuration
Example User (constants.ts:51-60):
{
  id: 'u_member',
  name: 'Miembro Cafh',
  email: '[email protected]',
  role: UserRole.MEMBER,
  tenantId: 't_santiago_01',
  interests: ['Meditación', 'Bienestar'],
  joinedDate: '2023-10-15'
}
User Interface (types.ts:22-35):
export interface User {
  id: string;
  name: string;
  email: string;
  role: UserRole;
  avatarUrl: string;
  tenantId: string;
  interests: string[];        // Generated by onboarding wizard
  joinedDate: string;
  coverUrl?: string;
  phone?: string;
  city?: string;
}

GUEST

Guest

Unauthenticated user - Public access only
Can Access:
  • Public homepage and marketing pages
  • Blog posts (marked as public)
  • Resources marked as access: 'public'
  • Event calendar (view only)
  • Login and registration pages
Cannot Access:
  • Member dashboard
  • Any admin routes
  • Private content
  • Event registration
  • Profile settings
Typical Use Cases:
  • Website visitors
  • Prospective members
  • Search engine crawlers
  • Social media link previews

Permission Matrix

FeatureSUPER_ADMINADMINEDITORMEMBERGUEST
View Public Pages
Member Dashboard
Edit CMS Pages
Upload Media
Delete Media
Access CRM
Send Campaigns
Create Automations
View Analytics
System Settings
Manage Users

Role Assignment

Default Assignment

New users are typically assigned roles based on registration method:
// Self-registration (public form)
defaultRole = UserRole.MEMBER;

// Invited by admin
defaultRole = UserRole.MEMBER; // or EDITOR if specified

// Created by SUPER_ADMIN
defaultRole = /* any role */ ;

Changing Roles

Only SUPER_ADMIN can change user roles:
// In production, this would be an admin UI action
db.auth.updateUserRole(userId, newRole);
Role changes take effect immediately but require the user to log out and log back in to refresh their session token.

Route Protection Implementation

The ProtectedRoute component enforces access control (App.tsx:33-47):
const ProtectedRoute: React.FC<{ children: React.ReactNode; allowedRoles?: UserRole[] }> = 
  ({ children, allowedRoles }) => {
    const user = db.auth.getCurrentUser();

    // Not logged in → redirect to login
    if (!user) {
      return <Navigate to="/login" replace />;
    }

    // Logged in but wrong role → redirect to their dashboard
    if (allowedRoles && !allowedRoles.includes(user.role)) {
      return <Navigate to={
        user.role === UserRole.MEMBER ? "/member/dashboard" : "/admin"
      } replace />;
    }

    // Authorized → render the protected content
    return <>{children}</>;
};

Best Practices

Principle of Least Privilege

Always assign the minimum role needed for a user’s responsibilities

Regular Audits

Periodically review user roles and revoke unnecessary access

Role Separation

Don’t use SUPER_ADMIN for daily tasks; create an ADMIN account instead

Document Changes

Log all role changes in your change management system

Advanced Scenarios

Multi-Tenant Role Isolation

In a multi-tenant setup, roles are scoped to tenants:
// types.ts:22-28
export interface User {
  id: string;
  name: string;
  email: string;
  role: UserRole;
  tenantId: string;  // ← Role is scoped to this tenant
}
A user who is ADMIN in tenant_a has no access to tenant_b.

Conditional UI Rendering

Components can check roles to show/hide features:
const user = db.auth.getCurrentUser();

{user?.role === UserRole.SUPER_ADMIN && (
  <button onClick={dangerousOperation}>Delete All Data</button>
)}

{[UserRole.ADMIN, UserRole.SUPER_ADMIN].includes(user?.role) && (
  <Link to="/admin/crm">CRM Dashboard</Link>
)}

Multi-Tenancy

How roles interact with tenant isolation

Data Model

See the full User entity structure

Build docs developers (and LLMs) love