- Use MediatR `IRequest<T>` for queries (return data) and `IRequest` for commands (no return value).
- Controllers dispatch via `IMediator.Send()` — no business logic in controllers.
- Separate read models (thin DTOs, denormalized views) from write models (rich domain entities) — use MediatR for dispatching commands and queries.
- Organize as `Features/Users/Commands/CreateUser.cs`, `Features/Users/Queries/GetUser.cs`.
- Use FluentValidation with MediatR pipeline behavior for automatic validation.
- Use `IPipelineBehavior<TRequest, TResponse>` for cross-cutting: logging, caching, transaction management.
- Keep handlers focused: one handler per command/query, one file per handler.