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

# Policies

> Create custom authorization policies for the Unleash Commerce Admin panel

## Extending Existing Policies

To customize authorization logic, extend or replace core policies.

### 1. Create the Contract

Define a policy contract interface:

```php theme={null}
namespace App\Contracts\Admin\Policies;

interface ProductPolicyContract
{
    public function view(AdminUser $user, Product $product): bool|null;
    public function create(AdminUser $user): bool|null;
    public function update(AdminUser $user, Product $product): bool|null;
    public function delete(AdminUser $user, Product $product): bool|null;
}
```

### 2. Create the Custom Policy

Implement your custom policy:

```php theme={null}
namespace App\Policies;

use App\Models\AdminUser;
use Esign\UnleashCommerce\Core\Models\Product;

class ProductPolicy
{
    public function view(AdminUser $user, Product $product): bool|null
    {
        // Allow admins to view all products
        if ($user->is_admin) {
            return true;
        }

        // Super admin check (return null to let gate decide)
        return null;
    }

    public function create(AdminUser $user): bool|null
    {
        // Only admins can create products
        return $user->is_admin ? true : null;
    }

    public function update(AdminUser $user, Product $product): bool|null
    {
        // Own products or admin
        if ($user->is_admin || $product->created_by === $user->getKey()) {
            return true;
        }

        return null;
    }

    public function delete(AdminUser $user, Product $product): bool|null
    {
        // Only admins can delete
        if ($user->is_admin) {
            return true;
        }

        // Deny for everyone else (even super admins)
        return false;
    }
}
```

## Registering Custom Policies

Register your policies using the `FilamentPolicyManifest`:

```php theme={null}
use Esign\UnleashCommerce\Admin\Support\FilamentPolicyManifest;
use Esign\UnleashCommerce\Admin\Contracts\Filament\Policies\ProductPolicy as ProductPolicyContract;

public function boot()
{
    $manifest = $this->app->make(FilamentPolicyManifest::class);
    $manifest->replace(
        ProductPolicyContract::class,
        CustomProductPolicy::class
    );
}
```

## Super Admin Support

Policies support super admin functionality:

* Returning `true` grants permission
* Returning `null` lets the super admin check decide
* Returning `false` denies permission (even for super admins)

```php theme={null}
public function delete(AdminUser $user, Product $product): bool|null
{
    // Allow super admins
    if ($user->is_super_admin) {
        return true;
    }

    // Check custom logic
    if ($user->can_delete_products) {
        return true;
    }

    // Let super admin check take over or deny
    return null;
}
```

## Using Policies in Filament

Filament automatically uses your policies to control visibility of actions:

```php theme={null}
// Actions are automatically hidden based on policies
Tables\Actions\EditAction::make(),
Tables\Actions\DeleteAction::make(),
```

## Testing Custom Policies

Test your policies:

```php theme={null}
public function test_admin_can_delete_product()
{
    // Arrange
    $admin = AdminUser::factory()->admin()->create();
    $product = Product::factory()->create();
    $policy = new ProductPolicy();

    // Act
    $result = $policy->delete($admin, $product);

    // Assert
    $this->assertTrue($result);
}

public function test_non_admin_cannot_delete()
{
    // Arrange
    $user = AdminUser::factory()->create();
    $product = Product::factory()->create();
    $policy = new ProductPolicy();

    // Act
    $result = $policy->delete($user, $product);

    // Assert
    $this->assertNull($result);
}
```

For more information, see the [Policies guide](../policies).
