|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 4 | + |
| 5 | +## Project Overview |
| 6 | + |
| 7 | +InfinityFlow.Aspire.Temporal is a .NET Aspire extension that enables running the Temporal CLI dev server as either a container or executable resource. The library provides integration between .NET Aspire and Temporal workflow orchestration. |
| 8 | + |
| 9 | +**Note:** Container deployment is the recommended and well-supported approach. Executable deployment has known limitations (see https://github.com/dotnet/aspire/issues/1637 and https://github.com/temporalio/cli/issues/316). |
| 10 | + |
| 11 | +## Build and Development Commands |
| 12 | + |
| 13 | +### Build the solution |
| 14 | +```bash |
| 15 | +dotnet build InfinityFlow.Aspire.Temporal.sln |
| 16 | +``` |
| 17 | + |
| 18 | +### Build specific project |
| 19 | +```bash |
| 20 | +dotnet build src/InfinityFlow.Aspire.Temporal/InfinityFlow.Aspire.Temporal.csproj |
| 21 | +``` |
| 22 | + |
| 23 | +### Pack NuGet package |
| 24 | +```bash |
| 25 | +dotnet pack src/InfinityFlow.Aspire.Temporal/InfinityFlow.Aspire.Temporal.csproj |
| 26 | +``` |
| 27 | + |
| 28 | +### Run sample application |
| 29 | +```bash |
| 30 | +dotnet run --project sample/AppHost/AppHost.csproj |
| 31 | +``` |
| 32 | + |
| 33 | +### Manage package references |
| 34 | +```bash |
| 35 | +# Add package reference |
| 36 | +dotnet add <project.csproj> package <PackageName> |
| 37 | + |
| 38 | +# Update package reference |
| 39 | +dotnet add <project.csproj> package <PackageName> |
| 40 | + |
| 41 | +# Remove package reference |
| 42 | +dotnet remove <project.csproj> package <PackageName> |
| 43 | +``` |
| 44 | + |
| 45 | +## Architecture |
| 46 | + |
| 47 | +### Core Components |
| 48 | + |
| 49 | +The library consists of two main integration patterns: |
| 50 | + |
| 51 | +1. **Container Resource** (`TemporalServerContainerResource`) - Uses the `temporalio/admin-tools:latest` Docker image |
| 52 | +2. **Executable Resource** (`TemporalServerExecutableResource`) - Runs the Temporal CLI binary directly |
| 53 | + |
| 54 | +Both resources share the same configuration model through `TemporalServerResourceArguments`. |
| 55 | + |
| 56 | +### Key Classes |
| 57 | + |
| 58 | +- **TemporalServerResourceBuilder** (src/InfinityFlow.Aspire.Temporal/TemporalServerResourceBuilder.cs:5) |
| 59 | + - Fluent builder for configuring Temporal server options |
| 60 | + - Provides methods for all CLI flags (ports, namespaces, logging, UI settings, etc.) |
| 61 | + - Returns `TemporalServerResourceArguments` via `Build()` |
| 62 | + |
| 63 | +- **TemporalServerResourceArguments** (src/InfinityFlow.Aspire.Temporal/TemporalServerResourceArguments.cs:6) |
| 64 | + - Holds all configuration properties (ports, log settings, namespaces, dynamic config) |
| 65 | + - `GetArgs()` method converts properties to CLI arguments for `temporal server start-dev` |
| 66 | + - Supports dynamic config values via `DynamicConfigValues` dictionary |
| 67 | + |
| 68 | +- **TemporalServerContainerBuilderExtensions** (src/InfinityFlow.Aspire.Temporal/TemporalServerContainerBuilderExtensions.cs:6) |
| 69 | + - `AddTemporalServerContainer()` extension methods for `IDistributedApplicationBuilder` |
| 70 | + - Configures container with proper endpoints (server:7233 gRPC, ui:8233 HTTP, optional metrics/http) |
| 71 | + - Server endpoint is marked as HTTP/2 service via `.AsHttp2Service()` |
| 72 | + |
| 73 | +- **TemporalServerExecutableBuilderExtensions** (src/InfinityFlow.Aspire.Temporal/TemporalServerExecutableBuilderExtensions.cs:6) |
| 74 | + - `AddTemporalServerExecutable()` extension methods |
| 75 | + - Configures endpoints with defaults (UI defaults to port+1000, metrics to 9000) |
| 76 | + |
| 77 | +- **Resource Classes** (src/InfinityFlow.Aspire.Temporal/TemporalServerExecutableResource.cs) |
| 78 | + - Both inherit from Aspire base classes (`ExecutableResource`, `ContainerResource`) |
| 79 | + - Implement `IResourceWithConnectionString` - connection string is the server endpoint host:port |
| 80 | + - Container resource also implements `IResourceWithEnvironment` |
| 81 | + |
| 82 | +### Configuration Pattern |
| 83 | + |
| 84 | +The library uses a fluent builder pattern: |
| 85 | +```csharp |
| 86 | +builder.AddTemporalServerContainer("temporal", x => x |
| 87 | + .WithLogFormat(LogFormat.Json) |
| 88 | + .WithLogLevel(LogLevel.Info) |
| 89 | + .WithNamespace("ns1", "ns2") |
| 90 | + .WithDynamicConfigValue("key", value)); |
| 91 | +``` |
| 92 | + |
| 93 | +All `temporal server start-dev` CLI flags map to builder methods (src/InfinityFlow.Aspire.Temporal/TemporalServerResourceBuilder.cs). |
| 94 | + |
| 95 | +### Enums |
| 96 | + |
| 97 | +Three enums define Temporal CLI options (src/InfinityFlow.Aspire.Temporal/Enums.cs): |
| 98 | +- `LogFormat`: Json, Pretty |
| 99 | +- `LogLevel`: Debug, Info, Warn, Error, Fatal |
| 100 | +- `SQLitePragma`: JournalMode, Synchronous |
| 101 | + |
| 102 | +`EnumHelpers` class converts enums to CLI string values. |
| 103 | + |
| 104 | +## Project Structure |
| 105 | + |
| 106 | +- **src/InfinityFlow.Aspire.Temporal/** - Main library code |
| 107 | + - Target framework: net9.0 |
| 108 | + - NuGet package ID: InfinityFlow.Aspire.Temporal |
| 109 | + - Dependencies: Aspire.Hosting.AppHost 9.5.0 |
| 110 | + |
| 111 | +- **sample/** - Example Aspire application demonstrating usage |
| 112 | + - **AppHost/** - Aspire orchestration project showing both container and executable resources |
| 113 | + - **Worker/** - Example Temporal worker with workflow and activity implementations |
| 114 | + - **Api/** - Example API client |
| 115 | + - **ServiceDefaults/** - Shared service configuration (includes Temporal observability setup) |
| 116 | + |
| 117 | +## Temporal Integration |
| 118 | + |
| 119 | +### Connection String |
| 120 | + |
| 121 | +Both resources implement `IResourceWithConnectionString`. The connection string is automatically injected as `ConnectionStrings:<resource-name>` in referenced projects. |
| 122 | + |
| 123 | +Example: A resource named "temporal" exposes `builder.Configuration["ConnectionStrings:temporal"]` which resolves to the gRPC server endpoint (e.g., "localhost:7233"). |
| 124 | + |
| 125 | +### Observability |
| 126 | + |
| 127 | +The sample demonstrates Temporal observability integration (sample/Worker/Program.cs, sample/ServiceDefaults/Extensions.cs): |
| 128 | +- Uses `Temporalio.Extensions.DiagnosticSource` for tracing (`TracingInterceptor`) |
| 129 | +- Uses `Temporalio.Extensions.OpenTelemetry` for metrics (`CustomMetricMeter`) |
| 130 | +- Custom meter and tracing sources must be added to Aspire service defaults |
| 131 | + |
| 132 | +### Endpoints |
| 133 | + |
| 134 | +Container resource endpoints: |
| 135 | +- **server**: gRPC endpoint (default 7233) - HTTP/2 service |
| 136 | +- **ui**: Web UI (default 8233) - HTTP service |
| 137 | +- **metrics**: Optional metrics endpoint |
| 138 | +- **http**: Optional HTTP API endpoint |
| 139 | + |
| 140 | +Executable resource endpoints have similar structure but with different default handling. |
| 141 | + |
| 142 | +## Package Management |
| 143 | + |
| 144 | +This is a packable library project (IsPackable=true) with package validation enabled. When modifying: |
| 145 | +- Update `PackageVersion` in src/InfinityFlow.Aspire.Temporal/InfinityFlow.Aspire.Temporal.csproj:10 |
| 146 | +- Include package assets from assets/ folder (packageIcon.png, README.md, LICENSE) |
| 147 | +- Documentation XML is generated automatically |
| 148 | +- SourceLink is configured for GitHub |
| 149 | + |
| 150 | +## Important Notes |
| 151 | + |
| 152 | +- Container resource uses `0.0.0.0` as default IP binding (src/InfinityFlow.Aspire.Temporal/TemporalServerResourceArguments.cs:46) |
| 153 | +- Port defaults: server=7233, UI=8233 |
| 154 | +- The "default" namespace is always created by Temporal |
| 155 | +- Dynamic config values support string, bool, int, float, double, long types (src/InfinityFlow.Aspire.Temporal/TemporalServerResourceArguments.cs:140-149) |
0 commit comments