cqrs
Skill0 starsChanged 23 days agoMITView on GitHub
Command Query Responsibility Segregation patterns for separating write and read models.
3 other projects use a version of this.
Adopted by
Most recently taken up by
- AnyOrgName/php-skillstheir own version, first seen Nov 8, 2026
- TheBeardedBearSAS/claude-crafttheir own version, first seen Oct 29, 2026
- G1Joshi/Agent-Skillstheir own version, first seen Oct 13, 2026
Other versions3 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 3
- TheBeardedBearSAS/claude-craft★ 108same name
- G1Joshi/Agent-Skills★ 15same name
- AnyOrgName/php-skills★ 4same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository32 other files it gives its agents.
- .claude/CLAUDE.mdCLAUDE.md
- api-designSkill
- arch-constraint-guardSkill
- backend-patternsSkill
- clean-architectureSkill
- codebase-mappingSkill
- context-budgetSkill
- ddd-architectureSkill
- debug-flowSkill
- dependency-auditSkill
- django-patternsSkill
- django-tddSkill
- event-driven-architectureSkill
- fd-codenavSkill
- fd-mapSkill
- frontend-patternSkill
- git-releaseSkill
- git-workflowSkill
- golang-patternsSkill
- hexagonal-architectureSkill
- java-patternsSkill
- layered-architectureSkill
- performance-profilingSkill
- postgres-patternsSkill
- python-patternsSkill
- refactor-guideSkill
- research-firstSkill
- rust-patternsSkill
- saga-architectureSkill
- security-scanSkill
- tdd-workflowSkill
- test-gap-detectorSkill
The file
We split this skill into the rules it gives an agent
6 rules. About 0 are common, 6 are distinctive, and 0 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈6
Distinctive · estimate
This author's own choices. Worth a look.
0
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 36
Keep command handlers small and focused
- Distinctive: line 78
When commands and queries share data:
- Distinctive: line 82
Dual writes: Update both models, handle eventual consistency
- Distinctive: line 108
If read and write models are updated asynchronously:
- Distinctive: line 110
Document expected consistency lag
- Distinctive: line 113
Use version numbers or timestamps for cache validation
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
CQRS (Command Query Responsibility Segregation)
When to Activate
Activate when:
- Designing read-heavy or write-heavy systems separately
- Implementing complex domain models with divergent read/write logic
- Building systems that need different data representations for reading vs. writing
- Scaling read and write workloads independently
- Implementing event sourcing alongside specialized read models
Steps
1. Separate Command and Query Models
| Aspect | Command | Query |
| Purpose | Modify state | Read state |
| Returns | Void / ACK | Data |
| Side Effects | Yes | No |
| Complexity | Business logic | Data shaping |
Commands and queries should use different models with different schemas optimized for their specific use case.
2. Design Command Side
- Commands are intent-based (present tense:
PlaceOrder,UpdatePrice) - Validate business rules before executing
- Return success/failure, not data
- Keep command handlers small and focused
interface Command {
id: string; // Correlation ID
type: string; // Command type
payload: unknown; // Command data
metadata: {
userId: string;
timestamp: string;
correlationId: string;
};
}
interface CommandHandler<T extends Command> {
execute(command: T): Promise<CommandResult>;
}3. Design Query Side
- Queries are data-focused (past/read tense:
GetUserOrders,FindActiveProducts) - Queries should be side-effect free
- Return read-optimized data structures (possibly denormalized)
- Support pagination, filtering, sorting
interface Query {
id: string;
type: string;
parameters: Record<string, unknown>;
pagination?: { page: number; limit: number };
sorting?: { field: string; direction: 'asc' | 'desc' }[];
}
interface QueryHandler<T extends Query> {
execute(query: T): Promise<QueryResult>;
}4. Implement Synchronization
When commands and queries share data:
- Synchronous (same DB): Update the read model transactionally
- Asynchronous (event-driven): Project events to read models
- Dual writes: Update both models, handle eventual consistency
// Synchronous synchronization
async function placeOrder(command: PlaceOrderCommand): Promise<void> {
const order = Order.create(command.payload);
await this.transactionManager.execute(async (tx) => {
// Write to command model
await this.orderRepo.save(order, tx);
// Synchronize to read model
const readModel = {
orderId: order.id,
customerId: order.customerId,
status: order.status,
total: order.total,
placedAt: order.placedAt
};
await this.orderReadRepo.save(readModel, tx);
});
}5. Handle Eventual Consistency
If read and write models are updated asynchronously:
- Document expected consistency lag
- Design UIs to handle stale data gracefully
- Implement cache invalidation strategies
- Use version numbers or timestamps for cache validation
Examples
Command Implementation
// commands/place-order.command.ts
interface PlaceOrderCommand {
orderId?: string; // Optional, generated if not provided
customerId: string;
items: OrderItem[];
paymentMethod: 'CARD' | 'PAYPAL';
}
class PlaceOrderCommandHandler implements CommandHandler<PlaceOrderCommand> {
async execute(command: PlaceOrderCommand): Promise<CommandResult> {
// 1. Validate command
const validation = this.validate(command);
if (!validation.success) {
return CommandResult.failure(validation.errors);
}
// 2. Check business invariants
const customer = await this.customerRepo.findById(command.customerId);
if (!customer.isActive) {
return CommandResult.failure('Customer account is not active');
}
// 3. Create aggregate
const order = Order.create({
id: command.orderId,
customerId: command.customerId,
items: command.items
});
// 4. Persist
await this.orderRepo.save(order);
// 5. Emit event for async processing
await this.eventBus.publish(OrderPlacedEvent.fromOrder(order));
return CommandResult.success({ orderId: order.id });
}
}Query Implementation
// queries/get-order-details.query.ts
interface GetOrderDetailsQuery {
orderId: string;
includeItems?: boolean;
}
interface OrderDetailsReadModel {
orderId: string;
customerId: string;
customerName: string;
status: string;
total: number;
placedAt: string;
items?: OrderItemReadModel[];
}
class GetOrderDetailsQueryHandler implements QueryHandler<GetOrderDetailsQuery, OrderDetailsReadModel> {
async execute(query: GetOrderDetailsQuery): Promise<OrderDetailsReadModel> {
const order = await this.readModelRepo.findOrderWithDetails(query.orderId);
if (!order) {
throw new QueryNotFoundError('Order not found');
}
const result: OrderDetailsReadModel = {
orderId: order.orderId,
customerId: order.customerId,
customerName: order.customerName,
status: order.status,
total: order.total,
placedAt: order.placedAt
};
if (query.includeItems) {
result.items = await this.readModelRepo.findOrderItems(query.orderId);
}
return result;
}
}Mediator Pattern for CQRS
class CqrsMediator {
private commandHandlers: Map<string, CommandHandler<any>>;
private queryHandlers: Map<string, QueryHandler<any>>;
async send<T>(message: Command | Query): Promise<CommandResult | QueryResult> {
const handler = message instanceof Command
? this.commandHandlers.get(message.type)
: this.queryHandlers.get(message.type);
if (!handler) {
throw new HandlerNotFoundError(message.type);
}
return handler.execute(message);
}
}
// Usage
const result = await mediator.send(new PlaceOrderCommand({ ... }));
const orderDetails = await mediator.send(new GetOrderDetailsQuery({ orderId: '123' }));Related Skills
- api-design
- event-driven-architecture
- backend-patterns
- event-sourcing
- hexagonal-architecture
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

