Skip to main content

StoreFlowStateRequest

Form request class for validating FlowState creation data. This request handles validation for creating new workflow states with multi-language support, status validation, and visual configuration.

Namespace

JobMetric\Flow\Http\Requests\FlowState\StoreFlowStateRequest

Overview

The StoreFlowStateRequest validates incoming data when creating a new FlowState entity. It ensures:

  • Required fields are present
  • Flow ID exists and is valid
  • Multi-language translations are valid
  • Status value is valid for the flow's driver
  • Visual configuration (color, icon, position) is correct
  • Translation uniqueness within the flow

Validation Rules

Required Fields

FieldRuleDescription
flow_idrequired|integer|exists:flows,idID of the parent flow
translationrequired|arrayMulti-language translation data
translation.{locale}required|arrayTranslation data for each active locale
translation.{locale}.namerequired|stringState name in each locale (must be unique within flow)

Optional Fields

FieldRuleDescription
statuspresent|nullable|CheckStatusInDriverRuleStatus value (validated against flow's driver)
configsometimes|arrayCustom configuration array
colorsometimes|nullable|hex_colorHex color code for visualization
iconsometimes|nullable|stringIcon identifier
positionsometimes|array|required_array_keys:x,yPosition coordinates
position.xnumericX coordinate
position.ynumericY coordinate
is_terminalsometimes|booleanWhether this is a terminal/end state
translation.{locale}.descriptionnullable|stringOptional description in each locale

Normalization

The request includes a static normalize() method that applies default values:

$normalized = StoreFlowStateRequest::normalize($data, ['flow_id' => 1]);

// Applies defaults:
// - is_terminal: false (if not provided)
// - config: [] (if not provided or invalid)
// - color: Based on is_terminal (end/middle state default)
// - icon: Based on is_terminal (end/middle state default)
// - position: Based on is_terminal (end/middle state default)

Status Validation

The status field uses CheckStatusInDriverRule to validate that the status value is valid for the flow's driver:

// If flow uses OrderStatus enum
// Valid status values are checked against enum values
'status' => 'pending', // ✅ Valid if OrderStatus::PENDING exists
'status' => 'invalid', // ❌ Invalid if not in enum

Translation Validation

Name Uniqueness

The translation.{locale}.name field is validated for uniqueness within the same flow:

  • Checks if a state with the same name already exists in the same flow and locale
  • Prevents duplicate state names within a flow
  • Trims whitespace before validation

Usage Examples

Basic State Creation

use JobMetric\Flow\Http\Requests\FlowState\StoreFlowStateRequest;
use JobMetric\Flow\Facades\FlowState;

public function store(StoreFlowStateRequest $request)
{
$validated = $request->validated();

$state = FlowState::store($validated['flow_id'], $validated);

return response()->json($state, 201);
}

Complete Request Data

$requestData = [
'flow_id' => 1,
'translation' => [
'en' => [
'name' => 'Pending Review',
'description' => 'Order is pending review',
],
'fa' => [
'name' => 'در انتظار بررسی',
'description' => 'سفارش در انتظار بررسی است',
],
],
'status' => 'pending',
'is_terminal' => false,
'color' => '#3B82F6',
'icon' => 'fas fa-clock',
'position' => [
'x' => 100,
'y' => 200,
],
'config' => [
'notify_user' => true,
'auto_advance' => false,
],
];

Minimal Request Data

$requestData = [
'flow_id' => 1,
'translation' => [
'en' => ['name' => 'Processing'],
],
];

Terminal State

$requestData = [
'flow_id' => 1,
'translation' => [
'en' => ['name' => 'Completed'],
],
'is_terminal' => true,
'status' => 'completed',
];

With Status Validation

// If flow uses OrderStatus enum with values: pending, processing, completed
$requestData = [
'flow_id' => 1,
'translation' => [
'en' => ['name' => 'Processing'],
],
'status' => 'processing', // ✅ Valid
// 'status' => 'invalid', // ❌ Invalid
];

Context Management

The request supports external context injection via setContext():

$request = new StoreFlowStateRequest();
$request->setContext(['flow_id' => 123]);

This allows validation to use the flow_id from context if not provided in input.

Static Methods

normalize()

Normalizes input data with safe defaults:

$data = [
'flow_id' => 1,
'translation' => ['en' => ['name' => 'State']],
'is_terminal' => true,
];

$context = ['flow_id' => 1];

$normalized = StoreFlowStateRequest::normalize($data, $context);

// Returns:
// [
// 'flow_id' => 1,
// 'translation' => [...],
// 'is_terminal' => true,
// 'config' => [],
// 'color' => config('workflow.state.end.color'),
// 'icon' => config('workflow.state.end.icon'),
// 'position' => ['x' => ..., 'y' => ...],
// ]

rulesFor()

Provides programmatic validation:

$input = [
'flow_id' => 1,
'translation' => ['en' => ['name' => 'State']],
];

$context = ['flow_id' => 1];

$rules = StoreFlowStateRequest::rulesFor($input, $context);

Error Handling

Validation Errors

{
"message": "The given data was invalid.",
"errors": {
"flow_id": [
"The selected flow id is invalid."
],
"translation.en.name": [
"A state with this name already exists in this flow."
],
"status": [
"The status value is not valid for this flow's driver."
]
}
}

Best Practices

  1. Always Provide Flow ID: Ensure flow_id is valid and exists

    // ✅ Good
    'flow_id' => 1, // Valid flow ID
  2. Use Valid Status Values: Ensure status matches flow's driver enum

    // ✅ Good - Check enum values first
    $validStatuses = OrderStatus::values();
    'status' => $validStatuses[0],
  3. Set Appropriate Visuals: Use meaningful colors and icons

    // ✅ Good
    'color' => '#3B82F6', // Blue for processing
    'icon' => 'fas fa-cog',
  4. Normalize Before Validation: Use normalize() for consistent data

    $normalized = StoreFlowStateRequest::normalize($data, $context);
    $request->merge($normalized);