docs: standardize documentation structure
- CLAUDE.md: universal development guidelines - README.md: project description (consistent template) - CONTRIBUTING.md: contribution workflow - CHANGELOG.md: version history Co-Authored-By: Svrnty Inc. <eng@svrnty.com>
This commit is contained in:
@@ -1,155 +1,79 @@
|
||||
# dotnet-cqrs -- Development Guide
|
||||
# Development Guidelines
|
||||
|
||||
## Overview
|
||||
Universal development practices for all Svrnty/a-gent repositories.
|
||||
|
||||
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).
|
||||
## Engineering Principles
|
||||
|
||||
## Tech Stack
|
||||
### KISS (Keep It Simple)
|
||||
- Prefer straightforward control flow over clever meta-programming
|
||||
- Keep error paths obvious and localized
|
||||
|
||||
- **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
|
||||
### YAGNI (You Aren't Gonna Need It)
|
||||
- Do not add features without concrete accepted use case
|
||||
- Do not introduce speculative abstractions
|
||||
|
||||
## Build & Test
|
||||
### DRY + Rule of Three
|
||||
- Duplicate small logic when it preserves clarity
|
||||
- Extract shared utilities only after 3+ repeated patterns
|
||||
|
||||
```bash
|
||||
# Restore dependencies
|
||||
dotnet restore
|
||||
### SRP + ISP (Single Responsibility + Interface Segregation)
|
||||
- Keep each module focused on one concern
|
||||
- Avoid "god modules" mixing multiple responsibilities
|
||||
|
||||
# Build entire solution
|
||||
dotnet build
|
||||
### Fail Fast + Explicit Errors
|
||||
- Prefer explicit errors for unsupported states
|
||||
- Document fallback behavior when intentional
|
||||
|
||||
# Build in Release mode
|
||||
dotnet build -c Release
|
||||
### Secure by Default
|
||||
- Deny-by-default for access boundaries
|
||||
- Never log secrets or sensitive payloads
|
||||
|
||||
# Create NuGet packages
|
||||
dotnet pack -c Release -o ./artifacts -p:Version=1.0.0
|
||||
```
|
||||
## Agent Workflow
|
||||
|
||||
No test projects currently. When adding tests: `tests/` directory, `.Tests` suffix.
|
||||
1. **Read before write** - Inspect existing code before editing
|
||||
2. **Define scope** - One concern per PR
|
||||
3. **Implement minimal patch** - Apply KISS/YAGNI explicitly
|
||||
4. **Validate** - Run lint, format, test before commit
|
||||
5. **Document impact** - Note behavior changes and risks
|
||||
|
||||
## Solution Structure
|
||||
## Branch Strategy
|
||||
|
||||
**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
|
||||
- All repos use `JP` branch for active development
|
||||
- Always verify current branch before committing
|
||||
|
||||
**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
|
||||
## Commit Rules
|
||||
|
||||
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
|
||||
NEVER use third-party AI tool/company names in commits.
|
||||
|
||||
### Documentation References
|
||||
## PR Discipline
|
||||
|
||||
- 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
|
||||
- Clear, scoped commit messages
|
||||
- Small PRs preferred
|
||||
- Never commit personal/sensitive data
|
||||
- Reference related repos for cross-repo changes
|
||||
|
||||
### Branch Strategy
|
||||
## Validation
|
||||
|
||||
- All repos use the `JP` branch for active development
|
||||
- Always check which branch you're on before committing
|
||||
Run before every commit:
|
||||
- Format check (language-specific)
|
||||
- Lint check (language-specific)
|
||||
- Test suite
|
||||
|
||||
### Cross-Repo Changes
|
||||
## Anti-Patterns
|
||||
|
||||
- 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
|
||||
- Do NOT add heavy dependencies for minor convenience
|
||||
- Do NOT mix formatting-only with functional changes
|
||||
- Do NOT modify unrelated modules "while here"
|
||||
- Do NOT bypass failing checks without explanation
|
||||
|
||||
## Documentation Triad
|
||||
## Cross-Repo Changes
|
||||
|
||||
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
|
||||
- Agent development guide for this repository.
|
||||
- Update when: build commands change, conventions change, new patterns established.
|
||||
|
||||
## 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.
|
||||
When changes span multiple repos:
|
||||
1. Commit to each repo separately
|
||||
2. Reference related repo in commit message
|
||||
3. Run tests in each affected repo before commit
|
||||
|
||||
Reference in New Issue
Block a user