adachsoft / workflow-definition-repository-json
JSON file-based implementations of WorkflowDefinitionRepositoryInterface and WorkflowRunRepositoryInterface.
Package info
gitlab.com/a.adach/workflow-definition-repository-json
pkg:composer/adachsoft/workflow-definition-repository-json
Requires
- php: ^8.3
- adachsoft/workflow: ^6.0
Requires (Dev)
- adachsoft/php-code-style: ^0.7.1
- friendsofphp/php-cs-fixer: ^3.68
- phpstan/phpstan: ^2.1
- phpunit/phpunit: ^12
- rector/rector: ^2.3
- symplify/phpstan-rules: ^14.9
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
A JSON file-based implementation of WorkflowDefinitionRepositoryInterface from adachsoft/workflow. Each workflow definition is stored in a separate JSON file.
Requirements
- PHP 8.3 or later
adachsoft/workflow^6.0
Installation
composer require adachsoft/workflow-definition-repository-json
Usage
<?php
declare(strict_types=1);
use AdachSoft\WorkflowDefinitionRepositoryJson\JsonFileWorkflowDefinitionRepository;
use AdachSoft\WorkflowDefinitionRepositoryJson\Mapper\WorkflowDefinitionJsonMapper;
$repository = new JsonFileWorkflowDefinitionRepository(
__DIR__ . '/var/workflows',
new WorkflowDefinitionJsonMapper(),
);
$definition = $repository->get('invoice');
$repository->save($definition);
$definitions = $repository->list();
get() returns a WorkflowDefinitionVo for the requested workflow ID and throws WorkflowNotFoundException when its JSON file does not exist. save() writes a workflow definition to <workflows-directory>/<workflow-id>.json, creating the directory when needed. list() returns workflow definitions keyed by ID in sorted order; it returns an empty array if the directory does not exist.
Workflow run repository
Workflow execution state can also be stored as one JSON file per run:
<?php
declare(strict_types=1);
use AdachSoft\WorkflowDefinitionRepositoryJson\JsonFileWorkflowRunRepository;
use AdachSoft\WorkflowDefinitionRepositoryJson\Mapper\WorkflowRunJsonMapper;
$runRepository = new JsonFileWorkflowRunRepository(
__DIR__ . '/var/runs',
new WorkflowRunJsonMapper(),
);
$run = $runRepository->get('run_6af54054929692.21062525');
$runRepository->save($run);
save() creates the runs directory when needed and atomically writes <runs-directory>/<run-id>.json by renaming a temporary file in that directory. Run IDs may contain only letters, digits, dots, underscores, and hyphens, and may not contain ... get() throws WorkflowNotFoundException when the run file does not exist. Invalid JSON and invalid run data raise a readable RuntimeException containing the file name. Payload and context values support scalars, null, and nested arrays; nested PayloadVo values are stored as arrays, while other objects are rejected with WorkflowException.
A run file stores the identifiers, current step, input and output payloads, completion flag, debug status, context, and latest debug step execution. Debug status is serialized by enum case name:
{
"runId": "run_6af54054929692.21062525",
"workflowId": "invoice",
"currentStep": "calculate_total",
"input": {
"customer": {
"name": "Żaneta"
}
},
"output": {
"total": 42
},
"finished": false,
"debugState": {
"status": "PAUSED"
},
"context": {
"locale": "pl-PL"
},
"lastStepExecution": {
"stepName": "calculate_total",
"input": {
"subtotal": 40
},
"output": {
"total": 42
},
"branch": "success"
}
}
An empty payload is restored as an empty PayloadVo.
JSON format
A workflow file contains a steps object keyed by step name. It may also contain input_schema and output_schema objects:
{
"input_schema": {
"customer_id": {
"type": "string",
"required": true,
"description": "Customer identifier"
}
},
"output_schema": {
"status": {
"type": "string",
"required": true,
"description": "Batch status"
},
"images": {
"type": "array",
"required": true,
"description": "Saved images"
}
},
"steps": {
"finish": {
"type": "finish",
"config": {
"output": {
"status": "done",
"images": []
}
}
}
}
}
The mapper converts workflow steps and nested JSON objects to workflow payload values, and maps schema declarations to workflow schema value objects. If input_schema is omitted, it is treated as empty; saving a workflow writes the input_schema field. If output_schema is omitted, no workflow output contract is declared and saving omits the key. An explicit empty output schema is serialized as [], declares an empty output contract, and is preserved on save and load; it is distinct from an omitted schema. Output schema fields use the same format as input schema fields. Invalid schema field definitions are rejected by the schema contract in adachsoft/workflow. Malformed JSON or an invalid top-level workflow structure raises RuntimeException.
Tests
Run the PHPUnit suite with:
vendor/bin/phpunit tests