agentic-team-templates 0.13.2 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/README.md +6 -1
  2. package/package.json +1 -1
  3. package/src/index.js +91 -13
  4. package/src/index.test.js +95 -1
  5. package/templates/cpp-expert/.cursorrules/concurrency.md +211 -0
  6. package/templates/cpp-expert/.cursorrules/error-handling.md +170 -0
  7. package/templates/cpp-expert/.cursorrules/memory-and-ownership.md +220 -0
  8. package/templates/cpp-expert/.cursorrules/modern-cpp.md +211 -0
  9. package/templates/cpp-expert/.cursorrules/overview.md +87 -0
  10. package/templates/cpp-expert/.cursorrules/performance.md +223 -0
  11. package/templates/cpp-expert/.cursorrules/testing.md +230 -0
  12. package/templates/cpp-expert/.cursorrules/tooling.md +312 -0
  13. package/templates/cpp-expert/CLAUDE.md +242 -0
  14. package/templates/csharp-expert/.cursorrules/aspnet-core.md +311 -0
  15. package/templates/csharp-expert/.cursorrules/async-patterns.md +206 -0
  16. package/templates/csharp-expert/.cursorrules/dependency-injection.md +206 -0
  17. package/templates/csharp-expert/.cursorrules/error-handling.md +235 -0
  18. package/templates/csharp-expert/.cursorrules/language-features.md +204 -0
  19. package/templates/csharp-expert/.cursorrules/overview.md +92 -0
  20. package/templates/csharp-expert/.cursorrules/performance.md +251 -0
  21. package/templates/csharp-expert/.cursorrules/testing.md +282 -0
  22. package/templates/csharp-expert/.cursorrules/tooling.md +254 -0
  23. package/templates/csharp-expert/CLAUDE.md +360 -0
  24. package/templates/java-expert/.cursorrules/concurrency.md +209 -0
  25. package/templates/java-expert/.cursorrules/error-handling.md +205 -0
  26. package/templates/java-expert/.cursorrules/modern-java.md +216 -0
  27. package/templates/java-expert/.cursorrules/overview.md +81 -0
  28. package/templates/java-expert/.cursorrules/performance.md +239 -0
  29. package/templates/java-expert/.cursorrules/persistence.md +262 -0
  30. package/templates/java-expert/.cursorrules/spring-boot.md +262 -0
  31. package/templates/java-expert/.cursorrules/testing.md +272 -0
  32. package/templates/java-expert/.cursorrules/tooling.md +301 -0
  33. package/templates/java-expert/CLAUDE.md +325 -0
  34. package/templates/javascript-expert/.cursorrules/overview.md +5 -3
  35. package/templates/javascript-expert/.cursorrules/typescript-deep-dive.md +348 -0
  36. package/templates/javascript-expert/CLAUDE.md +34 -3
  37. package/templates/kotlin-expert/.cursorrules/coroutines.md +237 -0
  38. package/templates/kotlin-expert/.cursorrules/error-handling.md +149 -0
  39. package/templates/kotlin-expert/.cursorrules/frameworks.md +227 -0
  40. package/templates/kotlin-expert/.cursorrules/language-features.md +231 -0
  41. package/templates/kotlin-expert/.cursorrules/overview.md +77 -0
  42. package/templates/kotlin-expert/.cursorrules/performance.md +185 -0
  43. package/templates/kotlin-expert/.cursorrules/testing.md +213 -0
  44. package/templates/kotlin-expert/.cursorrules/tooling.md +258 -0
  45. package/templates/kotlin-expert/CLAUDE.md +276 -0
  46. package/templates/swift-expert/.cursorrules/concurrency.md +230 -0
  47. package/templates/swift-expert/.cursorrules/error-handling.md +213 -0
  48. package/templates/swift-expert/.cursorrules/language-features.md +246 -0
  49. package/templates/swift-expert/.cursorrules/overview.md +88 -0
  50. package/templates/swift-expert/.cursorrules/performance.md +260 -0
  51. package/templates/swift-expert/.cursorrules/swiftui.md +260 -0
  52. package/templates/swift-expert/.cursorrules/testing.md +286 -0
  53. package/templates/swift-expert/.cursorrules/tooling.md +285 -0
  54. package/templates/swift-expert/CLAUDE.md +275 -0
@@ -0,0 +1,254 @@
1
+ # C# Tooling and Ecosystem
2
+
3
+ The .NET toolchain, project configuration, and CI/CD patterns.
4
+
5
+ ## Essential CLI Commands
6
+
7
+ ```bash
8
+ # Project management
9
+ dotnet new webapi -n MyApp.Api # Create new project
10
+ dotnet new sln -n MyApp # Create solution
11
+ dotnet sln add src/MyApp.Api # Add project to solution
12
+ dotnet add reference ../MyApp.Domain # Add project reference
13
+ dotnet add package Serilog # Add NuGet package
14
+
15
+ # Build and run
16
+ dotnet build --warnaserror # Build with warnings as errors
17
+ dotnet run --project src/MyApp.Api # Run specific project
18
+ dotnet watch --project src/MyApp.Api # Hot reload
19
+
20
+ # Testing
21
+ dotnet test # Run all tests
22
+ dotnet test --filter "Category=Unit" # Filter tests
23
+ dotnet test --collect:"XPlat Code Coverage" # With coverage
24
+ dotnet test --logger "console;verbosity=detailed"
25
+
26
+ # Analysis
27
+ dotnet format # Apply code style
28
+ dotnet format --verify-no-changes # CI check
29
+ ```
30
+
31
+ ## Project Configuration
32
+
33
+ ### Directory.Build.props
34
+
35
+ Shared settings across all projects in the solution:
36
+
37
+ ```xml
38
+ <Project>
39
+ <PropertyGroup>
40
+ <TargetFramework>net9.0</TargetFramework>
41
+ <Nullable>enable</Nullable>
42
+ <ImplicitUsings>enable</ImplicitUsings>
43
+ <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
44
+ <EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
45
+ <AnalysisLevel>latest-recommended</AnalysisLevel>
46
+ </PropertyGroup>
47
+
48
+ <!-- Central package management -->
49
+ <PropertyGroup>
50
+ <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
51
+ </PropertyGroup>
52
+ </Project>
53
+ ```
54
+
55
+ ### Directory.Packages.props
56
+
57
+ Central package version management (single source of truth):
58
+
59
+ ```xml
60
+ <Project>
61
+ <ItemGroup>
62
+ <!-- Core -->
63
+ <PackageVersion Include="Microsoft.EntityFrameworkCore" Version="9.0.0" />
64
+ <PackageVersion Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="9.0.0" />
65
+
66
+ <!-- Testing -->
67
+ <PackageVersion Include="xunit" Version="2.9.0" />
68
+ <PackageVersion Include="FluentAssertions" Version="7.0.0" />
69
+ <PackageVersion Include="NSubstitute" Version="5.3.0" />
70
+ <PackageVersion Include="Testcontainers.PostgreSql" Version="4.0.0" />
71
+
72
+ <!-- Analysis -->
73
+ <PackageVersion Include="SonarAnalyzer.CSharp" Version="10.0.0" />
74
+ <PackageVersion Include="Roslynator.Analyzers" Version="4.12.0" />
75
+ </ItemGroup>
76
+ </Project>
77
+ ```
78
+
79
+ ## .editorconfig
80
+
81
+ ```ini
82
+ root = true
83
+
84
+ [*.cs]
85
+ # Naming conventions
86
+ dotnet_naming_rule.private_fields_should_be_camel_case.severity = error
87
+ dotnet_naming_rule.private_fields_should_be_camel_case.symbols = private_fields
88
+ dotnet_naming_rule.private_fields_should_be_camel_case.style = underscore_camel_case
89
+
90
+ dotnet_naming_symbols.private_fields.applicable_kinds = field
91
+ dotnet_naming_symbols.private_fields.applicable_accessibilities = private
92
+
93
+ dotnet_naming_style.underscore_camel_case.required_prefix = _
94
+ dotnet_naming_style.underscore_camel_case.capitalization = camel_case
95
+
96
+ # Code style
97
+ csharp_style_var_for_built_in_types = false:warning
98
+ csharp_style_var_when_type_is_apparent = true:suggestion
99
+ csharp_style_var_elsewhere = false:suggestion
100
+
101
+ csharp_prefer_simple_using_statement = true:warning
102
+ csharp_style_namespace_declarations = file_scoped:warning
103
+ csharp_style_prefer_primary_constructors = true:suggestion
104
+
105
+ # Formatting
106
+ dotnet_sort_system_directives_first = true
107
+ csharp_new_line_before_open_brace = all
108
+ ```
109
+
110
+ ## Analyzers
111
+
112
+ ```xml
113
+ <!-- In .csproj or Directory.Build.props -->
114
+ <ItemGroup>
115
+ <!-- Roslyn analyzers -->
116
+ <PackageReference Include="SonarAnalyzer.CSharp" PrivateAssets="all" />
117
+ <PackageReference Include="Roslynator.Analyzers" PrivateAssets="all" />
118
+ <PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" PrivateAssets="all" />
119
+
120
+ <!-- Security analyzers -->
121
+ <PackageReference Include="SecurityCodeScan.VS2019" PrivateAssets="all" />
122
+ </ItemGroup>
123
+ ```
124
+
125
+ ## Docker
126
+
127
+ ```dockerfile
128
+ # Multi-stage build for minimal image
129
+ FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build
130
+ WORKDIR /src
131
+ COPY Directory.Build.props Directory.Packages.props ./
132
+ COPY **/*.csproj ./
133
+ RUN dotnet restore
134
+
135
+ COPY . .
136
+ RUN dotnet publish src/MyApp.Api -c Release -o /app --no-restore
137
+
138
+ # Runtime image — minimal, non-root
139
+ FROM mcr.microsoft.com/dotnet/aspnet:9.0-alpine AS runtime
140
+ RUN addgroup -S appgroup && adduser -S appuser -G appgroup
141
+ USER appuser
142
+ WORKDIR /app
143
+ COPY --from=build /app .
144
+ EXPOSE 8080
145
+ ENV ASPNETCORE_URLS=http://+:8080
146
+ ENTRYPOINT ["dotnet", "MyApp.Api.dll"]
147
+ ```
148
+
149
+ ## CI/CD (GitHub Actions)
150
+
151
+ ```yaml
152
+ name: CI
153
+
154
+ on:
155
+ push:
156
+ branches: [main]
157
+ pull_request:
158
+ branches: [main]
159
+
160
+ jobs:
161
+ build-and-test:
162
+ runs-on: ubuntu-latest
163
+
164
+ services:
165
+ postgres:
166
+ image: postgres:16-alpine
167
+ env:
168
+ POSTGRES_PASSWORD: test
169
+ POSTGRES_DB: testdb
170
+ ports:
171
+ - 5432:5432
172
+
173
+ steps:
174
+ - uses: actions/checkout@v4
175
+
176
+ - uses: actions/setup-dotnet@v4
177
+ with:
178
+ dotnet-version: '9.0.x'
179
+
180
+ - name: Restore
181
+ run: dotnet restore
182
+
183
+ - name: Build
184
+ run: dotnet build --no-restore --warnaserror
185
+
186
+ - name: Format check
187
+ run: dotnet format --verify-no-changes --no-restore
188
+
189
+ - name: Test
190
+ run: dotnet test --no-build --collect:"XPlat Code Coverage" --logger trx
191
+ env:
192
+ ConnectionStrings__TestDb: "Host=localhost;Database=testdb;Username=postgres;Password=test"
193
+
194
+ - name: Upload coverage
195
+ uses: codecov/codecov-action@v4
196
+ ```
197
+
198
+ ## NuGet Package Publishing
199
+
200
+ ```xml
201
+ <!-- For library projects -->
202
+ <PropertyGroup>
203
+ <PackageId>MyCompany.MyLibrary</PackageId>
204
+ <Version>1.0.0</Version>
205
+ <Description>A useful library</Description>
206
+ <Authors>Your Name</Authors>
207
+ <PackageLicenseExpression>MIT</PackageLicenseExpression>
208
+ <PackageReadmeFile>README.md</PackageReadmeFile>
209
+ <GenerateDocumentationFile>true</GenerateDocumentationFile>
210
+ <PublishRepositoryUrl>true</PublishRepositoryUrl>
211
+ <EmbedUntrackedSources>true</EmbedUntrackedSources>
212
+ <IncludeSymbols>true</IncludeSymbols>
213
+ <SymbolPackageFormat>snupkg</SymbolPackageFormat>
214
+ </PropertyGroup>
215
+ ```
216
+
217
+ ```bash
218
+ dotnet pack -c Release
219
+ dotnet nuget push bin/Release/*.nupkg --source https://api.nuget.org/v3/index.json --api-key $NUGET_KEY
220
+ ```
221
+
222
+ ## Logging with Serilog
223
+
224
+ ```csharp
225
+ // Program.cs
226
+ builder.Host.UseSerilog((context, config) =>
227
+ config.ReadFrom.Configuration(context.Configuration)
228
+ .Enrich.FromLogContext()
229
+ .Enrich.WithMachineName()
230
+ .Enrich.WithEnvironmentName()
231
+ .WriteTo.Console(new CompactJsonFormatter())
232
+ .WriteTo.Seq(context.Configuration["Seq:Url"]!));
233
+
234
+ // Structured logging — always use templates, never interpolation
235
+ logger.LogInformation("Processing order {OrderId} for {CustomerId}", order.Id, order.CustomerId);
236
+ // NOT: logger.LogInformation($"Processing order {order.Id}"); // Defeats structured logging
237
+ ```
238
+
239
+ ## Anti-Patterns
240
+
241
+ ```csharp
242
+ // Never: hardcoded connection strings
243
+ var conn = "Host=localhost;Database=mydb;Password=secret";
244
+ // Use configuration and user-secrets for development
245
+
246
+ // Never: version conflicts across projects
247
+ // Use Directory.Packages.props for central version management
248
+
249
+ // Never: shipping debug builds
250
+ // Always build Release for production: dotnet publish -c Release
251
+
252
+ // Never: skipping dotnet format in CI
253
+ // Code style drift makes reviews harder and diffs noisier
254
+ ```
@@ -0,0 +1,360 @@
1
+ # C# Expert Development Guide
2
+
3
+ Principal-level guidelines for C# engineering. Deep .NET runtime knowledge, modern language features, and production-grade patterns.
4
+
5
+ ---
6
+
7
+ ## Overview
8
+
9
+ This guide applies to:
10
+ - Web APIs and services (ASP.NET Core, Minimal APIs)
11
+ - Desktop and cross-platform applications (WPF, MAUI, Avalonia)
12
+ - Cloud-native services (Azure Functions, Worker Services)
13
+ - Libraries and NuGet packages
14
+ - Real-time systems (SignalR, gRPC)
15
+ - Background processing (Hosted Services, message consumers)
16
+
17
+ ### Core Philosophy
18
+
19
+ C# is a language of deliberate design. Every feature exists for a reason — use the right tool for the job.
20
+
21
+ - **Type safety is your first line of defense.** Nullable reference types enabled, warnings as errors.
22
+ - **Composition over inheritance.** Interfaces, extension methods, and dependency injection — not deep class hierarchies.
23
+ - **Async all the way down.** Never block on async code. Never use `.Result` or `.Wait()` in application code.
24
+ - **The framework does the heavy lifting.** ASP.NET Core's middleware pipeline, DI container, and configuration system are battle-tested — use them.
25
+ - **Measure before you optimize.** BenchmarkDotNet and dotnet-counters before rewriting anything.
26
+ - **If you don't know, say so.** Admitting uncertainty is professional. Guessing at runtime behavior you haven't verified is not.
27
+
28
+ ### Key Principles
29
+
30
+ 1. **Nullable Reference Types Are Non-Negotiable** — `<Nullable>enable</Nullable>` in every project
31
+ 2. **Prefer Records for Data** — Immutable by default, value semantics, concise syntax
32
+ 3. **Dependency Injection Is the Architecture** — Constructor injection, interface segregation, composition root
33
+ 4. **Errors Are Explicit** — Result patterns for expected failures, exceptions for exceptional conditions
34
+ 5. **Tests Describe Behavior** — Not implementation details
35
+
36
+ ### Project Structure
37
+
38
+ ```
39
+ Solution/
40
+ ├── src/
41
+ │ ├── MyApp.Api/ # ASP.NET Core host (thin — wiring only)
42
+ │ │ ├── Program.cs
43
+ │ │ ├── Endpoints/
44
+ │ │ └── Middleware/
45
+ │ ├── MyApp.Application/ # Use cases (no framework deps)
46
+ │ │ ├── Commands/
47
+ │ │ ├── Queries/
48
+ │ │ └── Interfaces/
49
+ │ ├── MyApp.Domain/ # Core domain (zero dependencies)
50
+ │ │ ├── Entities/
51
+ │ │ ├── ValueObjects/
52
+ │ │ └── Events/
53
+ │ └── MyApp.Infrastructure/ # External concerns (DB, HTTP)
54
+ │ ├── Persistence/
55
+ │ └── Services/
56
+ ├── tests/
57
+ │ ├── MyApp.UnitTests/
58
+ │ ├── MyApp.IntegrationTests/
59
+ │ └── MyApp.ArchitectureTests/
60
+ ├── Directory.Build.props
61
+ ├── .editorconfig
62
+ └── MyApp.sln
63
+ ```
64
+
65
+ ---
66
+
67
+ ## Language Features
68
+
69
+ ### Nullable Reference Types
70
+
71
+ ```csharp
72
+ public async Task<User?> FindByEmailAsync(string email)
73
+ {
74
+ ArgumentException.ThrowIfNullOrWhiteSpace(email);
75
+ return await _repository.FindByEmailAsync(email);
76
+ }
77
+ ```
78
+
79
+ - Never disable nullable warnings project-wide
80
+ - `string` means non-null. `string?` means nullable
81
+ - Use `ArgumentNullException.ThrowIfNull()` at public API boundaries
82
+
83
+ ### Records
84
+
85
+ ```csharp
86
+ // Immutable data with value semantics
87
+ public record CreateUserRequest(string Name, string Email);
88
+ public readonly record struct Coordinate(double Latitude, double Longitude);
89
+
90
+ // Non-destructive mutation
91
+ var updated = original with { Email = "new@example.com" };
92
+ ```
93
+
94
+ ### Pattern Matching
95
+
96
+ ```csharp
97
+ public static decimal CalculateDiscount(Order order) => order switch
98
+ {
99
+ { Total: > 1000, Customer.IsPremium: true } => order.Total * 0.15m,
100
+ { Total: > 500 } => order.Total * 0.10m,
101
+ { Customer.IsPremium: true } => order.Total * 0.05m,
102
+ _ => 0m
103
+ };
104
+ ```
105
+
106
+ ### Spans and Memory
107
+
108
+ ```csharp
109
+ public static bool StartsWithDigit(ReadOnlySpan<char> input)
110
+ => !input.IsEmpty && char.IsDigit(input[0]);
111
+ ```
112
+
113
+ ---
114
+
115
+ ## Async Patterns
116
+
117
+ ### The Golden Rules
118
+
119
+ 1. Async all the way down — never mix sync and async
120
+ 2. Never block on async — no `.Result`, `.Wait()`, `.GetAwaiter().GetResult()`
121
+ 3. Always pass `CancellationToken`
122
+ 4. `ConfigureAwait(false)` in library code only
123
+ 5. Return `Task`, not `void` — `async void` is only for event handlers
124
+
125
+ ### CancellationToken
126
+
127
+ ```csharp
128
+ public async Task<OrderResult> ProcessOrderAsync(
129
+ CreateOrderRequest request, CancellationToken cancellationToken)
130
+ {
131
+ var user = await _userService.GetByIdAsync(request.UserId, cancellationToken);
132
+ cancellationToken.ThrowIfCancellationRequested();
133
+ var order = Order.Create(user, request.Items);
134
+ await _repository.SaveAsync(order, cancellationToken);
135
+ return new OrderResult(order.Id);
136
+ }
137
+ ```
138
+
139
+ ### Concurrent Operations
140
+
141
+ ```csharp
142
+ var userTask = _userService.GetByIdAsync(userId, ct);
143
+ var ordersTask = _orderService.GetRecentAsync(userId, ct);
144
+ await Task.WhenAll(userTask, ordersTask);
145
+ ```
146
+
147
+ ### Channels
148
+
149
+ ```csharp
150
+ private readonly Channel<DomainEvent> _channel =
151
+ Channel.CreateBounded<DomainEvent>(new BoundedChannelOptions(1000)
152
+ {
153
+ FullMode = BoundedChannelFullMode.Wait,
154
+ SingleReader = true
155
+ });
156
+ ```
157
+
158
+ ---
159
+
160
+ ## Dependency Injection
161
+
162
+ ### Service Lifetimes
163
+
164
+ - **Transient**: New instance every time. Lightweight, stateless services.
165
+ - **Scoped**: One per request. DbContext, Unit of Work.
166
+ - **Singleton**: One for app lifetime. Caches, config, HTTP clients.
167
+
168
+ ### The Captive Dependency Problem
169
+
170
+ A singleton must NEVER depend on a scoped or transient service.
171
+
172
+ ```csharp
173
+ // WRONG: singleton captures scoped DbContext
174
+ // RIGHT: use IServiceScopeFactory to create scopes on demand
175
+ ```
176
+
177
+ ### Options Pattern
178
+
179
+ ```csharp
180
+ builder.Services
181
+ .AddOptions<SmtpOptions>()
182
+ .BindConfiguration(SmtpOptions.SectionName)
183
+ .ValidateDataAnnotations()
184
+ .ValidateOnStart();
185
+ ```
186
+
187
+ ---
188
+
189
+ ## Error Handling
190
+
191
+ ### Two Categories
192
+
193
+ 1. **Exceptions** — Programming errors, infrastructure failures
194
+ 2. **Result patterns** — Validation failures, business rule violations
195
+
196
+ ### Guard Clauses
197
+
198
+ ```csharp
199
+ ArgumentNullException.ThrowIfNull(request);
200
+ ArgumentException.ThrowIfNullOrWhiteSpace(request.Email);
201
+ ArgumentOutOfRangeException.ThrowIfNegativeOrZero(request.Quantity);
202
+ ```
203
+
204
+ ### Result Pattern
205
+
206
+ ```csharp
207
+ var result = await service.RegisterAsync(request, ct);
208
+ return result.Match(
209
+ user => Results.Created($"/users/{user.Id}", user),
210
+ error => error.Code switch
211
+ {
212
+ "VALIDATION" => Results.BadRequest(error),
213
+ "CONFLICT" => Results.Conflict(error),
214
+ _ => Results.Problem(error.Message)
215
+ });
216
+ ```
217
+
218
+ ---
219
+
220
+ ## Testing
221
+
222
+ ### Framework Stack
223
+
224
+ | Tool | Purpose |
225
+ |------|---------|
226
+ | xUnit | Test framework |
227
+ | NSubstitute | Mocking |
228
+ | FluentAssertions | Readable assertions |
229
+ | Bogus | Test data generation |
230
+ | Testcontainers | Real databases in tests |
231
+ | ArchUnitNET | Architecture tests |
232
+
233
+ ### Unit Test Structure
234
+
235
+ ```csharp
236
+ [Fact]
237
+ public async Task CreateOrder_WithValidItems_ReturnsOrder()
238
+ {
239
+ // Arrange
240
+ var request = new CreateOrderRequest("customer-1", [new("sku-1", 2)]);
241
+ _inventory.CheckAvailabilityAsync("sku-1", 2, Arg.Any<CancellationToken>())
242
+ .Returns(true);
243
+
244
+ // Act
245
+ var result = await _sut.CreateAsync(request, CancellationToken.None);
246
+
247
+ // Assert
248
+ result.IsSuccess.Should().BeTrue();
249
+ result.Value!.CustomerId.Should().Be("customer-1");
250
+ }
251
+ ```
252
+
253
+ ### Integration Tests
254
+
255
+ ```csharp
256
+ public class OrderEndpointTests : IClassFixture<WebApplicationFactory<Program>>
257
+ {
258
+ [Fact]
259
+ public async Task POST_orders_returns_created_for_valid_request()
260
+ {
261
+ var response = await _client.PostAsJsonAsync("/orders", request);
262
+ response.StatusCode.Should().Be(HttpStatusCode.Created);
263
+ }
264
+ }
265
+ ```
266
+
267
+ ---
268
+
269
+ ## Performance
270
+
271
+ ### Profile First
272
+
273
+ ```bash
274
+ dotnet-counters monitor --process-id <pid>
275
+ dotnet-trace collect --process-id <pid>
276
+ ```
277
+
278
+ ### Key Patterns
279
+
280
+ - `AsNoTracking()` for read-only EF Core queries
281
+ - `ArrayPool<T>.Shared` for buffer reuse
282
+ - `FrozenDictionary` for read-heavy, write-once lookups
283
+ - `ObjectPool<T>` for expensive-to-create objects
284
+ - Compiled EF Core queries for hot paths
285
+ - Project to DTOs in LINQ — don't load full entities
286
+ - Use `struct` for small, immutable value types (< 16 bytes guideline)
287
+
288
+ ---
289
+
290
+ ## ASP.NET Core
291
+
292
+ ### Minimal APIs
293
+
294
+ ```csharp
295
+ var group = app.MapGroup("/orders").RequireAuthorization();
296
+ group.MapGet("/{id:int}", GetOrderById);
297
+ group.MapPost("/", CreateOrder);
298
+ ```
299
+
300
+ ### Health Checks
301
+
302
+ ```csharp
303
+ builder.Services.AddHealthChecks()
304
+ .AddDbContextCheck<AppDbContext>("database")
305
+ .AddRedis(connectionString, "redis");
306
+
307
+ app.MapHealthChecks("/healthz");
308
+ ```
309
+
310
+ ### Rate Limiting
311
+
312
+ ```csharp
313
+ builder.Services.AddRateLimiter(options =>
314
+ options.AddFixedWindowLimiter("api", config =>
315
+ {
316
+ config.PermitLimit = 100;
317
+ config.Window = TimeSpan.FromMinutes(1);
318
+ }));
319
+ ```
320
+
321
+ ---
322
+
323
+ ## Tooling
324
+
325
+ ### Essential Stack
326
+
327
+ | Tool | Purpose |
328
+ |------|---------|
329
+ | dotnet CLI | Build, test, publish |
330
+ | dotnet format | Code style enforcement |
331
+ | Roslyn analyzers | Static analysis |
332
+ | BenchmarkDotNet | Performance benchmarks |
333
+ | Serilog | Structured logging |
334
+ | Central Package Management | Version consistency |
335
+
336
+ ### CI Essentials
337
+
338
+ ```bash
339
+ dotnet restore
340
+ dotnet build --warnaserror
341
+ dotnet format --verify-no-changes
342
+ dotnet test --collect:"XPlat Code Coverage"
343
+ ```
344
+
345
+ ---
346
+
347
+ ## Definition of Done
348
+
349
+ A C# feature is complete when:
350
+
351
+ - [ ] `dotnet build --warnaserror` passes with zero warnings
352
+ - [ ] `dotnet test` passes with no failures
353
+ - [ ] Nullable reference types produce no warnings
354
+ - [ ] No `#pragma warning disable` without inline justification
355
+ - [ ] Async methods don't block (no `.Result`, `.Wait()`, `.GetAwaiter().GetResult()`)
356
+ - [ ] All public APIs have XML documentation comments
357
+ - [ ] Error paths are tested
358
+ - [ ] DI registrations verified (no missing services at runtime)
359
+ - [ ] No `TODO` without an associated issue
360
+ - [ ] Code reviewed and approved