acc-create-saga-pattern

Generates Saga pattern components for PHP 8.5. Creates Saga interfaces, steps, orchestrator, state management, and compensation logic with unit tests.

181 stars

Best use case

acc-create-saga-pattern is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

Generates Saga pattern components for PHP 8.5. Creates Saga interfaces, steps, orchestrator, state management, and compensation logic with unit tests.

Teams using acc-create-saga-pattern should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/acc-create-saga-pattern/SKILL.md --create-dirs "https://raw.githubusercontent.com/majiayu000/claude-skill-registry/main/skills/data/acc-create-saga-pattern/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/acc-create-saga-pattern/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How acc-create-saga-pattern Compares

Feature / Agentacc-create-saga-patternStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

Generates Saga pattern components for PHP 8.5. Creates Saga interfaces, steps, orchestrator, state management, and compensation logic with unit tests.

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

SKILL.md Source

# Saga Pattern Generator

Creates Saga pattern infrastructure for distributed transaction coordination.

## When to Use

- Distributed transactions across multiple services
- Long-running business processes
- Operations requiring compensation on failure
- Multi-step workflows with rollback capability

## Component Characteristics

### SagaState Enum
- Domain layer enum
- Defines saga lifecycle states: Pending, Running, Compensating, Completed, Failed, CompensationFailed
- Includes state transition validation
- Terminal states detection

### SagaStep Interface
- Domain layer interface
- Execute and compensate methods
- Idempotency declaration
- Timeout configuration

### SagaContext
- Carries saga execution data
- Serializable for persistence
- Supports data accumulation across steps

### SagaOrchestrator
- Application layer coordinator
- Manages step execution
- Handles compensation flow (reverse order)
- Persists state after each step

### SagaPersistence
- Stores saga state for recovery
- Supports finding incomplete sagas
- Dead letter handling

---

## Generation Process

### Step 1: Analyze Request

Determine:
- Context name (Order, Payment, Shipping)
- Required saga steps
- Compensation logic for each step

### Step 2: Generate Core Components

Create in this order:

1. **Domain Layer** (`src/Domain/Shared/Saga/`)
   - `SagaState.php` — State enum with transitions
   - `StepResult.php` — Step result value object
   - `SagaStepInterface.php` — Step contract
   - `SagaContext.php` — Execution context
   - `SagaResult.php` — Saga result
   - Exception classes

2. **Application Layer** (`src/Application/Shared/Saga/`)
   - `SagaPersistenceInterface.php` — Persistence port
   - `SagaRecord.php` — Persisted record
   - `AbstractSagaStep.php` — Base step class
   - `SagaOrchestrator.php` — Orchestrator

3. **Infrastructure Layer**
   - `DoctrineSagaPersistence.php` — Doctrine implementation
   - Database migration

4. **Tests**
   - `SagaStateTest.php`
   - `SagaOrchestratorTest.php`

### Step 3: Generate Context-Specific Steps

For each saga step (e.g., Order saga):

```
src/Application/{Context}/Saga/Step/
├── ReserveInventoryStep.php
├── ChargePaymentStep.php
└── CreateShipmentStep.php

src/Application/{Context}/Saga/
└── {Context}SagaFactory.php
```

---

## File Placement

| Layer | Path |
|-------|------|
| Domain Types | `src/Domain/Shared/Saga/` |
| Application Saga | `src/Application/Shared/Saga/` |
| Context Steps | `src/Application/{Context}/Saga/Step/` |
| Saga Factory | `src/Application/{Context}/Saga/` |
| Infrastructure | `src/Infrastructure/Persistence/Doctrine/Repository/` |
| Unit Tests | `tests/Unit/{Layer}/{Path}/` |

---

## Key Principles

### Compensation Rules
1. Compensate in **reverse order** of execution
2. Compensations must be **idempotent**
3. Handle "already compensated" gracefully
4. Log all compensation attempts

### Idempotency
1. Use idempotency keys for each step
2. Check for existing results before executing
3. Return existing result if found

### State Transitions
```
Pending → Running → Completed
              ↓
         Compensating → Failed
              ↓
         CompensationFailed
```

---

## Naming Conventions

| Component | Pattern | Example |
|-----------|---------|---------|
| State Enum | `SagaState` | `SagaState` |
| Step Interface | `SagaStepInterface` | `SagaStepInterface` |
| Abstract Step | `AbstractSagaStep` | `AbstractSagaStep` |
| Concrete Step | `{Action}Step` | `ReserveInventoryStep` |
| Orchestrator | `SagaOrchestrator` | `SagaOrchestrator` |
| Factory | `{Name}SagaFactory` | `OrderSagaFactory` |
| Test | `{ClassName}Test` | `SagaOrchestratorTest` |

---

## Quick Template Reference

### SagaStepInterface

```php
interface SagaStepInterface
{
    public function name(): string;
    public function execute(SagaContext $context): StepResult;
    public function compensate(SagaContext $context): StepResult;
    public function isIdempotent(): bool;
    public function timeout(): int;
}
```

### StepResult

```php
final readonly class StepResult
{
    public static function success(array $data = []): self;
    public static function failure(string $error): self;
    public function isSuccess(): bool;
    public function isFailure(): bool;
}
```

### Concrete Step Pattern

```php
final readonly class {Action}Step extends AbstractSagaStep
{
    public function name(): string
    {
        return '{action_name}';
    }

    public function execute(SagaContext $context): StepResult
    {
        $idempotencyKey = $this->idempotencyKey($context);

        // Check for existing result (idempotency)
        // Execute action
        // Return StepResult::success([...data...]) or failure
    }

    public function compensate(SagaContext $context): StepResult
    {
        // Get data from context
        // Undo action
        // Handle "already undone" gracefully
        return StepResult::success();
    }
}
```

---

## Usage Example

```php
// Create saga
$saga = $orderSagaFactory->create($command);

// Execute
$result = $saga->execute();

if ($result->isCompleted()) {
    // Success
} elseif ($result->isFailed()) {
    // Failed but compensated
    $error = $result->error;
} elseif ($result->isCompensationFailed()) {
    // Needs manual intervention
    $originalError = $result->error;
    $compensationError = $result->compensationError;
}
```

---

## DI Configuration

```yaml
# Symfony services.yaml
Domain\Shared\Saga\SagaStepInterface:
    tags: ['saga.step']

Application\Shared\Saga\SagaPersistenceInterface:
    alias: Infrastructure\Persistence\Doctrine\Repository\DoctrineSagaPersistence

Application\Order\Saga\OrderSagaFactory:
    arguments:
        $reserveStep: '@Application\Order\Saga\Step\ReserveInventoryStep'
        $chargeStep: '@Application\Order\Saga\Step\ChargePaymentStep'
        $shipStep: '@Application\Order\Saga\Step\CreateShipmentStep'
```

---

## Database Schema

```sql
CREATE TABLE sagas (
    id VARCHAR(255) PRIMARY KEY,
    type VARCHAR(255) NOT NULL,
    state VARCHAR(50) NOT NULL,
    completed_steps JSONB NOT NULL DEFAULT '[]',
    context JSONB NOT NULL,
    error TEXT,
    created_at TIMESTAMP(6) NOT NULL,
    updated_at TIMESTAMP(6) NOT NULL,
    completed_at TIMESTAMP(6)
);

CREATE INDEX idx_sagas_state ON sagas (state);
CREATE INDEX idx_sagas_type_state ON sagas (type, state);
```

---

## References

For complete PHP templates and test examples, see:
- `references/templates.md` — All component templates
- `references/examples.md` — Order saga example and unit tests

Related Skills

advanced-patterns

181
from majiayu000/claude-skill-registry

Advanced T-SQL patterns and techniques for SQL Server. Use this skill when: (1) User needs help with CTEs or recursive queries, (2) User asks about APPLY operator, (3) User wants MERGE or OUTPUT clause help, (4) User works with temporal tables, (5) User needs In-Memory OLTP guidance, (6) User asks about advanced grouping (ROLLUP, CUBE, GROUPING SETS).

advanced-js-mocking-patterns

181
from majiayu000/claude-skill-registry

Advanced mocking patterns for Jest and Vitest including module mocking, spies, and fake timers. PROACTIVELY activate for: (1) Module mocking, (2) Partial mocking with spies, (3) Mock lifecycle management, (4) Fake timers for time-dependent code, (5) Complex mock implementations. Triggers: "jest.mock", "vi.mock", "spyOn", "fakeTimers", "mockImplementation", "mockReturnValue", "mock lifecycle"

Advanced GetX Patterns

181
from majiayu000/claude-skill-registry

Advanced GetX features including Workers, GetxService, SmartManagement, GetConnect, GetSocket, bindings composition, and testing patterns

add-outbox-pattern

181
from majiayu000/claude-skill-registry

Add transactional outbox pattern for reliable event publishing with RavenDB (project)

patterns/adapter

181
from majiayu000/claude-skill-registry

Adapter (Wrapper) Pattern pattern for C development

ActiveRecord Query Patterns

181
from majiayu000/claude-skill-registry

Complete guide to ActiveRecord query optimization, associations, scopes, and PostgreSQL-specific patterns. Use this skill when writing database queries, designing model associations, creating migrations, optimizing query performance, or debugging N+1 queries and grouping errors.

actions-pattern

181
from majiayu000/claude-skill-registry

Garante que novas Actions sigam o padrão de classes actions reutilizáveis do Easy Budget.

Action Pattern Conventions

181
from majiayu000/claude-skill-registry

This skill should be used when the user asks about "Laravel action pattern", "action class naming", "how to structure actions", "React component patterns", "Node.js service structure", "framework-specific conventions", or discusses creating reusable, focused classes following action pattern conventions in Laravel, Symfony, React, Vue, or Node.js projects.

Action Cable & WebSocket Patterns

181
from majiayu000/claude-skill-registry

Real-time WebSocket features with Action Cable in Rails. Use when: (1) Building real-time chat, (2) Live notifications/presence, (3) Broadcasting model updates, (4) WebSocket authorization. Trigger keywords: Action Cable, WebSocket, real-time, channels, broadcasting, stream, subscriptions, presence, cable

ace-pattern-learning

181
from majiayu000/claude-skill-registry

Search ACE playbook before implementing, building, fixing, debugging, or refactoring code. Capture patterns after completing substantial coding work.

accessibility-patterns

181
from majiayu000/claude-skill-registry

Build inclusive web experiences following WCAG guidelines. Covers semantic HTML, ARIA, keyboard navigation, color contrast, and testing strategies. Triggers on accessibility, a11y, WCAG, screen readers, or inclusive design requests.

access-control-patterns

181
from majiayu000/claude-skill-registry

[STUB - Not implemented] Access control auditing with IDOR detection, RBAC/ABAC patterns, and privilege escalation prevention. PROACTIVELY activate for: [TODO: Define on implementation]. Triggers: [TODO: Define on implementation]