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

87 lines
2.3 KiB
Markdown

---
name: add-query
description: 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.
argument-hint: <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`:
```csharp
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
```csharp
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)
```protobuf
// 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.