Authorization
The CPR backend uses Spatie Laravel Permission for role-based access control (RBAC).
Roles
There are 7 predefined roles in the system:
| Role | Description | Key Access Areas |
|---|---|---|
admin | Full system access | Everything + admin.access |
doctor | Patient care provider | Patients, consultations, medical records, prescriptions |
nurse | Clinical support | Patients, vitals, basic medical records |
receptionist | Front desk | Registration, appointments, queue management |
pharmacist | Medication management | Pharmacy, dispensing, inventory |
lab_technician | Lab operations | Laboratory tests, processing |
billing_staff | Financial operations | Billing, transactions, accounts |
Permission Naming Convention
Permissions follow the pattern: {module}.{action}
Available Modules and Actions
| Module | Actions |
|---|---|
users | create, read, update, delete |
roles | create, read, update, delete |
branches | create, read, update, delete |
patients | create, read, update, delete |
appointments | create, read, update, delete |
medical-records | create, read, update, delete |
consultations | create, read, update, delete |
laboratory | create, read, update, delete |
pharmacy | create, read, update, delete |
billing | create, read, update, delete |
reports | read |
settings | read, update |
vitals | create, read, update, delete |
inventory | create, read, update, delete |
admin | access |
How Authorization Is Enforced
Route-Level (Middleware)
Admin-only routes use the permission middleware:
php
// routes/api.php
Route::middleware(['auth:sanctum', 'permission:admin.access'])->group(function () {
Route::apiResource('branches', BranchController::class);
});Branch Isolation
The EnsureBranchContext middleware enforces that users can only access data from branches they're assigned to:
php
// Middleware resolves branch from (in priority order):
// 1. X-Branch-Id header
// 2. branch_id query parameter
// 3. User's default_branch_id
// Returns 400 if no branch context provided
// Returns 403 if user doesn't have access to the branchIn Controllers/Services
You can check permissions programmatically:
php
// Check if user has a permission
$user->hasPermissionTo('patients.create');
// Check if user has a role
$user->hasRole('admin');
// Check if user has any of the given roles
$user->hasAnyRole(['admin', 'doctor']);Branch Access
Users are assigned to branches via the branch_users pivot table. A user can:
- Work at multiple branches (many-to-many)
- Have a default branch (
default_branch_idon the user) - Switch branches via
POST /api/v1/auth/switch-branch
The EnsureBranchContext middleware validates that the authenticated user has access to the requested branch before allowing the request to proceed.
Adding New Permissions
- Add the permission to
RoleSeeder:php'new-module' => ['create', 'read', 'update', 'delete'], - Assign it to the appropriate roles in the same seeder
- Run
php artisan db:seed --class=RoleSeeder - Use the permission in routes or code:php
Route::middleware('permission:new-module.create')->post('/new-module', ...);
Guard Configuration
All permissions use the web guard (configured in Spatie's config):
php
// config/auth.php
'defaults' => [
'guard' => 'web',
],Sanctum authenticates the token and then uses the web guard for permission checks.