dotnet-cqrs/CLAUDE.md
Svrnty 7e12f73160 docs: add perfecto-managed documentation triad v1.0.0
Co-Authored-By: Svrnty Inc. <eng@svrnty.com>
2026-02-28 12:33:15 -05:00

158 lines
5.8 KiB
Markdown

<!-- perfecto:v1.0.0:2026-02-28 -->
# 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
```bash
# 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. `CreatePersonCommand``createPerson`)
- 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.