Skip to content

Latest commit

 

History

History
168 lines (128 loc) · 5.87 KB

File metadata and controls

168 lines (128 loc) · 5.87 KB

CLAUDE.md

Project context for Claude Code and AI-assisted development.

Project Overview

workflow-engine-core is a framework-agnostic PHP workflow engine. Zero production dependencies. PHP 8.3+. MIT licensed.

Status: v0.0.2-alpha — active development, not production-ready.

Related package: solution-forest/workflow-engine-laravel (Laravel integration layer).

Quick Reference

# Run tests
composer test

# Run tests with coverage
composer test:coverage

# Static analysis (PHPStan level 6)
composer analyze

# Code formatting (Laravel Pint)
composer pint

# Check formatting without changes (CI mode)
composer pint:test

# Full quality check: format + analyze + test
composer quality

# CI pipeline: check format + analyze + test
composer ci

Architecture

WorkflowBuilder → WorkflowDefinition → WorkflowEngine → Executor → Actions
                                              ↓
                                        StateManager → StorageAdapter
                                              ↓
                                        EventDispatcher

Namespace Map

Namespace Purpose
Core\ WorkflowEngine, WorkflowBuilder, Executor, StateManager, WorkflowInstance, WorkflowDefinition, WorkflowContext, ActionResult, Step, DefinitionParser, ActionResolver
Actions\ BaseAction, LogAction, EmailAction, HttpAction, DelayAction, ConditionAction
Contracts\ WorkflowAction, StorageAdapter, EventDispatcher, Logger
Attributes\ WorkflowStep, Retry, Timeout, Condition
Events\ WorkflowStartedEvent, WorkflowCompletedEvent, WorkflowFailedEvent, WorkflowCancelledEvent, StepCompletedEvent, StepFailedEvent, StepRetriedEvent
Exceptions\ WorkflowException (base), InvalidWorkflowDefinitionException, InvalidWorkflowStateException, ActionNotFoundException, StepExecutionException, WorkflowInstanceNotFoundException
Support\ NullLogger, NullEventDispatcher, SimpleWorkflow, Uuid, Timeout, ConditionEvaluator, Arr

State Machine

PENDING → RUNNING → COMPLETED
    ↓         ↓ ↑
  FAILED   WAITING
    ↑         ↓ ↑
  FAILED ← PAUSED
    ↑
CANCELLED ← (any non-terminal state)

Valid transitions (enforced at runtime):

  • PENDINGRUNNING, FAILED, CANCELLED
  • RUNNINGWAITING, PAUSED, COMPLETED, FAILED, CANCELLED
  • WAITINGRUNNING, FAILED, CANCELLED
  • PAUSEDRUNNING, FAILED, CANCELLED
  • Terminal states (COMPLETED, FAILED, CANCELLED) → no transitions allowed

Invalid transitions throw InvalidWorkflowStateException.

Key Contracts

Every custom integration implements one of these:

  • WorkflowActionexecute(WorkflowContext): ActionResult + canExecute(WorkflowContext): bool
  • StorageAdaptersave(), load(), findInstances(), delete(), exists(), updateState()
  • EventDispatcherdispatch(object $event): void
  • Logger — PSR-3 style: info(), error(), warning(), debug()

How Actions Work

Actions are instantiated by Executor with new $actionClass($config, $logger). They receive a WorkflowContext containing workflowId, stepId, data, config, and the instance reference. They return ActionResult::success($data) or ActionResult::failure($message).

Conventions

Code Style

  • Laravel Pint with Laravel preset
  • Alphabetically ordered imports
  • Short array syntax []
  • No trailing commas in single-line arrays
  • PHPDoc left-aligned

Testing

  • Pest PHP 2.0 with PHPUnit 10 base
  • Test structure: tests/Unit/, tests/Integration/, tests/RealWorld/
  • Base test class: TestCase (provides $this->engine and $this->storage via InMemoryStorage)
  • Use test('description', function () { ... }) syntax
  • Use describe() blocks for grouping related tests
  • Use expect() fluent assertions, not $this->assert*()
  • Architecture tests in tests/ArchTest.php — no dd, dump, ray calls

Naming

  • Step IDs: snake_case, must match /^[a-zA-Z][a-zA-Z0-9_-]*$/
  • Workflow names: kebab-case (e.g., user-onboarding, order-processing)
  • Action classes: PascalCase ending in Action (e.g., ProcessPaymentAction)
  • Event classes: PascalCase ending in Event (e.g., StepCompletedEvent)
  • Exception classes: PascalCase ending in Exception

PHP Features Used

  • PHP 8.3 readonly properties and classes
  • Backed enums with methods (WorkflowState)
  • Named arguments throughout builder API
  • Match expressions instead of switch
  • Union types (string|WorkflowAction)
  • Constructor promotion

Builder API Pattern

// Fluent builder (primary API)
$workflow = WorkflowBuilder::create('order-flow')
    ->description('Process customer orders')
    ->addStep('validate', ValidateOrderAction::class)
    ->when('order.total > 1000', function ($builder) {
        $builder->addStep('fraud_check', FraudCheckAction::class);
    })
    ->addStep('payment', ProcessPaymentAction::class, timeout: 300, retryAttempts: 3)
    ->build();

// Quick templates
$workflow = WorkflowBuilder::quick()->userOnboarding();
$workflow = WorkflowBuilder::quick()->orderProcessing();

Running a Workflow

$engine = new WorkflowEngine($storageAdapter, $eventDispatcher);
$instanceId = $engine->start('my-workflow', $definition->toArray(), ['key' => 'value']);
$instance = $engine->getInstance($instanceId);
$engine->cancel($instanceId, 'reason');

CI/CD

GitHub Actions workflows:

  • run-tests.yml — Matrix: PHP 8.3/8.4 × prefer-lowest/prefer-stable
  • phpstan.yml — Static analysis on .php changes
  • fix-php-code-style-issues.yml — Auto-format with Pint on push
  • update-changelog.yml — Auto-update CHANGELOG on release
  • dependabot-auto-merge.yml — Auto-merge minor/patch dependency updates

File Counts

  • 46 source files in src/
  • 25 test files in tests/
  • 93 tests, 224+ assertions
  • PHPStan level 6 compliance