-
Notifications
You must be signed in to change notification settings - Fork 0
Description
🎯 Objective
Implement RESTful Permission Management CRUD API for RBAC Phase 4 (#108).
📋 Scope
Permission CRUD Endpoints
1. List Permissions
GET /api/v1/permissions
- Group by resource (employees, shifts, roles, etc.)
- Include assigned roles count
- Authorization: Admin only (
permissions.read)
2. Create Permission
POST /api/v1/permissions
- Validate: name format
resource.action(e.g.,employees.read) - Validate: name unique
- Optional: description field
- Authorization: Admin only (
permissions.create)
3. Get Permission Details
GET /api/v1/permissions/{id}
- Include roles that have this permission
- Include users with direct assignment (if implemented)
- Authorization: Admin only (
permissions.read)
4. Update Permission
PATCH /api/v1/permissions/{id}
- Update description only (name immutable for security)
- Authorization: Admin only (
permissions.update)
5. Delete Permission
DELETE /api/v1/permissions/{id}
- Block if assigned to any role OR user directly
- Return 422 with assignment count if blocked
- Authorization: Admin only (
permissions.delete)
🏗️ Implementation Checklist
Controller
- Create
PermissionManagementController.php - Implement
index()- List permissions grouped by resource - Implement
store()- Create permission with validation - Implement
show()- Get permission details - Implement
update()- Update description only - Implement
destroy()- Delete with assignment check
Form Requests
- Create
CreatePermissionRequest.php- Validate name format:
resource.action - Validate name uniqueness
- Validate description (nullable, max 1000)
- Validate name format:
- Create
UpdatePermissionRequest.php- Validate description only (name immutable)
Policy
- Create
PermissionManagementPolicy.phpviewAny()→ checkspermissions.readview()→ checkspermissions.readcreate()→ checkspermissions.createupdate()→ checkspermissions.updatedelete()→ checkspermissions.delete
- Register policy in
AppServiceProvider
Routes
- Add 5 RESTful routes in
routes/api.php - All routes under
auth:sanctummiddleware
Tests
- Create
PermissionManagementApiTest.php - 8 comprehensive tests covering:
- List permissions (grouped by resource)
- Create permission (validation: format, uniqueness)
- Get permission details (with assigned roles)
- Update permission (description only)
- Delete permission (blocked if assigned)
- 401 Unauthorized (all endpoints)
- 403 Forbidden (missing permissions)
- 422 Validation errors
Quality Gates
- PHPStan Level Max: 0 errors
- Laravel Pint: Clean (
--test --dirty) - All tests pass locally
- REUSE compliance
✅ Acceptance Criteria
- 5 RESTful endpoints functional (
index,store,show,update,destroy) - Permissions follow
resource.actionnaming convention - Permission name is immutable after creation (security)
- Cannot delete permission if assigned to roles or users
- Response grouped by resource on
index() - Policy-based authorization on all methods
- 8 comprehensive tests (all passing)
- PHPStan + Pint clean
📊 Response Structure Examples
List Permissions (Grouped):
{
"data": {
"employees": [
{"id": 1, "name": "employees.read", "description": "View employees", "roles_count": 3},
{"id": 2, "name": "employees.create", "description": "Create employees", "roles_count": 2}
],
"shifts": [
{"id": 5, "name": "shifts.read", "description": "View shifts", "roles_count": 4}
]
}
}Delete Blocked (422):
{
"message": "Cannot delete permission while assigned to roles or users",
"assigned_to_roles": 3,
"assigned_to_users": 1
}🔗 Related Issues
Part of: #108 - RBAC Phase 4
Depends on: PR #131 (Role Management API merged first)
Follows pattern from: #131 (Role Management implementation)
⏱️ Effort Estimate
Time: 3-4 hours
Breakdown:
- Controller + Form Requests: 1.5h
- Policy + Routes: 0.5h
- Tests: 1.5h
- Quality gates: 0.5h
Complexity: Low (mirrors Role Management API structure)
🎯 Implementation Notes
Permission Naming Convention
Format: resource.action
Resources:
employees,shifts,work_instructions,roles,permissions,works_council,reports
Common Actions:
read,create,update,delete,export- Special:
read_salary,read_all_branches,publish,approve_as_br
Wildcard: * (all actions on resource)
Why Name is Immutable
Changing permission names would break:
- Authorization checks in code (
$user->can('employees.read')) - Policy references
- Frontend permission checks
- API contracts
Solution: Update description for clarification, create new permission if semantics change.
📝 Review Checklist
Before creating PR:
- Compare with
RoleManagementControllerpatterns - Test assertions match project standards
- Policy registration in
AppServiceProvider - PHPDoc annotations complete
- No magic numbers (extract to constants)
- Guard name explicit (
sanctum) in tests
Created: 2025-11-09
Category: Feature / RBAC
Size: ~400-500 LOC (excluding tests)
Risk: Low (follows established pattern from #131)
Metadata
Metadata
Assignees
Labels
Type
Projects
Status