원클릭으로
command-generator
Use when creating a new CQRS command with handler and FluentValidation validator.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Use when creating a new CQRS command with handler and FluentValidation validator.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Use when designing gRPC services, proto files, or adding gRPC-Web or JSON transcoding.
Use when writing async code, propagating CancellationTokens, or fixing async/await pitfalls.
Use when applying or enforcing C# coding style — namespaces, sealed classes, var usage, XML docs.
Use when applying modern C# idioms — records, pattern matching, primary constructors, collection expressions.
Use when registering services, choosing lifetimes, or implementing DI patterns like decorator or keyed services.
Use when selecting or implementing design patterns in C# — factory, builder, strategy, decorator, or mediator.
| name | command-generator |
| description | Use when creating a new CQRS command with handler and FluentValidation validator. |
| metadata | {"category":"cqrs","agent":"ef-specialist"} |
| when_to_use | When generating CQRS command records with handler and validator scaffolding |
namespace {Company}.{Domain}.Application.Features.Orders.Commands.Create;
public sealed record CreateOrderCommand(
string CustomerName,
decimal Total,
List<CreateOrderItemDto> Items) : IRequest<Result<Guid>>;
public sealed record CreateOrderItemDto(
string ProductName,
int Quantity,
decimal UnitPrice);
namespace {Company}.{Domain}.Application.Features.Orders.Commands.Create;
internal sealed class CreateOrderCommandValidator
: AbstractValidator<CreateOrderCommand>
{
public CreateOrderCommandValidator()
{
RuleFor(x => x.CustomerName)
.NotEmpty().WithMessage("Customer name is required")
.MaximumLength(200);
RuleFor(x => x.Total)
.GreaterThan(0).WithMessage("Total must be positive");
RuleFor(x => x.Items)
.NotEmpty().WithMessage("At least one item is required");
RuleForEach(x => x.Items).ChildRules(item =>
{
item.RuleFor(i => i.ProductName).NotEmpty();
item.RuleFor(i => i.Quantity).GreaterThan(0);
item.RuleFor(i => i.UnitPrice).GreaterThan(0);
});
}
}
namespace {Company}.{Domain}.Application.Features.Orders.Commands.Create;
internal sealed class CreateOrderCommandHandler(
IUnitOfWork unitOfWork)
: IRequestHandler<CreateOrderCommand, Result<Guid>>
{
public async Task<Result<Guid>> Handle(
CreateOrderCommand request, CancellationToken cancellationToken)
{
var order = Order.Create(
request.CustomerName,
request.Total,
request.Items.Select(i => new OrderItem(
i.ProductName, i.Quantity, i.UnitPrice)).ToList());
await unitOfWork.Orders.AddAsync(order, cancellationToken);
await unitOfWork.SaveChangesAsync(cancellationToken);
return Result<Guid>.Success(order.Id);
}
}
public sealed record UpdateOrderCommand(
Guid Id,
string CustomerName,
decimal Total) : IRequest<Result>;
internal sealed class UpdateOrderCommandHandler(
IUnitOfWork unitOfWork)
: IRequestHandler<UpdateOrderCommand, Result>
{
public async Task<Result> Handle(
UpdateOrderCommand request, CancellationToken cancellationToken)
{
var order = await unitOfWork.Orders.FindAsync(
request.Id, cancellationToken);
if (order is null)
return Result.Failure("Order not found");
order.Update(request.CustomerName, request.Total);
await unitOfWork.SaveChangesAsync(cancellationToken);
return Result.Success();
}
}
public sealed record DeleteOrderCommand(Guid Id) : IRequest<Result>;
internal sealed class DeleteOrderCommandHandler(
IUnitOfWork unitOfWork)
: IRequestHandler<DeleteOrderCommand, Result>
{
public async Task<Result> Handle(
DeleteOrderCommand request, CancellationToken cancellationToken)
{
var order = await unitOfWork.Orders.FindAsync(
request.Id, cancellationToken);
if (order is null)
return Result.Failure("Order not found");
unitOfWork.Orders.Remove(order);
await unitOfWork.SaveChangesAsync(cancellationToken);
return Result.Success();
}
}
Application/Features/Orders/Commands/
├── Create/
│ ├── CreateOrderCommand.cs
│ ├── CreateOrderCommandValidator.cs
│ └── CreateOrderCommandHandler.cs
├── Update/
│ ├── UpdateOrderCommand.cs
│ ├── UpdateOrderCommandValidator.cs
│ └── UpdateOrderCommandHandler.cs
└── Delete/
├── DeleteOrderCommand.cs
└── DeleteOrderCommandHandler.cs
| Anti-Pattern | Correct Approach |
|---|---|
| Command with mutable properties | Use sealed record (immutable) |
| Validation in handler | Use FluentValidation + pipeline behavior |
| Returning domain entity from handler | Return Result<T> with ID or DTO |
| Handler accessing DbContext directly | Use IUnitOfWork or IRepository |
grep -r "IRequest<\|IRequestHandler<" --include="*.cs"
grep -r "AbstractValidator<" --include="*.cs"
AddMediatR and AddValidatorsFromAssemblyValidationBehavior<,> pipeline behavior