Skip to content

Commit d9bfa4c

Browse files
committed
wip
1 parent 6701724 commit d9bfa4c

12 files changed

+894
-31
lines changed

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,13 @@
88

99
Create powerful business workflows with simple, maintainable code.
1010

11+
> ⚠️ **WARNING: DEVELOPMENT STATUS**⚠️
12+
>
13+
> This package is currently under active development and is **NOT READY FOR PRODUCTION USE**.
14+
>
15+
> Features may be incomplete, APIs might change, and there could be breaking changes. Use at your own risk in development environments only.
16+
17+
1118
## ✨ Why Choose This Workflow Engine?
1219

1320
- 🎨 **Simple & Intuitive** - Array-based workflow definitions and fluent WorkflowBuilder API

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
"illuminate/database": "^10.0||^11.0||^12.0",
2828
"illuminate/events": "^10.0||^11.0||^12.0",
2929
"illuminate/support": "^10.0||^11.0||^12.0",
30-
"solution-forest/workflow-engine-core": "^0.0.1-alpha"
30+
"solution-forest/workflow-engine-core": "^0.0.2-alpha"
3131
},
3232
"conflict": {
3333
"laravel/framework": "<11.0.0"

docs/advanced-features.md

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -131,10 +131,8 @@ Configure automatic retries for unreliable operations:
131131

132132
```php
133133
$workflow = WorkflowBuilder::create('robust-workflow')
134-
->step('api-call', ApiCallAction::class)
135-
->retry(attempts: 3, backoff: 'exponential')
136-
->step('database-operation', DatabaseAction::class)
137-
->retry(attempts: 5, backoff: 'linear')
134+
->addStep('api-call', ApiCallAction::class, [], null, 3) // 3 retry attempts
135+
->addStep('database-operation', DatabaseAction::class, [], null, 5) // 5 retry attempts
138136
->build();
139137
```
140138

@@ -147,7 +145,7 @@ $workflow = WorkflowBuilder::create('robust-workflow')
147145
```php
148146
// Custom backoff function
149147
$workflow = WorkflowBuilder::create('custom-retry')
150-
->step('operation', MyAction::class)
148+
->addStep('operation', MyAction::class, [], null, 3) // Basic retry with 3 attempts
151149
->retry(attempts: 3, backoff: function($attempt) {
152150
return $attempt * 1000; // 1s, 2s, 3s
153151
})

docs/api-reference.md

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -14,32 +14,29 @@ Creates a new workflow builder instance.
1414
$builder = WorkflowBuilder::create('my-workflow');
1515
```
1616

17-
#### `step(string $id, string $actionClass): self`
17+
#### `addStep(string $id, string $actionClass, array $config = [], ?int $timeout = null, int $retryAttempts = 0): self`
1818

1919
Adds a custom action step to the workflow.
2020

2121
```php
22-
$builder->step('process-payment', ProcessPaymentAction::class);
22+
$builder->addStep('process-payment', ProcessPaymentAction::class);
23+
$builder->addStep('process-payment', ProcessPaymentAction::class, ['currency' => 'USD'], 30, 3);
2324
```
2425

25-
#### `email(string $template, array $options = []): self`
26+
#### `email(string $template, string $to, string $subject, array $data = []): self`
2627

2728
Adds an email step to the workflow.
2829

2930
```php
30-
$builder->email('welcome-email', [
31-
'to' => '{{ user.email }}',
32-
'subject' => 'Welcome {{ user.name }}!',
33-
'data' => ['welcome_bonus' => 100]
34-
]);
31+
$builder->email('welcome-email', '{{ user.email }}', 'Welcome {{ user.name }}!', ['welcome_bonus' => 100]);
3532
```
3633

37-
#### `http(string $method, string $url, array $data = []): self`
34+
#### `http(string $url, string $method = 'GET', array $data = [], array $headers = []): self`
3835

3936
Adds an HTTP request step to the workflow.
4037

4138
```php
42-
$builder->http('POST', 'https://api.example.com/webhooks', [
39+
$builder->http('https://api.example.com/webhooks', 'POST', [
4340
'event' => 'user_registered',
4441
'user_id' => '{{ user.id }}'
4542
]);
@@ -61,26 +58,24 @@ Adds conditional logic to the workflow.
6158

6259
```php
6360
$builder->when('user.age >= 18', function($builder) {
64-
$builder->step('verify-identity', VerifyIdentityAction::class);
61+
$builder->addStep('verify-identity', VerifyIdentityAction::class);
6562
});
6663
```
6764

68-
#### `retry(int $attempts, string $backoff = 'linear'): self`
65+
#### `startWith(string $actionClass, array $config = [], ?int $timeout = null, int $retryAttempts = 0): self`
6966

70-
Configures retry behavior for the previous step.
67+
Adds the first step in a workflow (syntactic sugar for better readability).
7168

7269
```php
73-
$builder->step('api-call', ApiCallAction::class)
74-
->retry(attempts: 3, backoff: 'exponential');
70+
$builder->startWith(ValidateInputAction::class, ['strict' => true]);
7571
```
7672

77-
#### `timeout(int $seconds = null, int $minutes = null, int $hours = null): self`
73+
#### `then(string $actionClass, array $config = [], ?int $timeout = null, int $retryAttempts = 0): self`
7874

79-
Sets a timeout for the previous step.
75+
Adds a sequential step (syntactic sugar for better readability).
8076

8177
```php
82-
$builder->step('long-operation', LongOperationAction::class)
83-
->timeout(minutes: 5);
78+
$builder->then(ProcessDataAction::class)->then(SaveResultAction::class);
8479
```
8580

8681
#### `build(): WorkflowDefinition`

docs/getting-started.md

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,10 @@ use App\Actions\CreateUserProfileAction;
5353

5454
// Create the workflow
5555
$registrationWorkflow = WorkflowBuilder::create('user-registration')
56-
->step('create-profile', CreateUserProfileAction::class)
57-
->email('welcome-email', to: '{{ user.email }}', subject: 'Welcome!')
56+
->addStep('create-profile', CreateUserProfileAction::class)
57+
->email('welcome-email', '{{ user.email }}', 'Welcome!')
5858
->delay(hours: 24)
59-
->email('tips-email', to: '{{ user.email }}', subject: 'Getting Started Tips')
59+
->email('tips-email', '{{ user.email }}', 'Getting Started Tips')
6060
->build();
6161

6262
// Start the workflow
@@ -155,9 +155,7 @@ The workflow engine automatically handles errors and provides retry mechanisms:
155155

156156
```php
157157
$workflow = WorkflowBuilder::create('robust-workflow')
158-
->step('risky-operation', RiskyAction::class)
159-
->retry(attempts: 3, backoff: 'exponential')
160-
->timeout(seconds: 30)
158+
->addStep('risky-operation', RiskyAction::class, [], 30, 3) // timeout: 30s, retry: 3 attempts
161159
->build();
162160
```
163161

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<?php
2+
3+
namespace SolutionForest\WorkflowEngine\Laravel\Tests\Support\TestActions;
4+
5+
use SolutionForest\WorkflowEngine\Attributes\Retry;
6+
use SolutionForest\WorkflowEngine\Attributes\Timeout;
7+
use SolutionForest\WorkflowEngine\Attributes\WorkflowStep;
8+
use SolutionForest\WorkflowEngine\Contracts\WorkflowAction;
9+
use SolutionForest\WorkflowEngine\Core\ActionResult;
10+
use SolutionForest\WorkflowEngine\Core\WorkflowContext;
11+
12+
#[WorkflowStep(
13+
id: 'create_profile',
14+
name: 'Create User Profile',
15+
description: 'Creates a new user profile in the database'
16+
)]
17+
#[Timeout(seconds: 30)]
18+
#[Retry(attempts: 3, backoff: 'exponential')]
19+
class CreateUserProfileAction implements WorkflowAction
20+
{
21+
public function execute(WorkflowContext $context): ActionResult
22+
{
23+
$userData = $context->getData('user') ?? [];
24+
25+
// Mock user profile creation
26+
$profile = [
27+
'id' => rand(1000, 9999),
28+
'user_id' => $userData['id'] ?? null,
29+
'name' => $userData['name'] ?? 'Unknown',
30+
'email' => $userData['email'] ?? 'unknown@example.com',
31+
'created_at' => date('Y-m-d H:i:s'),
32+
];
33+
34+
return ActionResult::success([
35+
'profile_id' => $profile['id'],
36+
'profile' => $profile,
37+
]);
38+
}
39+
40+
public function canExecute(WorkflowContext $context): bool
41+
{
42+
return true; // Always executable for testing
43+
}
44+
45+
public function getName(): string
46+
{
47+
return 'Create User Profile';
48+
}
49+
50+
public function getDescription(): string
51+
{
52+
return 'Creates a new user profile in the database';
53+
}
54+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
namespace SolutionForest\WorkflowEngine\Laravel\Tests\Support\TestActions;
4+
5+
use SolutionForest\WorkflowEngine\Contracts\WorkflowAction;
6+
use SolutionForest\WorkflowEngine\Core\ActionResult;
7+
use SolutionForest\WorkflowEngine\Core\WorkflowContext;
8+
9+
class RiskyAction implements WorkflowAction
10+
{
11+
public function execute(WorkflowContext $context): ActionResult
12+
{
13+
$config = $context->getConfig();
14+
$failureRate = $config['failure_rate'] ?? 0.3; // 30% chance of failure by default
15+
16+
// Simulate risky operation that sometimes fails
17+
if (rand(1, 100) <= ($failureRate * 100)) {
18+
throw new \Exception('Simulated failure in risky operation');
19+
}
20+
21+
return ActionResult::success([
22+
'operation_id' => 'risky_'.uniqid(),
23+
'success' => true,
24+
'executed_at' => date('Y-m-d H:i:s'),
25+
]);
26+
}
27+
28+
public function canExecute(WorkflowContext $context): bool
29+
{
30+
return true; // Always executable for testing
31+
}
32+
33+
public function getName(): string
34+
{
35+
return 'Risky Operation';
36+
}
37+
38+
public function getDescription(): string
39+
{
40+
return 'A simulated risky operation that sometimes fails for testing retry logic';
41+
}
42+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
3+
namespace SolutionForest\WorkflowEngine\Laravel\Tests\Support\TestActions;
4+
5+
use SolutionForest\WorkflowEngine\Contracts\WorkflowAction;
6+
use SolutionForest\WorkflowEngine\Core\ActionResult;
7+
use SolutionForest\WorkflowEngine\Core\WorkflowContext;
8+
9+
class SendWelcomeEmailAction implements WorkflowAction
10+
{
11+
public function execute(WorkflowContext $context): ActionResult
12+
{
13+
$config = $context->getConfig();
14+
$userData = $context->getData('user') ?? [];
15+
16+
// Mock email sending
17+
$emailData = [
18+
'id' => 'email_'.uniqid(),
19+
'to' => $userData['email'] ?? 'unknown@example.com',
20+
'subject' => $config['subject'] ?? 'Welcome!',
21+
'template' => $config['template'] ?? 'welcome',
22+
'sent_at' => date('Y-m-d H:i:s'),
23+
];
24+
25+
return ActionResult::success([
26+
'email_id' => $emailData['id'],
27+
'email_sent' => true,
28+
'email_data' => $emailData,
29+
]);
30+
}
31+
32+
public function canExecute(WorkflowContext $context): bool
33+
{
34+
$userData = $context->getData('user') ?? [];
35+
36+
return ! empty($userData['email']);
37+
}
38+
39+
public function getName(): string
40+
{
41+
return 'Send Welcome Email';
42+
}
43+
44+
public function getDescription(): string
45+
{
46+
return 'Sends a welcome email to the user';
47+
}
48+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php
2+
3+
namespace SolutionForest\WorkflowEngine\Laravel\Tests\Support\TestActions;
4+
5+
use SolutionForest\WorkflowEngine\Contracts\WorkflowAction;
6+
use SolutionForest\WorkflowEngine\Core\ActionResult;
7+
use SolutionForest\WorkflowEngine\Core\WorkflowContext;
8+
9+
class VerifyIdentityAction implements WorkflowAction
10+
{
11+
public function execute(WorkflowContext $context): ActionResult
12+
{
13+
$userData = $context->getData('user') ?? [];
14+
15+
// Mock identity verification
16+
$verificationResult = [
17+
'verification_id' => 'verify_'.uniqid(),
18+
'user_id' => $userData['id'] ?? null,
19+
'status' => 'verified',
20+
'verified_at' => date('Y-m-d H:i:s'),
21+
];
22+
23+
return ActionResult::success([
24+
'verification' => $verificationResult,
25+
'identity_verified' => true,
26+
]);
27+
}
28+
29+
public function canExecute(WorkflowContext $context): bool
30+
{
31+
$userData = $context->getData('user') ?? [];
32+
33+
return isset($userData['id']) && ($userData['age'] ?? 0) >= 18;
34+
}
35+
36+
public function getName(): string
37+
{
38+
return 'Verify Identity';
39+
}
40+
41+
public function getDescription(): string
42+
{
43+
return 'Verifies user identity for users 18 years and older';
44+
}
45+
}

0 commit comments

Comments
 (0)