Awesome-claude-code create-snapshot

Generates Snapshot pattern for PHP 8.4. Creates aggregate snapshot infrastructure for event sourcing performance optimization with configurable strategies and version tracking. Includes unit tests.

install
source · Clone the upstream repo
git clone https://github.com/dykyi-roman/awesome-claude-code
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/dykyi-roman/awesome-claude-code "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/create-snapshot" ~/.claude/skills/dykyi-roman-awesome-claude-code-create-snapshot && rm -rf "$T"
manifest: skills/create-snapshot/SKILL.md
source content

Snapshot Generator

Creates Snapshot infrastructure for optimizing event sourcing aggregate rebuilds.

When to Use

ScenarioExample
Long event streamsAggregates with 100+ events in their history
Slow aggregate rebuildEvent replay taking too long for read operations
Frequent readsAggregates loaded many times per second
Large aggregatesComplex state requiring many events to reconstruct

Component Characteristics

Snapshot

  • Immutable state capture of an aggregate at a point in time
  • Properties: aggregateId, aggregateType, version, state (JSON), createdAt
  • Supports
    fromArray()
    /
    toArray()
    for serialization
  • Version must be >= 1

SnapshotStoreInterface

  • save(Snapshot $snapshot): void
    — persist snapshot (upsert)
  • load(string $aggregateId): ?Snapshot
    — retrieve latest snapshot
  • delete(string $aggregateId): void
    — remove all snapshots for aggregate

SnapshotStrategy

  • Configurable event threshold (default: 100)
  • shouldTakeSnapshot(int $eventsSinceLastSnapshot): bool
  • Determines when a new snapshot should be captured

AggregateSnapshotter

  • Application service coordinating snapshot operations
  • Loads aggregate from snapshot + remaining events
  • Takes snapshots when strategy threshold is met

Generation Process

Step 1: Generate Domain Components

Path:

src/Domain/{BC}/Snapshot/

  1. Snapshot.php
    — Immutable snapshot value object
  2. SnapshotStoreInterface.php
    — Repository interface for snapshot persistence

Step 2: Generate Application Components

Path:

src/Application/{BC}/Snapshot/

  1. SnapshotStrategy.php
    — Configurable threshold strategy
  2. AggregateSnapshotter.php
    — Application service for snapshot operations

Step 3: Generate Infrastructure Components

Path:

src/Infrastructure/{BC}/Snapshot/

  1. DoctrineSnapshotStore.php
    — Doctrine DBAL implementation of SnapshotStoreInterface
  2. Database migration SQL for snapshots table

Step 4: Generate Tests

  1. SnapshotTest.php
    — Construction, serialization, validation tests
  2. SnapshotStrategyTest.php
    — Threshold behavior tests
  3. AggregateSnapshotterTest.php
    — Load and take snapshot tests

File Placement

ComponentPath
Snapshot, SnapshotStoreInterface
src/Domain/{BC}/Snapshot/
SnapshotStrategy, AggregateSnapshotter
src/Application/{BC}/Snapshot/
DoctrineSnapshotStore
src/Infrastructure/{BC}/Snapshot/
Unit Tests
tests/Unit/Domain/{BC}/Snapshot/
,
tests/Unit/Application/{BC}/Snapshot/

Naming Conventions

ComponentPatternExample
Value Object
Snapshot
Snapshot
Store Interface
SnapshotStoreInterface
SnapshotStoreInterface
Strategy
SnapshotStrategy
SnapshotStrategy
Application Service
AggregateSnapshotter
AggregateSnapshotter
Infrastructure Store
DoctrineSnapshotStore
DoctrineSnapshotStore
Test
{ClassName}Test
SnapshotTest

Quick Template Reference

Snapshot

final readonly class Snapshot
{
    public function __construct(
        public string $aggregateId,
        public string $aggregateType,
        public int $version,
        public string $state,
        public \DateTimeImmutable $createdAt
    ) {
        // version >= 1 validation
    }

    public static function fromArray(array $data): self;
    public function toArray(): array;
}

SnapshotStoreInterface

interface SnapshotStoreInterface
{
    public function save(Snapshot $snapshot): void;
    public function load(string $aggregateId): ?Snapshot;
    public function delete(string $aggregateId): void;
}

SnapshotStrategy

final readonly class SnapshotStrategy
{
    public function __construct(
        private int $eventThreshold = 100
    ) {}

    public function shouldTakeSnapshot(int $eventsSinceLastSnapshot): bool;
}

Usage Example

$snapshotter = new AggregateSnapshotter($snapshotStore, $strategy);

// Load aggregate from snapshot + remaining events
$result = $snapshotter->loadWithSnapshot($aggregateId, $eventStore);
$snapshot = $result['snapshot'];
$remainingEvents = $result['remainingEvents'];

$aggregate = $snapshot !== null
    ? Order::fromSnapshot($snapshot)
    : new Order($aggregateId);

foreach ($remainingEvents as $event) {
    $aggregate->apply($event);
}

// Take snapshot if threshold reached
$snapshotter->takeSnapshotIfNeeded(
    aggregateId: $aggregateId,
    aggregateType: 'Order',
    version: $aggregate->getVersion(),
    state: $aggregate->toSnapshot(),
    eventsSinceSnapshot: count($remainingEvents)
);

Database Schema

CREATE TABLE snapshots (
    id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    aggregate_id VARCHAR(36) NOT NULL,
    aggregate_type VARCHAR(255) NOT NULL,
    version INT UNSIGNED NOT NULL,
    state JSON NOT NULL,
    created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    UNIQUE INDEX idx_snapshots_aggregate_id (aggregate_id),
    INDEX idx_snapshots_aggregate_type (aggregate_type)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

Anti-patterns to Avoid

Anti-patternProblemSolution
Snapshot Every EventStorage bloat, no performance gainUse threshold strategy (e.g., every 100 events)
Mutable SnapshotsState corruption, debugging nightmaresMake Snapshot immutable (final readonly)
Missing VersionCannot determine event replay start pointAlways track version in snapshot
No CleanupUnbounded storage growthImplement retention policy, keep only latest
Tight CouplingSnapshot tied to infrastructureDomain interface, infrastructure implementation
Skipping ValidationInvalid snapshots persistedValidate version >= 1, non-empty state

References

For complete PHP templates and examples, see:

  • references/templates.md
    — Snapshot, SnapshotStoreInterface, SnapshotStrategy, AggregateSnapshotter, DoctrineSnapshotStore templates
  • references/examples.md
    — OrderAggregate integration, event sourcing examples and tests