acc-event-sourcing-knowledge

📁 dykyi-roman/awesome-claude-code 📅 2 days ago
1
总安装量
1
周安装量
#44913
全站排名
安装命令
npx skills add https://github.com/dykyi-roman/awesome-claude-code --skill acc-event-sourcing-knowledge

Agent 安装分布

opencode 1
claude-code 1

Skill 文档

Event Sourcing Knowledge Base

Quick reference for Event Sourcing architecture patterns and PHP implementation guidelines.

Core Principles

Event Sourcing Fundamentals

Traditional Storage:          Event Sourcing:
┌─────────────────┐           ┌─────────────────┐
│  Current State  │           │  Event Stream   │
│  ─────────────  │           │  ─────────────  │
│  Order #123     │           │  1. OrderCreated│
│  Status: Paid   │           │  2. ItemAdded   │
│  Total: $150    │           │  3. ItemAdded   │
└─────────────────┘           │  4. OrderPaid   │
       ↓                      └────────┬────────┘
  Direct update                        │
                                       ▼
                              ┌─────────────────┐
                              │  Current State  │
                              │  (Rebuilt from  │
                              │   events)       │
                              └─────────────────┘

Rule: Store events, derive state. Never modify events.

Key Concepts

Concept Description
Event Immutable record of something that happened
Event Store Append-only storage for events
Event Stream Ordered sequence of events for one aggregate
Aggregate Consistency boundary, rebuilt from events
Projection Read model built by processing events
Snapshot Cached aggregate state for performance

Quick Checklists

Event Checklist

  • Named in past tense (OrderCreated, ItemAdded)
  • Immutable (readonly class)
  • Contains all data needed to apply change
  • Has metadata (timestamp, causation, correlation IDs)
  • No business logic
  • Versioned for schema evolution

Aggregate Checklist

  • State rebuilt from events only
  • apply*() methods modify state from events
  • record*() methods create and apply events
  • No direct state modification
  • Returns uncommitted events for persistence

Event Store Checklist

  • Append-only (no updates, no deletes)
  • Ordered within stream
  • Supports optimistic concurrency
  • Events never modified
  • Stream position tracking

Projection Checklist

  • Idempotent event handlers
  • Can be rebuilt from scratch
  • Handles event ordering
  • Tracks processed position

Common Violations Quick Reference

Violation Where to Look Severity
Mutable event Event with setters Critical
Direct state mutation Aggregate bypassing events Critical
Missing event data Event without full state info Critical
Event with logic Event doing calculations Warning
Non-idempotent projection Projection with side effects Warning
Missing metadata Event without timestamp/IDs Warning

PHP 8.5 Event Sourcing Patterns

Domain Event

final readonly class OrderConfirmedEvent
{
    public function __construct(
        public string $orderId,
        public int $totalCents,
        public string $currency,
        public DateTimeImmutable $confirmedAt,
        public EventMetadata $metadata
    ) {}
}

final readonly class EventMetadata
{
    public function __construct(
        public string $eventId,
        public DateTimeImmutable $occurredAt,
        public ?string $causationId = null,
        public ?string $correlationId = null,
        public int $version = 1
    ) {}
}

Event-Sourced Aggregate

final class Order extends EventSourcedAggregate
{
    private OrderStatus $status;
    private Money $total;

    public static function create(OrderId $id, CustomerId $customerId): self
    {
        $order = new self($id);
        $order->recordThat(new OrderCreatedEvent(
            orderId: $id->value,
            customerId: $customerId->value,
            createdAt: new DateTimeImmutable()
        ));
        return $order;
    }

    public function confirm(): void
    {
        if ($this->status !== OrderStatus::Draft) {
            throw new InvalidStateException();
        }
        $this->recordThat(new OrderConfirmedEvent(
            orderId: $this->id->value,
            totalCents: $this->total->cents(),
            currency: $this->total->currency(),
            confirmedAt: new DateTimeImmutable()
        ));
    }

    protected function applyOrderCreatedEvent(OrderCreatedEvent $event): void
    {
        $this->status = OrderStatus::Draft;
        $this->total = Money::zero('USD');
    }

    protected function applyOrderConfirmedEvent(OrderConfirmedEvent $event): void
    {
        $this->status = OrderStatus::Confirmed;
    }
}

Projection

final class OrderListProjection
{
    public function __construct(
        private Connection $connection
    ) {}

    public function applyOrderCreatedEvent(OrderCreatedEvent $event): void
    {
        $this->connection->insert('order_list', [
            'id' => $event->orderId,
            'customer_id' => $event->customerId,
            'status' => 'draft',
            'created_at' => $event->createdAt->format('Y-m-d H:i:s'),
        ]);
    }

    public function applyOrderConfirmedEvent(OrderConfirmedEvent $event): void
    {
        $this->connection->update('order_list', [
            'status' => 'confirmed',
            'total_cents' => $event->totalCents,
            'confirmed_at' => $event->confirmedAt->format('Y-m-d H:i:s'),
        ], ['id' => $event->orderId]);
    }
}

References

For detailed information, load these reference files:

  • references/event-store-patterns.md — Event persistence, streams, concurrency
  • references/projection-patterns.md — Read model projections
  • references/snapshot-patterns.md — Performance optimization with snapshots
  • references/versioning-patterns.md — Event schema evolution
  • references/antipatterns.md — Common violations with detection patterns