Skip to main content

StoreRoleRequest

Form request for validating role creation payloads. Used by the Role service via dto($data, StoreRoleRequest::class) inside changeFieldStore.

Namespace

JobMetric\Rolix\Http\Requests\Role\StoreRoleRequest

Overview

StoreRoleRequest ensures:

  • Required fields (name) are present
  • Optional hierarchy, permissions, and rule drivers are well-typed
  • Cross-field checks for role type, parent, permissions, unique super role, and registered rule drivers

authorize() always returns true (authorization is expected at the application/controller layer).

Validation Rules

FieldRuleDescription
typesometimes|nullable|string|max:255Role type key; defaults to system in the service when omitted
parent_idnullable|integer|exists:{rolix.tables.role},idParent role id (same type, hierarchical types only)
namerequired|string|max:255Display name
descriptionnullable|stringOptional description
allowsometimes|arrayAllowed permission strings
allow.*stringEach allow entry
denysometimes|arrayDenied permission strings
deny.*stringEach deny entry
is_defaultsometimes|booleanDefault role for the type
is_supersometimes|booleanSuper role (bypasses allow/deny lists)
orderingsometimes|integer|min:0Sort order
rulessometimes|arrayRole rule definitions
rules.*.driverrequired_with:rules|stringEvaluator name()
rules.*.payloadnullable|arrayDriver-specific payload

Table name for exists comes from config('rolix.tables.role').

Attributes

Translated labels via rolix::base.fields.* for: type, parent_id, name, description, allow, deny, is_default, is_super, ordering, rules.

Cross-Field Validation (withValidator)

Runs after basic rules. Early-returns if the resolved type is unknown.

1. Role type

  • Resolved type: $data['type'] ?? 'system'
  • Must exist in RoleTypeRegistry::has($type)
  • Error key: typerolix::base.exceptions.role_type_not_found

2. Parent (validateParent)

When parent_id is set:

CheckError keyTranslation
Type is not hierarchical (hierarchical option false)parent_idrolix::base.validation.role.parent_not_allowed
Parent exists but parent->type !== $typeparent_idrolix::base.validation.role.parent_type_mismatch

3. Permissions (validatePermissions)

Skipped when is_super is truthy.

Otherwise, if Permission::getFlatPermissions(null, $model) is non-empty for the type’s model, each allow / deny entry must be in that list.

CheckError keyTranslation
Unknown permission stringallow or denyrolix::base.validation.role.permission_not_registered

4. Rule drivers (validateRuleDrivers)

Each rules.$index.driver must satisfy RuleEvaluatorRegistry::has($driver).

CheckError keyTranslation
Unknown / invalid driverrules.$index.driverrolix::base.validation.role.rule_driver_invalid

5. Unique super (validateUniqueSuper)

When is_super is truthy, no other role with the same type may already have is_super = true.

CheckError keyTranslation
Super already exists for typeis_superrolix::base.validation.role.is_super_already_exists

Usage Examples

Controller

use JobMetric\Rolix\Facades\Role;
use JobMetric\Rolix\Http\Requests\Role\StoreRoleRequest;
use JobMetric\Rolix\Http\Resources\RoleResource;

public function store(StoreRoleRequest $request)
{
$response = Role::store($request->validated());

return RoleResource::make($response->getData())
->response()
->setStatusCode(201);
}

Via Role service / dto

use JobMetric\Rolix\Facades\Role;

Role::store([
'type' => 'system',
'name' => 'Editor',
'description' => 'Can edit content',
'allow' => ['posts.view', 'posts.update'],
'deny' => ['posts.delete'],
'is_default' => false,
'is_super' => false,
'ordering' => 10,
'parent_id' => null,
'rules' => [
[
'driver' => 'env',
'payload' => ['environments' => 'local,staging'],
],
],
]);

Minimal payload

Role::store([
'name' => 'Viewer',
]);
// type defaults to "system" in Role::changeFieldStore