.claude/skills/ecotone-laravel-setup/SKILL.md
Sets up Ecotone in a Laravel project: composer installation, auto-discovery, config/ecotone.php, Eloquent ORM integration, LaravelConnectionReference for DBAL, Laravel Queue channels, artisan consumer commands, and ServiceContext. Use when installing Ecotone in Laravel, configuring Laravel-specific connections, or setting up Laravel async consumers.
npx skillsauth add ecotoneframework/ecotone-dev ecotone-laravel-setupInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
This skill covers setting up and configuring Ecotone within a Laravel application. Use it when installing Ecotone, configuring database connections, setting up async messaging with Laravel Queue, integrating Eloquent aggregates, or configuring multi-tenancy.
composer require ecotone/laravel
Optional packages:
composer require ecotone/dbal # Database support (DBAL, outbox, dead letter, event sourcing)
composer require ecotone/amqp # RabbitMQ support
composer require ecotone/redis # Redis support
composer require ecotone/sqs # SQS support
composer require ecotone/kafka # Kafka support
The service provider Ecotone\Laravel\EcotoneProvider is auto-discovered by Laravel.
Publish configuration:
php artisan vendor:publish --tag=ecotone-config
This creates config/ecotone.php.
Ecotone automatically registers EloquentRepository -- Eloquent models extending Model are auto-detected as aggregates.
use Ecotone\Modelling\Attribute\Aggregate;
use Ecotone\Modelling\Attribute\AggregateIdentifierMethod;
use Ecotone\Modelling\Attribute\CommandHandler;
use Ecotone\Modelling\WithEvents;
use Illuminate\Database\Eloquent\Model;
#[Aggregate]
class Order extends Model
{
use WithEvents;
public $fillable = ['id', 'user_id', 'total_price', 'is_cancelled'];
#[CommandHandler]
public static function place(PlaceOrder $command): self
{
$order = self::create([
'user_id' => $command->userId,
'total_price' => $command->totalPrice,
'is_cancelled' => false,
]);
$order->recordThat(new OrderWasPlaced($order->id));
return $order;
}
#[CommandHandler]
public function cancel(CancelOrder $command): void
{
$this->is_cancelled = true;
$this->save();
}
#[AggregateIdentifierMethod('id')]
public function getId(): int
{
return $this->id;
}
}
Key differences from regular aggregates:
Illuminate\Database\Eloquent\Model#[AggregateIdentifierMethod('id')] instead of #[Identifier] on properties$this->save() in action handlersself::create([...])WithEvents trait for recording domain events#[ServiceContext]
public function databaseConnection(): LaravelConnectionReference
{
return LaravelConnectionReference::defaultConnection('mysql');
}
The connection name matches the key in config/database.php connections array.
#[ServiceContext]
public function asyncChannel(): LaravelQueueMessageChannelBuilder
{
return LaravelQueueMessageChannelBuilder::create('notifications');
}
php artisan ecotone:run <channel_name>
php artisan ecotone:run orders --handledMessageLimit=100
php artisan ecotone:run orders --memoryLimit=256
php artisan ecotone:run orders --executionTimeLimit=60000
php artisan ecotone:list
#[ServiceContext]
public function multiTenant(): MultiTenantConfiguration
{
return MultiTenantConfiguration::create(
tenantHeaderName: 'tenant',
tenantToConnectionMapping: [
'tenant_a' => LaravelConnectionReference::create('tenant_a_connection'),
'tenant_b' => LaravelConnectionReference::create('tenant_b_connection'),
],
);
}
LaravelConnectionReference::defaultConnection() takes the key from config/database.php connections arrayLaravelQueueMessageChannelBuilder::create() channel name must match an Ecotone async routing, optionally takes a queue connection name as second parameter#[AggregateIdentifierMethod] instead of #[Identifier] on properties#[ServiceContext] methods in a class registered as a service for configurationconfig/ecotone.php file with all options and comments, all configuration option descriptions with defaults, and LaravelConnectionReference API table. Load when you need the complete configuration file or all available config options.config/queue.php, DBAL-backed channels, and multi-tenant setup with config/database.php. Load when you need full working class files with imports and complete configuration examples.development
Implements workflows in Ecotone: Sagas (stateful process managers), stateless workflows with InternalHandler and outputChannelName chaining, and Orchestrators (Enterprise) with routing slip pattern. Use when building Sagas, process managers, multi-step workflows, long-running processes, handler chaining, or Orchestrators.
development
Writes and debugs tests for Ecotone using EcotoneLite::bootstrapFlowTesting, aggregate testing, async-tested-synchronously patterns, projections, and common failure diagnosis. Use when writing tests, debugging test failures, adding test coverage, or implementing any new feature that needs tests. Should be co-triggered whenever a new handler, aggregate, saga, projection, or interceptor is being implemented.
testing
Sets up Ecotone in a Symfony project: composer installation, bundle registration, YAML configuration, Doctrine ORM integration, SymfonyConnectionReference for DBAL, Symfony Messenger channels, async consumer commands, and ServiceContext. Use when installing Ecotone in Symfony, configuring Symfony-specific connections, or setting up Symfony async consumers.
development
Implements message resiliency in Ecotone: RetryTemplateBuilder for retry strategies, error channels, ErrorHandlerConfiguration, DBAL dead letter queues, outbox pattern for guaranteed delivery, and FinalFailureStrategy for permanent failures. Use when handling failed messages, configuring retries, setting up dead letter queues, implementing outbox pattern, or managing error channels.