Event sourcing patterns for storing state as a sequence of events. Use when implementing event-driven architectures, CQRS, audit trails, or building systems requiring full history reconstruction.
View on GitHubyonatangross/skillforge-claude-plugin
orchestkit-complete
January 23, 2026
Select agents to install to:
npx add-skill https://github.com/yonatangross/skillforge-claude-plugin/blob/main/./skills/event-sourcing/SKILL.md -a claude-code --skill event-sourcingInstallation paths:
.claude/skills/event-sourcing/# Event Sourcing Patterns
Store application state as immutable events rather than current state snapshots.
## Overview
- Full audit trail requirements (compliance, finance)
- Temporal queries ("what was state at time X?")
- CQRS implementations with separate read/write models
- Systems requiring event replay and debugging
- Microservices with eventual consistency
## Quick Reference
### Domain Event Base
```python
from pydantic import BaseModel, Field
from datetime import datetime, timezone
from uuid import UUID, uuid4
class DomainEvent(BaseModel):
event_id: UUID = Field(default_factory=uuid4)
aggregate_id: UUID
event_type: str
version: int
timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
class Config:
frozen = True # Events are immutable
```
### Event-Sourced Aggregate
```python
class Account:
def __init__(self):
self._changes, self._version, self.balance = [], 0, 0.0
def deposit(self, amount: float):
self._raise_event(MoneyDeposited(aggregate_id=self.id, amount=amount, version=self._version + 1))
def _apply(self, event):
match event:
case MoneyDeposited(): self.balance += event.amount
case MoneyWithdrawn(): self.balance -= event.amount
def load_from_history(self, events):
for e in events: self._apply(e); self._version = e.version
```
### Event Store Append
```python
async def append_events(self, aggregate_id: UUID, events: list, expected_version: int):
current = await self.get_version(aggregate_id)
if current != expected_version:
raise ConcurrencyError(f"Expected {expected_version}, got {current}")
for event in events:
await self.session.execute(insert(event_store).values(
event_id=event.event_id, aggregate_id=aggregate_id,
event_type=event.event_type, version=event.version, data=event.model_dump()
))
```
## Key Decisions
| Decision | Recommendation |
|----