From 79d4fb7b3412a048cd81930b3a46859d7d28a9e3 Mon Sep 17 00:00:00 2001 From: "Jeremy D. Miller" Date: Tue, 3 Feb 2026 08:05:10 -0600 Subject: [PATCH] Basic CLAUDE md file --- .claude/docs/architectural_patterns.md | 240 +++++++++++++++++++++++++ CLAUDE.md | 119 ++++++++++++ wolverine.sln | 2 + 3 files changed, 361 insertions(+) create mode 100644 .claude/docs/architectural_patterns.md create mode 100644 CLAUDE.md diff --git a/.claude/docs/architectural_patterns.md b/.claude/docs/architectural_patterns.md new file mode 100644 index 000000000..3ac3873e4 --- /dev/null +++ b/.claude/docs/architectural_patterns.md @@ -0,0 +1,240 @@ +# Architectural Patterns + +Patterns and conventions used consistently across the Wolverine codebase. + +## Dependency Injection + +### Constructor-Based DI with Runtime Context + +Dependencies are injected via constructors. The `IWolverineRuntime` interface is the central runtime dependency. + +**Examples**: +- `src/Wolverine/Runtime/MessageContext.cs:41-49` - Accepts IWolverineRuntime +- `src/Wolverine/Runtime/Handlers/MessageContextFrame.cs:23-26` - Generated code creates MessageContext +- `src/Persistence/Wolverine.EntityFrameworkCore/DbContextOutbox.cs:11-16` - Multi-dependency injection + +### Factory Delegates for Lazy Construction + +Complex objects use factory functions rather than direct instantiation. + +**Examples**: +- `src/Wolverine/Configuration/ListenerConfiguration.cs:30-32` - `Func` +- `src/Wolverine/Configuration/IEndpointPolicy.cs:25-31` - LambdaEndpointPolicy stores Action + +## State Management + +### Transaction-Based Envelope Management + +Messages are tracked through a transaction-like pattern in MessageContext. + +**Implementation** (`src/Wolverine/Runtime/MessageContext.cs:34-43`): +- `Transaction` property manages IEnvelopeTransaction state +- `_outstanding` List tracks pending messages +- `_sent` List tracks completed sends +- `MultiFlushMode` enum controls flush behavior (lines 15-32) + +### Saga State Persistence + +Sagas maintain state through dedicated persistence interfaces. + +**Pattern** (`src/Wolverine/Saga.cs:8-36`): +- Abstract `Saga` base class with `Version` and `IsCompleted` tracking +- `ISagaSupport` interface (`src/Wolverine/Persistence/Sagas/ISagaSupport.cs:5-7`) for storage enrollment + +## Fluent Configuration + +### Self-Typed Generic Builder Pattern + +Configuration methods return `TSelf` for type-safe chaining. + +**Pattern** (`src/Wolverine/Configuration/ListenerConfiguration.cs:88-90`): +```csharp +public class ListenerConfiguration : DelayedEndpointConfiguration, + IListenerConfiguration + where TSelf : IListenerConfiguration +``` + +Methods return `this.As()` for chaining. + +**Examples**: +- `src/Wolverine/Configuration/SubscriberConfiguration.cs:79-81` +- `src/Wolverine/Configuration/IListenerConfiguration.cs:47-136` + +### Generic Extension Methods + +Type constraints ensure methods work only on appropriate configuration objects. + +**Example** (`src/Extensions/Wolverine.MemoryPack/WolverineMemoryPackSerializationExtensions.cs:34-44`): +```csharp +public static T UseMemoryPackSerialization(this T endpoint, ...) + where T : IEndpointConfiguration +``` + +## Message Handling + +### Handler Pipeline with Middleware + +Message handling uses composable middleware chains. + +**Interfaces**: +- `src/Wolverine/Runtime/IHandlerPipeline.cs:6-10` - Pipeline entry point +- `src/Wolverine/Runtime/Handlers/MessageHandler.cs:24-36` - Abstract handler base + +### Continuation-Based Error Handling + +Handlers return continuations that determine post-execution actions rather than throwing. + +**Pattern**: +- `src/Wolverine/Runtime/IContinuation.cs:18-30` - IContinuation interface +- `src/Wolverine/ErrorHandling/IContinuationSource.cs:8-21` - Builds continuations from exceptions +- `src/Wolverine/ErrorHandling/IWithFailurePolicies.cs:3-8` - FailureRuleCollection on handlers + +### Cascading Message Pattern + +Handlers can emit multiple downstream messages. + +**Implementation** (`src/Wolverine/Runtime/MessageContext.cs:513-573`): +- Handles `ISendMyself`, `IEnumerable`, `IAsyncEnumerable` +- `src/Wolverine/Configuration/Chain.cs:317-323` - CaptureCascadingMessages middleware + +## Persistence + +### Multi-Store Abstraction with Role-Based Routing + +Multiple message stores with different roles (Main, Ancillary, Tenant, Composite). + +**Interface** (`src/Wolverine/Persistence/Durability/IMessageStore.cs:8-31`): +- Properties: Uri, Role, TenantIds, Inbox, Outbox, Nodes +- `IMessageInbox` and `IMessageOutbox` separate concerns (lines 33-51) + +### Outbox Pattern + +Domain persistence uses transactional outbox for message delivery guarantees. + +**Pattern** (`src/Persistence/Wolverine.EntityFrameworkCore/`): +- `IDbContextOutbox.cs:9-32` - Generic interface +- `DbContextOutbox.cs:7-35` - Implementation with `SaveChangesAndFlushMessagesAsync()` + +## Agent Abstraction + +### IAgent for Background Processing + +Background work uses `IAgent` extending `IHostedService`. + +**Interface** (`src/Wolverine/Runtime/Agents/IAgent.cs:15-26`): +- Extends IHostedService with Uri identification +- `IAgentFamily.cs:22-56` - Factory pattern for agent creation + +**Specialized agents**: +- `src/Wolverine/Transports/Sending/ISendingAgent.cs:5-30` - Outbound delivery + +## Configuration Organization + +### Partial Classes for Concern Separation + +WolverineOptions splits configuration across partial classes: + +| File | Concern | +|------|---------| +| `WolverineOptions.cs` | Core options | +| `WolverineOptions.Serialization.cs` | Message serialization | +| `WolverineOptions.Endpoints.cs` | Endpoint setup | +| `WolverineOptions.Policies.cs` | Error/retry policies | +| `WolverineOptions.Assemblies.cs` | Assembly scanning | + +### Enum-Based Configuration + +Type-safe configuration choices via enums. + +**Examples**: +- `MultipleHandlerBehavior`, `WolverineMetricsMode`, `UnknownMessageBehavior` (`WolverineOptions.cs:27-63`) +- `MultiFlushMode` (`MessageContext.cs:15-32`) +- `MessageStoreRole` (`IMessageStore.cs:8-31`) + +## Code Generation + +### Frame-Based Source Generation + +Runtime code generation uses "Frame" objects that emit source code. + +**Pattern**: +- `src/Wolverine/Runtime/Handlers/MessageFrame.cs:8-26` - Variable assignment generation +- `src/Wolverine/Runtime/Handlers/MessageContextFrame.cs:28-32` - MessageContext instantiation +- Frames implement `GenerateCode(GeneratedMethod, ISourceWriter)` +- Base: JasperFx.CodeGeneration.Frame + +## Handler Discovery + +### Attribute-Based Metadata + +Attributes control handler discovery and behavior. + +**Discovery** (`src/Wolverine/Configuration/HandlerDiscovery.cs:17-22`): +- Valid method names: Handle, HandleAsync, Consume, ConsumeAsync +- Scanning attributes: `[WolverineHandler]`, `[WolverineMessage]`, `[WolverineIgnore]` (lines 58-68) + +**Application** (`src/Wolverine/Configuration/Chain.cs:122-146`): +- `ApplyAttributesAndConfigureMethods` processes `TModifyAttribute` generics + +## Policy Architecture + +### Generic Visitor Pattern for Policies + +Policies are applied via visitor-like pattern during bootstrap. + +**Interfaces**: +- `src/Wolverine/Configuration/IHandlerPolicy.cs:44-53` - Apply to HandlerChain list +- `src/Wolverine/Configuration/IEndpointPolicy.cs:5-8` - Apply to Endpoint +- `src/Wolverine/Configuration/IChainPolicy.cs:13-21` - Generic chain policy + +**Lambda wrappers**: LambdaEndpointPolicy, LambdaHandlerPolicy for delegate-based policies + +## Data Transfer + +### Records for Immutable Values + +Records used for DTOs and configuration data. + +**Examples**: +- `src/Wolverine/Configuration/Capabilities/HandlerMethod.cs` - `record HandlerMethod(TypeDescriptor, string)` +- `src/Wolverine/BrokerName.cs` - `record BrokerName(string Name)` +- `src/Wolverine/Transports/IDurableProcessor.cs` - `record BufferingLimits(int, int)` +- `src/Wolverine/Runtime/Metrics/MessageHandlingMetrics.cs` - Nested metric records + +## Testing Patterns + +### Test Harness Pattern + +Dedicated harnesses for isolated testing. + +**Example** (`src/Testing/Wolverine.ComplianceTests/Sagas/SagaTestHarness.cs:10-45`): +- `SagaTestHarness` provides test-specific invoke/send helpers +- Lazy host initialization (lines 27-29) +- `LoadState` overloads for different ID types (lines 62-80) + +### Compliance Test Suites + +Shared tests ensure transport implementations meet contracts. + +**Location**: `src/Testing/Wolverine.ComplianceTests/` +- Used by transports in `src/Transports/*/ChaosTesting/` + +## Interface Composition + +### Role-Based Interfaces + +Interfaces composed to represent capabilities. + +**Example** (`src/Wolverine/Runtime/MessageContext.cs:34`): +```csharp +public class MessageContext : MessageBus, IMessageContext, IHasTenantId, + IEnvelopeTransaction, IEnvelopeLifecycle +``` + +### Marker Interfaces + +Empty interfaces for type constraints and categorization. + +**Examples**: +- `src/Wolverine/Configuration/IWolverinePolicy.cs:3-6` - Base policy marker +- `src/Wolverine/Configuration/IHandlerPolicy.cs` - Handler-specific policies diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 000000000..91ba12cd6 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,119 @@ +# Wolverine + +.NET distributed application framework providing in-process mediator and message bus capabilities for event-driven architectures. Part of the "critter stack" with Marten. + +## Tech Stack + +- **Language**: C# 12+ +- **Frameworks**: .NET 8.0, 9.0, 10.0 +- **Build**: MSBuild + Nuke (scripted automation) +- **Core Dependencies**: JasperFx (runtime compilation), Microsoft.Extensions.*, System.Threading.Tasks.Dataflow +- **Docs**: Vitepress (in `/docs`) + +## Project Structure + +``` +src/ +├── Wolverine/ # Core framework - message bus, handlers, middleware +├── Http/ # HTTP/REST support +│ ├── Wolverine.Http/ # ASP.NET Core integration +│ └── Wolverine.Http.Marten/ +├── Persistence/ # Storage providers +│ ├── Wolverine.RDBMS/ # Base RDBMS implementation +│ ├── Wolverine.SqlServer/ +│ ├── Wolverine.Postgresql/ +│ ├── Wolverine.EntityFrameworkCore/ +│ ├── Wolverine.Marten/ # Event sourcing with Marten +│ └── Wolverine.RavenDb/ +├── Transports/ # Message brokers +│ ├── RabbitMQ/ +│ ├── AWS/ # SQS, SNS +│ ├── Azure/ # Service Bus +│ ├── Kafka/ +│ ├── Redis/ +│ └── [NATS, Pulsar, GCP, MQTT, SignalR] +├── Extensions/ # Serialization & validation +│ ├── Wolverine.FluentValidation/ +│ ├── Wolverine.MessagePack/ +│ └── Wolverine.MemoryPack/ +├── Samples/ # Example applications +└── Testing/ # Test suites + ├── CoreTests/ + ├── Wolverine.ComplianceTests/ + └── SlowTests/ +``` + +## Build & Test + +```bash +# Build (uses Nuke) +./build.sh # macOS/Linux +build.ps1 # Windows + +# Start test infrastructure +docker compose up -d # PostgreSQL, SQL Server, RabbitMQ, Kafka, etc. + +# Run tests +dotnet test # All tests +dotnet test src/Testing/CoreTests/ + +# Documentation +npm install && npm run docs +``` + +**Solutions**: +- `wolverine.sln` - Full solution +- `wolverine_slim.sln` - Lightweight variant + +## Key Entry Points + +| Concept | Location | +|---------|----------| +| Options/Config | `src/Wolverine/WolverineOptions.cs:97` | +| Message Bus | `src/Wolverine/Runtime/MessageBus.cs` | +| Message Context | `src/Wolverine/Runtime/MessageContext.cs:34` | +| Handler Discovery | `src/Wolverine/Configuration/HandlerDiscovery.cs:17` | +| Endpoint Config | `src/Wolverine/Configuration/ListenerConfiguration.cs` | +| Sagas | `src/Wolverine/Saga.cs:8` | +| HTTP Endpoints | `src/Http/Wolverine.Http/` | + +## Handler Conventions + +Valid handler method names: `Handle`, `HandleAsync`, `Consume`, `ConsumeAsync` (`HandlerDiscovery.cs:17-22`) + +Handlers are discovered by scanning assemblies. Use attributes like `[WolverineHandler]`, `[WolverineMessage]`, `[WolverineIgnore]` to control discovery. + +## Configuration Organization + +WolverineOptions uses partial classes to organize concerns: +- `WolverineOptions.cs` - Main options +- `WolverineOptions.Serialization.cs` - Message serialization +- `WolverineOptions.Endpoints.cs` - Endpoint configuration +- `WolverineOptions.Policies.cs` - Error handling policies +- `WolverineOptions.Assemblies.cs` - Assembly scanning + +## Test Infrastructure (docker-compose.yml) + +| Service | Port | +|---------|------| +| PostgreSQL | 5433 | +| SQL Server | 1434 | +| RabbitMQ | 5672 (mgmt: 15672) | +| Kafka | 9092 | +| Redis | 6379 | +| NATS | 4222 | +| LocalStack (AWS) | 4566 | +| GCP Pub/Sub | 8085 | +| Pulsar | 6650 | + +## Additional Documentation + +When working on specific areas, consult these files: + +| Topic | File | +|-------|------| +| Architectural patterns & conventions | `.claude/docs/architectural_patterns.md` | + +## Version + +Current: **5.13.0** (see `Directory.Build.props`) diff --git a/wolverine.sln b/wolverine.sln index 87769282a..18ad91790 100644 --- a/wolverine.sln +++ b/wolverine.sln @@ -103,6 +103,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".SolutionItems", ".Solution package.json = package.json .github\workflows\publish_nugets.yml = .github\workflows\publish_nugets.yml README.md = README.md + CLAUDE.md = CLAUDE.md + .claude\docs\architectural_patterns.md = .claude\docs\architectural_patterns.md EndProjectSection EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wolverine.MemoryPack", "src\Extensions\Wolverine.MemoryPack\Wolverine.MemoryPack.csproj", "{469A2C91-64B4-439B-9097-05499770FFB3}"