Skip to content

Permission Management CRUD API (RBAC Phase 4) #137

@kevalyq

Description

@kevalyq

🎯 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)
  • Create UpdatePermissionRequest.php
    • Validate description only (name immutable)

Policy

  • Create PermissionManagementPolicy.php
    • viewAny() → checks permissions.read
    • view() → checks permissions.read
    • create() → checks permissions.create
    • update() → checks permissions.update
    • delete() → checks permissions.delete
  • Register policy in AppServiceProvider

Routes

  • Add 5 RESTful routes in routes/api.php
  • All routes under auth:sanctum middleware

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.action naming 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 RoleManagementController patterns
  • 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

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status

    ✅ Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions