From 3bca2ada25a938745e77587c86f743c96cb877a0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 20 Jul 2025 11:18:05 +0000 Subject: [PATCH 1/3] Initial plan From ef76a480d2f502608d7d39a66c471d98b019cebf Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 20 Jul 2025 11:35:46 +0000 Subject: [PATCH 2/3] Update README.md with missing factory methods and comprehensive step examples Co-authored-by: Grazulex <4521546+Grazulex@users.noreply.github.com> --- README.md | 141 ++++++++++++++++++++++++++++++++++++++++++++-- test_flowpipe.php | 59 +++++++++++++++++++ 2 files changed, 196 insertions(+), 4 deletions(-) create mode 100644 test_flowpipe.php diff --git a/README.md b/README.md index 8f16691..630cfef 100644 --- a/README.md +++ b/README.md @@ -82,6 +82,45 @@ $result = Flowpipe::make() // Result: "HELLO-WORLD!" ``` +### 🎯 Factory Methods + +**Laravel Flowpipe** provides convenient factory methods for creating instances with specific tracers: + +```php +use Grazulex\LaravelFlowpipe\Flowpipe; + +// Create with debug tracing (logs to file or console) +$debugFlow = Flowpipe::debug(true, 'flowpipe'); // logToFile=true, channel='flowpipe' +$result = $debugFlow + ->send($data) + ->through($steps) + ->thenReturn(); + +// Create with performance tracing +$perfFlow = Flowpipe::performance(); +$result = $perfFlow + ->send($data) + ->through($steps) + ->thenReturn(); + +// Create with database tracing +$dbFlow = Flowpipe::database('custom_traces_table'); +$result = $dbFlow + ->send($data) + ->through($steps) + ->thenReturn(); + +// Create with test tracing (for unit tests) +$testFlow = Flowpipe::test(); +$result = $testFlow + ->send($data) + ->through($steps) + ->thenReturn(); + +// Standard make method (no tracing by default) +$flow = Flowpipe::make(); // or Flowpipe::make($customTracer) +``` + ### 🛡️ Error Handling with Retry ```php @@ -508,6 +547,82 @@ $result = Flowpipe::make() ->thenReturn(); ``` +### 🔧 Built-in Step Types + +**Laravel Flowpipe** includes various specialized step types for common operations: + +```php +use Grazulex\LaravelFlowpipe\Flowpipe; + +// Cache step - cache expensive operations +$result = Flowpipe::make() + ->send($userData) + ->cache('user_profile_' . $userData['id'], 3600) // Cache for 1 hour + ->through([ + fn($data, $next) => $next(fetchUserProfile($data)), + ]) + ->thenReturn(); + +// Transform step - transform data structure +$result = Flowpipe::make() + ->send($rawData) + ->transform(function ($data) { + return [ + 'name' => strtoupper($data['name']), + 'email' => strtolower($data['email']), + 'created_at' => now(), + ]; + }) + ->through([ + fn($data, $next) => $next(saveUser($data)), + ]) + ->thenReturn(); + +// Validation step - validate data using Laravel validation +$result = Flowpipe::make() + ->send($inputData) + ->validate([ + 'name' => 'required|string|max:255', + 'email' => 'required|email|unique:users', + 'age' => 'required|integer|min:18', + ]) + ->through([ + fn($data, $next) => $next(processValidData($data)), + ]) + ->thenReturn(); + +// Batch step - process data in batches +$result = Flowpipe::make() + ->send($largeDataset) + ->batch(100) // Process 100 items at a time + ->through([ + fn($batch, $next) => $next(processBatch($batch)), + ]) + ->thenReturn(); + +// Rate limiting step - prevent API abuse +$result = Flowpipe::make() + ->send($apiRequest) + ->rateLimit('api_calls', 60, 1) // 60 calls per minute + ->through([ + fn($data, $next) => $next(callExternalAPI($data)), + ]) + ->thenReturn(); + +// Combine multiple step types +$result = Flowpipe::make() + ->send($complexData) + ->validate(['data' => 'required|array']) + ->transform(fn($data) => ['processed' => $data['data']]) + ->cache('complex_operation', 1800) + ->batch(50) + ->rateLimit('processing', 30, 1) + ->through([ + fn($data, $next) => $next(performComplexOperation($data)), + ]) + ->thenReturn(); +``` + ### Error Handling in Production Workflows ```php @@ -624,6 +739,19 @@ public function test_user_processing_flow() $this->assertEquals('JOHN', $result); $this->assertCount(1, $tracer->count()); } + +// Or use the factory method for cleaner tests: +public function test_user_processing_flow_with_factory() +{ + $result = Flowpipe::test() + ->send(['name' => 'John']) + ->through([ + fn($data, $next) => $next(strtoupper($data['name'])), + ]) + ->thenReturn(); + + $this->assertEquals('JOHN', $result); +} ``` ## ⚡ Performance @@ -668,10 +796,15 @@ public function test_user_processing_flow() ### Static Methods -- **`group(string $name, array $steps)`** - Define a reusable step group -- **`hasGroup(string $name)`** - Check if a group exists -- **`getGroups()`** - Get all registered groups -- **`clearGroups()`** - Clear all registered groups (useful for testing) +- **`make(?Tracer $tracer = null)`** - Create a new flowpipe instance +- **`debug(bool $logToFile = false, string $logChannel = 'default')`** - Create instance with debug tracer +- **`performance()`** - Create instance with performance tracer +- **`database(string $tableName = 'flowpipe_traces')`** - Create instance with database tracer +- **`test()`** - Create instance with test tracer (for testing) +- **`group(string $name, array $steps)`** - Define a reusable step group +- **`hasGroup(string $name)`** - Check if a group exists +- **`getGroups()`** - Get all registered groups +- **`clearGroups()`** - Clear all registered groups (useful for testing) ### Conditional Steps diff --git a/test_flowpipe.php b/test_flowpipe.php new file mode 100644 index 0000000..172d1a7 --- /dev/null +++ b/test_flowpipe.php @@ -0,0 +1,59 @@ +send('Hello World') + ->through([ + fn($data, $next) => $next(strtoupper($data)), + fn($data, $next) => $next(str_replace(' ', '-', $data)), + fn($data, $next) => $next($data . '!'), + ]) + ->thenReturn(); + + echo "Basic test result: " . $result . PHP_EOL; + + // Test group functionality + Flowpipe::group('text-processing', [ + fn($data, $next) => $next(trim($data)), + fn($data, $next) => $next(strtoupper($data)), + fn($data, $next) => $next(str_replace(' ', '-', $data)), + ]); + + $groupResult = Flowpipe::make() + ->send(' hello world ') + ->useGroup('text-processing') + ->through([ + fn($data, $next) => $next($data . '!'), + ]) + ->thenReturn(); + + echo "Group test result: " . $groupResult . PHP_EOL; + + // Test nested flows + $nestedResult = Flowpipe::make() + ->send('hello world') + ->nested([ + fn($data, $next) => $next(strtoupper($data)), + fn($data, $next) => $next(str_replace(' ', '-', $data)), + ]) + ->through([ + fn($data, $next) => $next($data . '!'), + ]) + ->thenReturn(); + + echo "Nested flow test result: " . $nestedResult . PHP_EOL; + + echo "All tests passed!" . PHP_EOL; + +} catch (Exception $e) { + echo "Error: " . $e->getMessage() . PHP_EOL; + echo "File: " . $e->getFile() . ":" . $e->getLine() . PHP_EOL; + exit(1); +} \ No newline at end of file From 8be5f218e015b35eeb340f95e061a8585dcdcb5a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 20 Jul 2025 11:40:56 +0000 Subject: [PATCH 3/3] Add missing group YAML files and update examples documentation Co-authored-by: Grazulex <4521546+Grazulex@users.noreply.github.com> --- examples/README.md | 49 +++++++++++++++++-- examples/groups/inventory-management.yaml | 31 ++++++++++++ examples/groups/order-notifications.yaml | 31 ++++++++++++ examples/groups/order-validation.yaml | 31 ++++++++++++ examples/groups/user-notifications.yaml | 31 ++++++++++++ examples/groups/user-setup.yaml | 31 ++++++++++++ test_flowpipe.php | 59 ----------------------- 7 files changed, 200 insertions(+), 63 deletions(-) create mode 100644 examples/groups/inventory-management.yaml create mode 100644 examples/groups/order-notifications.yaml create mode 100644 examples/groups/order-validation.yaml create mode 100644 examples/groups/user-notifications.yaml create mode 100644 examples/groups/user-setup.yaml delete mode 100644 test_flowpipe.php diff --git a/examples/README.md b/examples/README.md index 1dca29b..3fb0961 100644 --- a/examples/README.md +++ b/examples/README.md @@ -222,23 +222,64 @@ php artisan flowpipe:export user-registration --format=md --output=docs/user-reg ## Step Groups -The examples demonstrate three types of reusable step groups: +The examples demonstrate multiple types of reusable step groups organized by functionality: -### User Validation Group (`groups/user-validation.yaml`) +### User-Related Groups + +#### User Validation Group (`groups/user-validation.yaml`) - Email format validation - Password strength checking - Required field validation - User existence checking - Terms acceptance validation -### Order Processing Group (`groups/order-processing.yaml`) +#### User Setup Group (`groups/user-setup.yaml`) +- User ID generation +- Password hashing +- Profile creation +- Default preferences setup +- API key generation + +#### User Notifications Group (`groups/user-notifications.yaml`) +- Welcome email sending +- Email verification dispatch +- Admin notifications +- Registration event logging +- User statistics updates + +### E-commerce Groups + +#### Order Validation Group (`groups/order-validation.yaml`) +- Order structure validation +- Customer information validation +- Item and quantity validation +- Order total verification +- Business rules checking + +#### Inventory Management Group (`groups/inventory-management.yaml`) +- Item availability checking +- Inventory reservation +- Shipping cost calculation +- Inventory level updates +- Inventory reporting + +#### Order Notifications Group (`groups/order-notifications.yaml`) +- Order confirmation emails +- SMS notifications +- Customer account updates +- Warehouse notifications +- Notification event logging + +### General Processing Groups + +#### Order Processing Group (`groups/order-processing.yaml`) - Order data validation - Inventory checking and reservation - Payment processing - Order record creation - Confirmation generation -### Notifications Group (`groups/notifications.yaml`) +#### Notifications Group (`groups/notifications.yaml`) - Welcome email sending - Verification email dispatch - SMS notifications diff --git a/examples/groups/inventory-management.yaml b/examples/groups/inventory-management.yaml new file mode 100644 index 0000000..7b85299 --- /dev/null +++ b/examples/groups/inventory-management.yaml @@ -0,0 +1,31 @@ +# Example: Inventory Management Group +# File: groups/inventory-management.yaml + +group: inventory-management +description: Manage inventory for e-commerce orders + +steps: + # Check item availability + - type: closure + action: check_item_availability + description: Check if all items are available in requested quantities + + # Reserve inventory items + - type: closure + action: reserve_items + description: Reserve items for this order + + # Calculate shipping costs + - type: closure + action: calculate_shipping + description: Calculate shipping costs based on items and location + + # Update inventory levels + - type: closure + action: update_inventory_levels + description: Update inventory levels after reservation + + # Generate inventory report + - type: closure + action: generate_inventory_report + description: Generate inventory status report for this order \ No newline at end of file diff --git a/examples/groups/order-notifications.yaml b/examples/groups/order-notifications.yaml new file mode 100644 index 0000000..202e349 --- /dev/null +++ b/examples/groups/order-notifications.yaml @@ -0,0 +1,31 @@ +# Example: Order Notifications Group +# File: groups/order-notifications.yaml + +group: order-notifications +description: Send notifications for e-commerce orders + +steps: + # Send order confirmation email + - type: closure + action: send_order_confirmation + description: Send order confirmation email to customer + + # Send SMS notification + - type: closure + action: send_sms_notification + description: Send SMS notification if customer opted in + + # Update customer account + - type: closure + action: update_customer_account + description: Update customer's order history + + # Notify warehouse + - type: closure + action: notify_warehouse + description: Notify warehouse team about new order + + # Log notification events + - type: closure + action: log_notifications + description: Log all notification events for auditing \ No newline at end of file diff --git a/examples/groups/order-validation.yaml b/examples/groups/order-validation.yaml new file mode 100644 index 0000000..fddb827 --- /dev/null +++ b/examples/groups/order-validation.yaml @@ -0,0 +1,31 @@ +# Example: Order Validation Group +# File: groups/order-validation.yaml + +group: order-validation +description: Validate e-commerce order data and requirements + +steps: + # Validate order structure + - type: closure + action: validate_order_structure + description: Ensure order contains required fields + + # Validate customer information + - type: closure + action: validate_customer_info + description: Validate customer name, email, and address + + # Validate items and quantities + - type: closure + action: validate_items + description: Validate item names, prices, and quantities + + # Calculate and verify total + - type: closure + action: verify_order_total + description: Calculate total and verify against provided total + + # Check business rules + - type: closure + action: check_business_rules + description: Apply business rules (minimum order, restrictions, etc.) \ No newline at end of file diff --git a/examples/groups/user-notifications.yaml b/examples/groups/user-notifications.yaml new file mode 100644 index 0000000..8ef5670 --- /dev/null +++ b/examples/groups/user-notifications.yaml @@ -0,0 +1,31 @@ +# Example: User Notifications Group +# File: groups/user-notifications.yaml + +group: user-notifications +description: Send notifications for new user registration + +steps: + # Send welcome email + - type: closure + action: send_welcome_email + description: Send welcome email with account details + + # Send verification email + - type: closure + action: send_verification_email + description: Send email verification link + + # Send admin notification + - type: closure + action: notify_admin + description: Notify administrators about new user registration + + # Log registration event + - type: closure + action: log_registration + description: Log user registration event for analytics + + # Update user stats + - type: closure + action: update_user_stats + description: Update application user statistics \ No newline at end of file diff --git a/examples/groups/user-setup.yaml b/examples/groups/user-setup.yaml new file mode 100644 index 0000000..ba24b7f --- /dev/null +++ b/examples/groups/user-setup.yaml @@ -0,0 +1,31 @@ +# Example: User Setup Group +# File: groups/user-setup.yaml + +group: user-setup +description: Set up new user account and profile + +steps: + # Generate user ID + - type: closure + action: generate_user_id + description: Generate unique user identifier + + # Hash password + - type: closure + action: hash_password + description: Hash user password securely + + # Create user profile + - type: closure + action: create_user_profile + description: Create initial user profile with default settings + + # Set default preferences + - type: closure + action: set_default_preferences + description: Set default user preferences and settings + + # Generate API key + - type: closure + action: generate_api_key + description: Generate API key for user account \ No newline at end of file diff --git a/test_flowpipe.php b/test_flowpipe.php deleted file mode 100644 index 172d1a7..0000000 --- a/test_flowpipe.php +++ /dev/null @@ -1,59 +0,0 @@ -send('Hello World') - ->through([ - fn($data, $next) => $next(strtoupper($data)), - fn($data, $next) => $next(str_replace(' ', '-', $data)), - fn($data, $next) => $next($data . '!'), - ]) - ->thenReturn(); - - echo "Basic test result: " . $result . PHP_EOL; - - // Test group functionality - Flowpipe::group('text-processing', [ - fn($data, $next) => $next(trim($data)), - fn($data, $next) => $next(strtoupper($data)), - fn($data, $next) => $next(str_replace(' ', '-', $data)), - ]); - - $groupResult = Flowpipe::make() - ->send(' hello world ') - ->useGroup('text-processing') - ->through([ - fn($data, $next) => $next($data . '!'), - ]) - ->thenReturn(); - - echo "Group test result: " . $groupResult . PHP_EOL; - - // Test nested flows - $nestedResult = Flowpipe::make() - ->send('hello world') - ->nested([ - fn($data, $next) => $next(strtoupper($data)), - fn($data, $next) => $next(str_replace(' ', '-', $data)), - ]) - ->through([ - fn($data, $next) => $next($data . '!'), - ]) - ->thenReturn(); - - echo "Nested flow test result: " . $nestedResult . PHP_EOL; - - echo "All tests passed!" . PHP_EOL; - -} catch (Exception $e) { - echo "Error: " . $e->getMessage() . PHP_EOL; - echo "File: " . $e->getFile() . ":" . $e->getLine() . PHP_EOL; - exit(1); -} \ No newline at end of file