feat: granular permissions, export backup, user/role management
Some checks failed
Tests / PHP 8.3 (push) Has been cancelled
Tests / PHP 8.4 (push) Has been cancelled
Tests / PHP 8.5 (push) Has been cancelled

- PermissionSeeder: 29 permissions with role mapping (admin/manager/staff)
- Policies updated to use hasPermissionTo() instead of hasRole()
- ExportBackup command: JSON per-table backup with chunk processing
- UserResource: CRUD users with role assignment (admin only)
- RoleResource: CRUD roles with permission assignment (admin only)
- UserPolicy + RolePolicy: admin-only access control
- ImportCskh: detailed skip logging with color in dry-run mode
- Widgets: permission-based visibility checks
- Tests: 8/8 pass (21 assertions)
This commit is contained in:
2026-05-02 04:47:10 +00:00
parent 7c5055075b
commit 3a8db5cae6
40 changed files with 1804 additions and 440 deletions

View File

@@ -44,6 +44,11 @@ php artisan db:seed
php artisan route:list
php artisan storage:link # needed for file uploads
php artisan test # run pest tests
# Export database backup (JSON format, one file per table)
php artisan app:export-backup
php artisan app:export-backup --path=/custom/path --pretty
php artisan app:export-backup --tables=feedback,customers,products
```
## Directory Structure
@@ -222,7 +227,9 @@ Dashboard
├── Products (building-storefront, sort=1)
├── Customers (user-group, sort=2)
├── Channels (inbox-stack, sort=3)
── Tags (tag, sort=default)
── Tags (tag, sort=default)
├── Users (users, sort=5) — admin only
└── Roles (shield-check, sort=6) — admin only
```
Dashboard widgets: ResolvedTicketsWidget, AvgProcessingTimeWidget, HandlerPerformanceWidget (admin/manager only)
@@ -231,18 +238,61 @@ Dashboard widgets: ResolvedTicketsWidget, AvgProcessingTimeWidget, HandlerPerfor
Roles: `admin`, `manager`, `staff`
### Granular Permissions (Spatie Permission)
**Feedback:** `view-feedback`, `create-feedback`, `update-feedback`, `delete-feedback`, `add-interaction`, `close-ticket`, `transfer-department`
**Products:** `view-product`, `create-product`, `update-product`, `delete-product`
**Customers:** `view-customer`, `create-customer`, `update-customer`, `delete-customer`
**Contracts:** `view-contract`, `create-contract`, `update-contract`, `delete-contract`
**Channels:** `view-channel`, `create-channel`, `update-channel`, `delete-channel`
**Tags:** `view-tag`, `create-tag`, `update-tag`, `delete-tag`
**Dashboard:** `view-dashboard-widgets`, `export-data`
### Permission Matrix
| Permission | admin | manager | staff |
|-----------|-------|---------|-------|
| View products/customers/channels/tags | ✓ | ✓ | ✓ |
| Create/Update products/customers/channels | ✓ | ✓ | |
| Delete anything | ✓ | | |
| View feedbacks | ✓ | ✓ | |
| Create/Update feedbacks | ✓ | ✓ | ✓ |
| Delete feedbacks | ✓ | ✓ | ✗ |
| Add interactions | ✓ | ✓ | |
| Close ticket (status→closed) | ✓ | ✓ | ✗ (403) |
| Transfer department | ✓ | ✓ | ✗ |
| Dashboard widgets | ✓ | | ✗ |
| view-feedback | ✓ | ✓ | ✓ |
| create-feedback | ✓ | ✓ | |
| update-feedback | ✓ | | |
| delete-feedback | ✓ | ✓ | |
| add-interaction | ✓ | ✓ | ✓ |
| close-ticket | ✓ | ✓ | ✗ |
| transfer-department | ✓ | ✓ | |
| view-product | ✓ | ✓ | |
| create/update-product | ✓ | ✓ | ✗ |
| delete-product | ✓ | | ✗ |
| view-customer | ✓ | ✓ | ✓ |
| create/update-customer | ✓ | ✓ | ✗ |
| delete-customer | ✓ | ✗ | ✗ |
| view-contract | ✓ | ✓ | ✓ |
| create/update-contract | ✓ | ✓ | ✗ |
| delete-contract | ✓ | ✗ | ✗ |
| view-channel/tag | ✓ | ✓ | ✓ |
| create/update-channel/tag | ✓ | ✓ | ✗ |
| delete-channel/tag | ✓ | ✗ | ✗ |
| view-dashboard-widgets | ✓ | ✓ | ✗ |
| export-data | ✓ | ✗ | ✗ |
### Permission check patterns
```php
// In Policies
$user->hasPermissionTo('close-ticket');
$user->hasPermissionTo('view-feedback');
// In Filament
auth()->user()->hasPermissionTo('transfer-department');
auth()->user()->hasPermissionTo('view-dashboard-widgets');
// Role check (still used for admin-only guards)
$user->hasRole('admin');
```
## Filament Key Patterns (v5.6)