ACTIVATE when implementing domain events, event store, outbox pattern, or reliable event publishing in TypeScript. ACTIVATE for 'domain event', 'outbox', 'event store', 'event-driven', 'reliable publishing'. Covers: domain event structure and naming, event store (append-only), outbox pattern for reliable publishing (no dual-write), consumer pattern. DO NOT use for: aggregate modeling (see ddd-ts-fp), general async patterns, message queue configuration.
From typescriptnpx claudepluginhub fabiensalles/claude-marketplace --plugin typescriptThis skill uses the workspace's default tool permissions.
references/event-implementation-patterns.mdSearches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Searches prompts.chat for AI prompt templates by keyword or category, retrieves by ID with variable handling, and improves prompts via AI. Use for discovering or enhancing prompts.
Compares coding agents like Claude Code and Aider on custom YAML-defined codebase tasks using git worktrees, measuring pass rate, cost, time, and consistency.
A business fact that occurred in the past. Named in past tense, immutable:
type ReceiptGenerated = {
readonly receiptId: string;
readonly tenantId: string;
readonly landlordId: string;
readonly period: { year: number; month: number };
readonly amount: number;
readonly generatedAt: Date;
};
| Element | Convention | Example |
|---|---|---|
| Type | PascalCase past tense | ReceiptGenerated, LeaseTerminated |
| File | kebab-case.event.ts | receipt-generated.event.ts |
| Directory | domain/events/ | Co-located with the aggregate |
type DomainEvent<T> = {
readonly id: string; // UUID unique
readonly type: string; // 'receipt.generated'
readonly timestamp: Date;
readonly version: string; // '1.0' -- for versioning
readonly metadata?: Record<string, string>;
readonly data: T; // Payload type
};
Persist events as source of truth. Append-only, never delete.
Guarantees reliable event publishing. The event is persisted in an outbox table atomically with the state change, then published asynchronously:
Command -> Domain Logic -> Transaction {
1. Persist aggregate state
2. Insert event in outbox table <- atomic
}
Worker -> Poll outbox -> Publish event -> Mark as processed
Status flow: created -> in_progress -> processed / failed
When implementing event store persistence, outbox tables, or outbox publishers, read
references/event-implementation-patterns.mdfor complete Drizzle schemas and publisher implementations.
When emitting events from handlers or writing consumers, read
references/event-implementation-patterns.mdfor atomic transaction patterns and consumer examples.
| Pattern | Use case |
|---|---|
| Domain Event | Business fact to communicate between bounded contexts |
| Event Store | Audit trail, replay, event sourcing |
| Outbox | Reliable publishing without dual-write |
| Consumer | Asynchronous reaction to an event |
| Rule | Convention |
|---|---|
| Naming | Past tense (ReceiptGenerated) |
| Structure | { id, type, timestamp, version, data } |
| Event Store | Append-only, domain_events table |
| Outbox | Atomic with state change |
| Status | created -> in_progress -> processed / failed |
| Retries | numberOfRetries + maxNumberOfRetries |
| Consumer | Idempotent, null-safe |