skills/cqrs-event-sourcing-architect/SKILL.md
CQRS pattern, event stores, projections, eventual consistency. Activate on: CQRS, event sourcing, event store, read model, projection, aggregate, domain event, command handler. NOT for: message broker setup (use event-driven-architecture-expert), database optimization (use data-warehouse-optimizer).
npx skillsauth add curiositech/windags-skills cqrs-event-sourcing-architectInstall 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.
Design systems that separate read/write models and derive state from immutable event logs using EventStoreDB, Marten, or custom stores.
Activate on: "CQRS", "event sourcing", "event store", "read model", "projection", "aggregate", "domain event", "command handler", "EventStoreDB", "Marten"
NOT for: Message broker infrastructure → event-driven-architecture-expert | Database query optimization → data-warehouse-optimizer | API design → api-architect
OrderPlaced, ItemShipped| Domain | Technologies | |--------|-------------| | Event Stores | EventStoreDB 24.x, Marten 7.x, custom PostgreSQL | | Frameworks | NestJS CQRS, Axon (JVM), Eventuous, Commanded (Elixir) | | Projections | In-memory, PostgreSQL views, Elasticsearch, Redis | | Serialization | JSON with versioned schemas, Protobuf | | Testing | Given-When-Then event test pattern |
Command Side Query Side
───────────── ──────────
POST /orders GET /orders/:id
↓ ↑
Command Handler Read Model (Postgres/ES)
↓ ↑
Aggregate.apply(event) Projection Handler
↓ ↑
Event Store (append) ──────→ Event Subscription
class OrderAggregate {
private status: 'draft' | 'placed' | 'shipped' = 'draft';
private items: OrderItem[] = [];
private uncommitted: DomainEvent[] = [];
place(command: PlaceOrderCommand): void {
if (this.status !== 'draft') throw new Error('Order already placed');
this.apply(new OrderPlaced({ orderId: command.orderId, items: command.items }));
}
private apply(event: DomainEvent): void {
this.when(event); // mutate state
this.uncommitted.push(event); // track for persistence
}
private when(event: DomainEvent): void {
if (event instanceof OrderPlaced) {
this.status = 'placed';
this.items = event.items;
}
}
static rehydrate(events: DomainEvent[]): OrderAggregate {
const agg = new OrderAggregate();
events.forEach(e => agg.when(e));
return agg;
}
}
1. Stop projection subscription
2. Drop/truncate read model table
3. Replay all events from position 0
4. Resume subscription at current position
Key: projections are disposable — the event log is the source of truth
OrderUpdated are useless; capture what changed specificallydata-ai
license: Apache-2.0 NOT for unrelated tasks outside this domain.
development
Use when designing caching strategies (cache-aside, write-through, write-behind), implementing distributed locks, building rate limiters, leaderboards, real-time streams (XADD/consumer groups), pub/sub, or tuning eviction policies. Triggers: thundering-herd on cache miss, dogpile on key expiry, Redlock vs SET-NX-PX choice, sliding-window rate limiter, hot-key on a single cluster slot, big-key blowup, MULTI/EXEC across slots, KEYS in production. NOT for Redis Cluster operations/admin (different domain), embedded KV (SQLite, leveldb), in-process LRU caches, or Memcached.
tools
Drawing the `'use client'` boundary correctly in React Server Components apps (Next.js App Router, RSC frameworks) — leaf-pushing, slot composition, serialization rules, and environment poisoning prevention. Grounded in react.dev and Next.js 16 docs.
development
Use when designing rate limiting for an API, choosing between token bucket / sliding window / leaky bucket / fixed window, implementing it in Redis, deciding edge (Cloudflare/Upstash) vs origin enforcement, sizing per-user vs per-IP vs per-endpoint quotas, returning the right 429 response with Retry-After, or fixing the boundary-burst bug in fixed-window limiters. Triggers: 429 too many requests, INCR + EXPIRE, ZADD + ZREMRANGEBYSCORE + ZCARD, X-RateLimit-Remaining header, Cloudflare WAF rate limiting rules, Upstash @upstash/ratelimit, leaky bucket shaping vs policing, distributed rate limiter consistency. NOT for DDoS mitigation specifically (different scale), CAPTCHA / bot management, full WAF design, or per-user quota billing.