Business Roles & Permissions Guide
Business Roles & Permissions Guide
This guide explains the default business roles available when inviting team members and how to assign super admin privileges via roles.
Role-Based Super Admin Access
How It Works
Super admin access can be granted two ways:
- Boolean Field (System-Level): Set
is_super_admin = trueon the user model
- Traditional method
- Used for true system administrators
- Accessible via:
UserResourcein Filament admin panel, or Artisan commands
- Role-Based (Recommended for Operations Managers): Assign the
super-adminSpatie role
- More flexible
- Can be managed through role assignments
- The
isSuperAdmin()method checks both the boolean field and the role
Assigning Super Admin via Role
Via Filament Admin Panel:
- Go to
/admin - Navigate to Users
- Edit the user
- Assign them the
super-adminrole via Spatie Permission system
Via Code:
$user->assignRole('super-admin'); // Global role (not tenant-scoped)
Via Artisan (Creating Operations Manager):
// Create user
$user = User::create([...]);
// Assign super-admin role
$user->assignRole('super-admin');
// Or use the set-super-admin command which sets the boolean
php artisan user:set-super-admin operations@example.com
Default Business Roles
When inviting team members, you'll see these common small business roles:
Management Roles
Operations Manager
- Best For: Day-to-day operations, team management
- Permissions:
- Manage team members
- View/edit tenant settings
- Full CRM access (view, create, edit, delete)
- Full Projects access (view, create, edit, delete)
- Finance access with approvals
- File management
Account Manager
- Best For: Client relationships, customer success
- Permissions:
- Full CRM access (view, create, edit, delete)
- Project viewing and editing
- Finance viewing and editing
- File access
Project Manager
- Best For: Project oversight, delivery management
- Permissions:
- CRM viewing
- Full Projects access (view, create, edit, delete)
- Finance viewing and editing
- File management
Finance Manager
- Best For: Financial oversight, approvals
- Permissions:
- CRM and Projects viewing
- Full Finance access (view, create, edit, delete, approve)
- File access
Sales Manager
- Best For: Lead management, sales tracking
- Permissions:
- Full CRM access (view, create, edit, delete)
- Project viewing
- Finance viewing
- File access
HR Manager
- Best For: Employee management, HR functions
- Permissions:
- Team member management
- CRM access (view, create, edit)
- File management
Standard Roles
Admin
- Best For: Full access without owner privileges
- Permissions: All management permissions except billing (unless explicitly granted)
Member
- Best For: Standard team members
- Permissions: Basic viewing and creating in active modules
Guest
- Best For: Read-only access for clients/consultants
- Permissions: View-only access to modules
When to Use Each Role
Operations Manager
- Someone who runs day-to-day operations
- Needs to manage team members
- Needs access to all modules
- Doesn't need billing access
Account Manager
- Manages client relationships
- Needs CRM access to track interactions
- Needs to view projects and finances
- Doesn't need to create projects
Project Manager
- Oversees project delivery
- Needs full project access
- Needs to view CRM for context
- May need to approve finances related to projects
Finance Manager
- Handles financial approvals
- Needs full finance access
- Needs to view related projects/CRM
- Doesn't need to create projects
Sales Manager
- Manages leads and sales pipeline
- Needs full CRM access
- Needs to view projects to see what's been sold
- Doesn't need to manage projects
HR Manager
- Manages employees
- Needs team management access
- Needs CRM access for employee records
- Doesn't need project/finance management
Customizing Roles
Adding a New Role
- Add to Seeder (
database/seeders/RolePermissionSeeder.php):
'custom-role' => [
'description' => 'Custom Role - Description',
'permissions' => [
'crm.view',
'crm.create',
// ... other permissions
],
],
- Run Seeder:
php artisan db:seed --class=RolePermissionSeeder
- Add to Team Management:
- Update validation in
app/Livewire/Settings/TeamManagement.php - Add option to role dropdown in
resources/views/livewire/settings/team-management.blade.php
Modifying Permissions for a Role
- Edit Seeder (
database/seeders/RolePermissionSeeder.php) - Update permissions array for the role
- Reseed (this will update existing roles):
php artisan db:seed --class=RolePermissionSeeder
Note: Reseeding will update role permissions. Users with that role will automatically get the new permissions.
Checking Super Admin Access
The isSuperAdmin() method checks both:
public function isSuperAdmin(): bool
{
// Check boolean field first (system-level)
if ($this->is_super_admin === true) {
return true;
}
// Check if user has the 'super-admin' role (role-based)
return $this->hasRole('super-admin');
}
This means:
- Users with
is_super_admin = trueare super admins - Users with
super-adminrole are also super admins - Both methods work for accessing
/adminpanel and bypassing checks
Best Practices
For Operations Managers
- Use role-based super admin (
super-adminrole) - Easier to manage and audit
- Can be revoked without changing the boolean field
For System Administrators
- Use boolean field (
is_super_admin = true) - More permanent and explicit
- Clear separation from business roles
For Regular Business Roles
- Use the business role names (operations-manager, account-manager, etc.)
- Permissions are automatically assigned
- Easy to understand and manage
Examples
Example 1: Operations Manager with Super Admin Access
// Create user
$user = User::create([
'name' => 'Operations Manager',
'email' => 'ops@example.com',
'password' => Hash::make('password'),
]);
// Option 1: Assign super-admin role (recommended)
$user->assignRole('super-admin');
// Option 2: Set boolean field
$user->is_super_admin = true;
$user->save();
// Both methods work - user can now access /admin
Example 2: Account Manager with Standard Permissions
// Invite user via UI or code
$invitation = UserInvitation::createInvitation(
tenantId: $tenant->id,
email: 'account@example.com',
role: 'account-manager', // Business role
invitedBy: auth()->id()
);
// When user accepts invitation, they'll get:
// - Role in tenant_user pivot: 'account-manager'
// - Spatie role assigned: 'account-manager' (tenant-scoped)
// - Permissions: CRM full access, Projects view/edit, Finance view/edit
Permissions Reference
Permission Structure
Permissions follow the pattern: {module}.{action}
Available Permissions:
crm.view,crm.create,crm.edit,crm.deleteprojects.view,projects.create,projects.edit,projects.deletefinance.view,finance.create,finance.edit,finance.delete,finance.approvefiles.view,files.upload,files.deletetenant.settings.view,tenant.settings.edittenant.modules.managetenant.users.manage
Role Permissions Summary
Role | CRM | Projects | Finance | Files | Team | Settings |
|---|---|---|---|---|---|---|
Operations Manager | Full | Full | Approve | Full | Manage | View/Edit |
Account Manager | Full | View/Edit | View/Edit | Upload | ||
Project Manager | View | Full | View/Edit | Full | ||
Finance Manager | View | View | Full | Upload | ||
Sales Manager | Full | View | View | Upload | ||
HR Manager | View/Edit | Full | Manage | |||
Admin | Full | Full | Full | Full | Manage | View/Edit |
Member | View | View | View | Upload | ||
Guest | View | View | View | View |
Troubleshooting
User Can't Access Admin Panel
Check:
- User has
is_super_admin = trueOR - User has
super-adminrole assigned
Fix:
# Check user's status
php artisan tinker
>>> $user = User::where('email', 'user@example.com')->first();
>>> $user->is_super_admin; // Should be true
>>> $user->hasRole('super-admin'); // Should be true
Role Permissions Not Working
Check:
- Role exists:
Role::where('name', 'operations-manager')->exists() - Role has permissions assigned
- User has the role assigned (tenant-scoped)
Fix:
# Reseed roles and permissions
php artisan db:seed --class=RolePermissionSeeder
# Check user's role
php artisan tinker
>>> $user = User::where('email', 'user@example.com')->first();
>>> $tenant = Tenant::current();
>>> $user->getTenantRole($tenant); // Should return role name
>>> $user->hasTenantRole('operations-manager'); // Should be true
Related Documentation
Updated on: 13/03/2026
Thank you!
