dotnet-cqrs/CLAUDE.md
Svrnty 2ff8eae75c docs: update CLAUDE.md via perfecto
🤖 Generated with [Claude Code](https://claude.ai/claude-code)

Co-Authored-By: Svrnty Inc. <eng@svrnty.com>
2026-02-28 17:35:42 -05:00

5.8 KiB

dotnet-cqrs -- Development Guide

Overview

Svrnty.CQRS — modern CQRS implementation for .NET 10. Forked from PoweredSoft.CQRS. Provides command/query handlers exposed via HTTP (Minimal API) or gRPC (source-generated), dynamic query capabilities, FluentValidation with RFC 7807 (HTTP) and Google Rich Error Model (gRPC).

Tech Stack

  • Framework: .NET 10 / C# 14
  • Packages: 10 NuGet packages + 1 sample project
  • gRPC: Grpc.AspNetCore 2.68+, source-generated service implementations
  • Validation: FluentValidation 11.11.0
  • Dynamic queries: PoweredSoft.DynamicQuery 3.0.1

Build & Test

# Restore dependencies
dotnet restore

# Build entire solution
dotnet build

# Build in Release mode
dotnet build -c Release

# Create NuGet packages
dotnet pack -c Release -o ./artifacts -p:Version=1.0.0

No test projects currently. When adding tests: tests/ directory, .Tests suffix.

Solution Structure

Abstractions (interfaces only):

  • Svrnty.CQRS.Abstractions — Core interfaces (ICommandHandler, IQueryHandler)
  • Svrnty.CQRS.DynamicQuery.Abstractions — Dynamic query interfaces (multi-targets netstandard2.1 + net10.0)
  • Svrnty.CQRS.Grpc.Abstractions — gRPC-specific contracts

Implementation:

  • Svrnty.CQRS — Core discovery and registration
  • Svrnty.CQRS.MinimalApi — HTTP endpoint mapping
  • Svrnty.CQRS.DynamicQuery — PoweredSoft.DynamicQuery integration
  • Svrnty.CQRS.DynamicQuery.MinimalApi — Dynamic query HTTP endpoints
  • Svrnty.CQRS.FluentValidation — Validation helpers
  • Svrnty.CQRS.Grpc — gRPC service support
  • Svrnty.CQRS.Grpc.Generators — Source generator for .proto + gRPC service implementations

Sample: Svrnty.Sample — HTTP + gRPC demo

Architecture

Metadata-Driven Discovery

  1. services.AddCommand<TCommand, THandler>() registers handler + creates ICommandMeta
  2. ICommandDiscovery / IQueryDiscovery query all registered metadata from DI
  3. Endpoint mapping (HTTP/gRPC) uses discovery to dynamically generate endpoints at startup

Integration Options

  • gRPC (recommended for performance): Source-generated CommandServiceImpl / QueryServiceImpl
  • HTTP (recommended for web): MapSvrntyCommands() / MapSvrntyQueries() via Minimal API
  • Both: Dual protocol support in single codebase

Dynamic Query System

  • IDynamicQuery<TSource, TDestination> with filters, sorts, groups, aggregates
  • IQueryableProvider<TSource> provides base IQueryable
  • IAlterQueryableService<TSource, TDestination> for middleware (security filters)
  • Up to 5 interceptors per query type

Conventions

  • Abstractions contain ONLY interfaces/attributes with minimal dependencies
  • Handler naming: strip "Command"/"Query" suffix, convert to lowerCamelCase (e.g. CreatePersonCommandcreatePerson)
  • All handlers are async with CancellationToken support
  • Endpoint mapping happens at startup — discovery must be registered first
  • FluentValidation: HTTP returns RFC 7807, gRPC returns Google Rich Error Model

Key Files

  • Handler interfaces: Svrnty.CQRS.Abstractions/ICommandHandler.cs, IQueryHandler.cs
  • Discovery: Svrnty.CQRS/Discovery/
  • Registration: */ServiceCollectionExtensions.cs
  • HTTP endpoints: Svrnty.CQRS.MinimalApi/EndpointRouteBuilderExtensions.cs
  • gRPC generators: Svrnty.CQRS.Grpc.Generators/

Publishing

NuGet packages via GitHub Actions on release: .github/workflows/publish-nugets.yml

What NOT to Do

  • Do NOT modify abstractions projects to add implementation dependencies
  • Do NOT skip CancellationToken in handler signatures
  • Do NOT call MapSvrntyCommands() before registering discovery services
  • Do NOT add heavy dependencies to abstractions packages

Critical Rules

Commit Authorship

All AI-authored commits MUST use:

Co-Authored-By: Svrnty Inc. <eng@svrnty.com>

NEVER use:

  • Third-party AI tool names (e.g. "Claude") in any Co-Authored-By
  • Third-party AI company names (e.g. "Anthropic") in any Co-Authored-By
  • Third-party AI tool names in commit messages

Documentation References

  • Do NOT reference third-party AI tool names as product names in any documentation
  • Use "agent runtime", "agent CLI", or "Svrnty runtime" instead
  • CLAUDE.md files keep their filename (industry standard) but content must not mention third-party AI tool names as products

Branch Strategy

  • All repos use the JP branch for active development
  • Always check which branch you're on before committing

Cross-Repo Changes

  • If a change spans multiple repos, commit to each repo separately
  • Reference the related repo in commit messages when relevant
  • Run tests in each affected repo before committing

Documentation Triad

This repo maintains three canonical files. Keep them in sync.

PROJECT.md — What & Why

  • User perspective. No code, no architecture.
  • Update when: features added/removed, scope changes, user-facing behaviour changes.

GRAPH.md — Architecture

  • Unicode cascade diagrams. Entire file IS the diagram.
  • Update when: modules added/removed, data flow changes, API surface changes.

CLAUDE.md — How to Work Here

  • Assembled by perfecto from shared fragments + repo body.
  • To update repo content: edit perfecto/repo/<name>.body.md then run perfecto build <name>
  • To update shared conventions: edit JP/CLAUDE.md, update perfecto/shared/, then run perfecto build --all

GRAPH.md Maintenance

This repo contains a GRAPH.md file with unicode cascade diagrams showing the architecture. You MUST update GRAPH.md whenever you:

  • Add, remove, or rename modules, directories, or major components
  • Change data flow, dependencies, or integration points
  • Modify the public API surface or protocol contracts

Keep the diagrams accurate. They are read by non-technical stakeholders.