원클릭으로
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 adding caching to .NET APIs or optimizing response times with distributed cache, output cache, or ETags.
Use when configuring API response formats, custom formatters, or Accept header handling.
Use when building controller-based REST APIs with action results, model binding, or MediatR integration.
Use when creating RESTful API controllers with MediatR dispatch and ProblemDetails error responses.
Use when designing gRPC services, proto files, or adding gRPC-Web or JSON transcoding.
Use when building minimal API endpoints with route groups, filters, or TypedResults.
| 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