RBAC & Menu Management
The Role-Based Access Control (RBAC) system integrates directly with the dynamic menu generation, ensuring users only experience features they are authorized to access.
1. Role System
Roles define a set of permissions and access levels. The system supports dynamic role creation and assignment.
Database Structure
- Roles Table: Stores role definitions (e.g., Administrator, Manager, User).
- Users Table: Links users to a specific `role_id`.
Helper Functions
Located in app/Helpers/rbac_helper.php:
// Get current user's role
$role = userRole();
// Check if user has specific permission (if permissions implemented)
if (userCan('manage_users')) { ... }2. Dynamic Menu Management
The sidebar menu is not hardcoded; it is generated dynamically based on the active module and user's role.
Menu Logic (`sidebar.php`)
The sidebar component filters menu items using the userMenu($module) helper function.
- Fetch: Retrieves all menu items for the current module (e.g., 'admin').
- Filter: Removes items not permitted for the user's role.
- Structure: Builds a hierarchy of parent and child items.
- Render: Outputs the HTML with active state highlighting.
Defining Menus
Menus are currently managed via the database or configuration, allowing for runtime updates without code changes.
// Example Menu Item Structure
[
'name' => 'Dashboard',
'route' => '/admin/dashboard',
'icon' => 'fa-home',
'parent_id' => 0,
'sort' => 1,
'is_active' => true,
'prefetch_enabled' => true, // Enable/disable page prefetch on hover
'permission' => 'dashboard.view' // Required permission (or null)
]Prefetch Control
Each menu item has a prefetch_enabled toggle that controls whether the page is pre-loaded when users hover over the link:
- Enabled (default): The page is fetched in the background when hovering, making navigation feel instant.
- Disabled: The link has
data-prefetch="false", skipping preload for logout links, heavy pages, or external URLs.
Configure this in Admin → RBAC → Menus using the "Prefetch" toggle on each menu item.
3. Managing Roles in Admin
Navigate to System > Roles to manage access.
- Create Role: Define a new functional role.
- Edit Role: Update name or permissions.
- Assign Role: Go to Users module and select the role for a user.
4. Permission Management
Permissions can be created and managed directly through the Admin UI at /admin/rbac/permissions.
Creating Permissions via Web GUI
- Navigate to Settings → Permissions in the sidebar
- Click "New Permission"
- Fill in the form:
- Slug: Use format
module.action(e.g.,reports.export,invoices.delete) - Name: Human-readable display name (e.g., "Export Reports")
- Module: Optional grouping for organization (e.g., "reports", "invoices")
- Slug: Use format
- Click Create Permission
Assigning Permissions to Roles
- Navigate to Settings → Roles
- Click Edit on the role you want to modify
- Check/uncheck the permissions in the permission list
- Click Save
Auto-Registration via Attributes
Permissions are automatically created in the database when you use the #[Permission] attribute on controllers:
use App\Attributes\Permission;
// Class-level: applies to all methods
#[Permission('reports.view', 'View Reports')]
class ReportController extends BaseController
{
// All methods require 'reports.view' permission
// Method-level: more specific permission
#[Permission('reports.export', 'Export Reports')]
public function export()
{
// Requires 'reports.export' (overrides class-level)
}
}PermissionFilter checks if the permission exists in the database.
If not, it automatically creates it with the slug and name from the attribute.
The check is cached for 1 hour to avoid repeated DB queries.
Slug Naming Convention
Use the format: module.action
| Slug Example | Display Name |
|---|---|
users.create | Create Users |
reports.export | Export Reports |
leave_requests.approve | Approve Leave Requests |
purchase_orders.bulk_approve | Bulk Approve Purchase Orders |
Rules:
- Use snake_case for multi-word modules/actions
- Allowed characters: letters, numbers, underscores, dashes, periods
- The module is auto-extracted from the slug (before the dot)
Benefits:
- No need to manually create permissions via GUI or seeders
- Permission slug and name are defined in one place (the code)
- Developers can add new protected routes without database access
5. Admin Routes
| Route | Description |
|---|---|
/admin/rbac/roles | List and manage roles |
/admin/rbac/permissions | List and manage permissions |
/admin/rbac/menus | Manage menu items and structure |