ts-ddd-cqrslisted
Install: claude install-skill Methasit-Pun/ts-ddd-clean-architecture
# CQRS Pattern — TypeScript DDD
Implement the Command Query Responsibility Segregation pattern cleanly within the Application layer. Commands mutate state; queries read state. They never cross.
## Core rule
> A method is either a **Command** (changes state, returns void or the aggregate ID) or a **Query** (returns data, changes nothing). Never both.
---
## Folder structure
```
src/[context]/
application/
commands/
[ActionName]/
[ActionName]Command.ts ← the DTO (plain data)
[ActionName]CommandHandler.ts
queries/
[QueryName]/
[QueryName]Query.ts
[QueryName]QueryHandler.ts
[QueryName]Result.ts ← typed read model
ports/
ICommandBus.ts
IQueryBus.ts
```
---
## Command implementation
### Command DTO
```typescript
// Commands are plain data bags — no methods, no logic
export class CreateOrderCommand {
constructor(
public readonly customerId: string,
public readonly items: { productId: string; quantity: number }[],
) {}
}
```
### Command Handler
```typescript
// Handler lives in Application layer — it orchestrates, never contains business logic
export class CreateOrderCommandHandler {
constructor(
private readonly orderRepository: IOrderRepository, // domain interface
private readonly eventBus: IEventBus,
) {}
async execute(command: CreateOrderCommand): Promise<string> {
const order = Order.create(command.customerId, command.items); // domain logic here