dotnet-cqrs/.claude/skills/add-query/SKILL.md
Mathias Beaulieu-Duncan a4525bad6a Add Claude Code harness: rules, skills, hooks, and editorconfig
- Add path-specific rules for commands/queries, dynamic queries, validation, and gRPC
- Add /add-command, /add-query, /add-dynamic-query scaffolding skills
- Add project settings with post-edit formatting, proto validation, and build-gate hooks
- Add .editorconfig codifying existing code style conventions
- Trim CLAUDE.md from 414 to 130 lines (domain details moved to rules)
- Add .harness-version tracking for the shared claude-harness repo

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 03:30:27 -04:00

2.3 KiB

name description argument-hint
add-query Scaffold a new regular CQRS query with handler and DI registration. Use ONLY for single-entity lookups or non-queryable results. For list/collection queries, use /add-dynamic-query instead. <description of the query in natural language>

Add Query

Scaffold a new regular query based on: $ARGUMENTS

Important: Is This the Right Skill?

This skill is for the rare case. Most queries should be dynamic queries (/add-dynamic-query).

Only use this for:

  • Single entity by ID (e.g., FetchOrderByIdQuery)
  • Non-entity results (e.g., GetDashboardStatsQuery, CheckAvailabilityQuery)
  • Complex aggregation not expressible as IQueryable

If the user is asking for a list/collection query with filtering, sorting, or pagination → suggest /add-dynamic-query instead.

Instructions

1. Determine the query name

Use descriptive, domain-oriented names:

  • FetchOrderByIdQuery — fetching a single entity
  • GetSystemHealthQuery — non-entity result
  • CheckInventoryAvailabilityQuery — domain-specific check

2. Determine the feature folder

Place the file in: Features/{DomainArea}/

3. Create the file

Create Features/{DomainArea}/{QueryName}Query.cs:

using Svrnty.CQRS.Abstractions;

namespace {ProjectNamespace}.Features.{DomainArea};

// 1. Query POCO
public record {QueryName}Query
{
    // Parameters — e.g., Id for lookups
}

// 2. Handler
public class {QueryName}QueryHandler : IQueryHandler<{QueryName}Query, {ResultType}>
{
    public Task<{ResultType}> HandleAsync({QueryName}Query query, CancellationToken cancellationToken = default)
    {
        throw new NotImplementedException();
    }
}

4. Register in DI

builder.Services.AddQuery<{QueryName}Query, {ResultType}, {QueryName}QueryHandler>();

// With validator (if needed)
builder.Services.AddQuery<{QueryName}Query, {ResultType}, {QueryName}QueryHandler, {QueryName}QueryValidator>();

5. Proto message (if project uses gRPC)

// In the QueryService definition
rpc {QueryName} ({QueryName}QueryRequest) returns ({QueryName}QueryResponse);

message {QueryName}QueryRequest {
  // fields matching query properties
}

message {QueryName}QueryResponse {
  {ResultMessage} result = 1;
}

6. Summary

After creating everything, list what was created and where.