> ## Documentation Index
> Fetch the complete documentation index at: https://docs.laravelshopper.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Roles & Permissions

> Manage user access control programmatically with Spatie Laravel Permission.

Shopper uses [spatie/laravel-permission](https://github.com/spatie/laravel-permission) to manage roles and permissions. Every admin user has one or more roles, and each role has a set of permissions that control access to admin panel sections and actions. Since all permissions are registered on Laravel's gate, you can use Laravel's built-in `can()` function and `@can` Blade directive.

For a visual walkthrough of managing roles and permissions in the admin panel, see the User Guide pages: [Managing Staff](/v2/user-guide/administration/users) and [Roles & Permissions](/v2/user-guide/administration/roles).

## Configuration

Roles are configured in `config/shopper/admin.php`. These names are used throughout the system for authorization checks:

```php theme={null}
'roles' => [
    'admin' => 'administrator',
    'manager' => 'manager',
    'user' => 'user',
],
```

| Role            | Purpose                                           | Admin Access |
| --------------- | ------------------------------------------------- | ------------ |
| `administrator` | Full access to all admin panel features           | Yes          |
| `manager`       | Configurable access based on assigned permissions | Yes          |
| `user`          | Customer role, assigned to storefront users       | No           |

<Warning>
  Do not rename roles after they have been assigned to users. Role names are used in middleware and authorization checks throughout the system.
</Warning>

## Models

### Role

The model used is `Shopper\Models\Role`, which extends Spatie's Role model with additional fields.

| Column           | Type    | Nullable | Default | Description                                    |
| ---------------- | ------- | -------- | ------- | ---------------------------------------------- |
| `id`             | bigint  | no       | auto    | Primary key                                    |
| `name`           | string  | no       | -       | Role name in lowercase (e.g., `administrator`) |
| `guard_name`     | string  | no       | auto    | Filled automatically by Spatie                 |
| `display_name`   | string  | yes      | null    | Human-readable name                            |
| `description`    | text    | yes      | null    | Role description                               |
| `can_be_removed` | boolean | no       | true    | Whether the role can be deleted                |

The Role model provides an `isAdmin()` method:

```php theme={null}
use Shopper\Models\Role;

$role = Role::query()->where('name', 'administrator')->first();
$role->isAdmin(); // true
```

### Permission

The model used is `Shopper\Models\Permission`, which extends Spatie's Permission model with grouping support.

| Column           | Type    | Nullable | Default | Description                               |
| ---------------- | ------- | -------- | ------- | ----------------------------------------- |
| `id`             | bigint  | no       | auto    | Primary key                               |
| `name`           | string  | no       | -       | Permission name (e.g., `browse_products`) |
| `guard_name`     | string  | no       | auto    | Filled automatically by Spatie            |
| `group_name`     | string  | yes      | null    | Permission group for organization         |
| `display_name`   | string  | yes      | null    | Human-readable name                       |
| `description`    | text    | yes      | null    | Permission description                    |
| `can_be_removed` | boolean | no       | true    | Whether the permission can be deleted     |

### Permission Groups

Permissions are organized into groups for display in the admin panel:

```php theme={null}
use Shopper\Models\Permission;

Permission::groups();
```

This returns the built-in groups: `system`, `brands`, `categories`, `collections`, `products`, `customers`, `orders`, `discounts`.

### System Permissions

The `system` group contains the global capabilities that gate everything outside the resource permissions:

| Permission       | Description                                                                                                                           |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `access_setting` | Required for any write action on settings surfaces (PaymentMethods, Currencies, Carriers, Locations, Legal, Team, Roles, Permissions) |
| `view_users`     | Required to view the customers list and customer detail pages                                                                         |

<Note>
  Since v2.8, `access_setting` is the only permission that grants write access to PaymentMethods, Currencies, Carriers, Team management, and Role/Permission management. Roles that previously relied on `view_users` to mutate these surfaces must be granted `access_setting` to keep working.
</Note>

### Generating Permissions

The `Permission::generate()` method creates five permissions for a given resource (browse, read, edit, add, delete):

```php theme={null}
Permission::generate('brands');
// Creates: browse_brands, read_brands, add_brands, edit_brands, delete_brands

Permission::generate('tags', 'products');
// Creates: browse_tags, read_tags, add_tags, edit_tags, delete_tags (in the "products" group)
```

## Working with Roles

### Creating Roles

To create a new role programmatically:

```php theme={null}
use Shopper\Models\Role;

$role = Role::query()->create([
    'name' => 'warehouse-manager',
    'display_name' => 'Warehouse Manager',
    'description' => 'Manages inventory locations and stock levels.',
]);

$role->givePermissionTo([
    'browse_inventories',
    'read_inventories',
    'edit_inventories',
    'browse_products',
    'read_products',
]);
```

### Assigning Roles

Assign a role to a user:

```php theme={null}
$user->assignRole('warehouse-manager');

$user->assignRole(config('shopper.admin.roles.admin'));
```

### Checking Roles

The `InteractsWithShopper` trait on the User model provides role checking methods:

```php theme={null}
$user->isAdmin();    // true if user has the administrator role
$user->isManager();  // true if user has the manager role

$user->hasRole('warehouse-manager');
```

## Working with Permissions

### Checking Permissions

Use Laravel's standard authorization:

```php theme={null}
$user->hasPermissionTo('browse_products');

$user->can('edit_products');
```

In Blade templates:

```blade theme={null}
@can('add_products')
    <a href="/admin/products/create">Add Product</a>
@endcan
```

In Livewire components, Shopper uses the `authorize()` method:

```php theme={null}
public function mount(): void
{
    $this->authorize('browse_products');
}
```

### Creating Custom Permissions

To add a custom permission and assign it to a role:

```php theme={null}
use Shopper\Models\Permission;
use Shopper\Models\Role;

$permission = Permission::query()->create([
    'name' => 'view_analytics',
    'group_name' => 'system',
    'display_name' => 'View Analytics',
    'description' => 'Access the analytics dashboard.',
]);

$role = Role::query()->where('name', 'manager')->first();
$role->givePermissionTo($permission);
```

Custom permissions without a recognized group appear in a "Custom permissions" section in the admin panel.

### Revoking Permissions

To remove a permission from a role:

```php theme={null}
$role->revokePermissionTo('delete_products');
```

## Admin User Creation

You can create an admin user from the command line:

```bash theme={null}
php artisan shopper:user
```

Or programmatically:

```php theme={null}
use App\Models\User;
use Illuminate\Support\Facades\Hash;

$admin = User::query()->create([
    'first_name' => 'John',
    'last_name' => 'Doe',
    'email' => 'admin@example.com',
    'password' => Hash::make('password'),
    'email_verified_at' => now(),
]);

$admin->assignRole(config('shopper.admin.roles.admin'));
```

## Components

To customize the roles and permissions admin UI:

```bash theme={null}
php artisan shopper:component:publish setting
```

The relevant components in `config/shopper/components/setting.php`:

```php theme={null}
use Shopper\Livewire;

return [
    'pages' => [
        'team-index' => Livewire\Pages\Settings\Team\Index::class,
        'team-roles' => Livewire\Pages\Settings\Team\RolePermission::class,
    ],
    'components' => [
        'settings.team.permissions' => Livewire\Components\Settings\Team\Permissions::class,
        'settings.team.users' => Livewire\Components\Settings\Team\UsersRole::class,
        'slide-overs.create-team-member' => Livewire\SlideOvers\CreateTeamMember::class,
    ],
];
```
