Parcourir la source

init

pull/1/head
Daniel Covington il y a 1 semaine
révision
05fbe70f7f
30 fichiers modifiés avec 1627 ajouts et 0 suppressions
  1. +42
    -0
      .ai/SKILLS.md
  2. +17
    -0
      .ai/prompts/csharp-dotnet-agent-prompt.md
  3. +36
    -0
      .ai/skills/00-agent-operating-rules.md
  4. +43
    -0
      .ai/skills/01-dotnet-platform-tooling.md
  5. +41
    -0
      .ai/skills/02-csharp-language-fundamentals.md
  6. +36
    -0
      .ai/skills/03-types-values-nullability.md
  7. +31
    -0
      .ai/skills/04-control-flow-exceptions.md
  8. +40
    -0
      .ai/skills/05-functions-debugging-testing.md
  9. +45
    -0
      .ai/skills/06-oop-types-records.md
  10. +40
    -0
      .ai/skills/07-interfaces-generics-events-inheritance.md
  11. +36
    -0
      .ai/skills/08-common-dotnet-types.md
  12. +37
    -0
      .ai/skills/09-files-streams-serialization.md
  13. +48
    -0
      .ai/skills/10-ef-core-data-access.md
  14. +41
    -0
      .ai/skills/11-linq-querying.md
  15. +39
    -0
      .ai/skills/12-aspnetcore-web-fundamentals.md
  16. +36
    -0
      .ai/skills/13-blazor-components.md
  17. +37
    -0
      .ai/skills/14-minimal-api-web-services.md
  18. +40
    -0
      .ai/skills/15-packaging-publishing-nuget-aot.md
  19. +40
    -0
      .ai/skills/16-security-reliability-performance.md
  20. +30
    -0
      .ai/skills/17-code-review-definition-of-done.md
  21. +467
    -0
      .ai/skills/18-unit-of-work-pattern.md
  22. +10
    -0
      .claude/settings.local.json
  23. +86
    -0
      AGENTS.md
  24. +1
    -0
      CLAUDE.md
  25. +56
    -0
      README.md
  26. +64
    -0
      docs/concept-map.md
  27. +62
    -0
      docs/review-checklist.md
  28. +55
    -0
      docs/task-routing.md
  29. +40
    -0
      docs/unit-of-work-pattern.md
  30. +31
    -0
      manifest.json

+ 42
- 0
.ai/SKILLS.md Voir le fichier

@@ -0,0 +1,42 @@
# .ai/SKILLS.md - C# / .NET Skill Router

Use this file to route tasks to focused skill files.

## Always Load

- `.ai/skills/00-agent-operating-rules.md`
- `.ai/skills/17-code-review-definition-of-done.md`

## Route by Task

| Task type | Load these skills |
|---|---|
| Project setup, SDKs, CLI, solution layout, tools | `.ai/skills/01-dotnet-platform-tooling.md`, `.ai/skills/15-packaging-publishing-nuget-aot.md` |
| C# syntax, variables, operators, strings, console apps | `.ai/skills/02-csharp-language-fundamentals.md`, `.ai/skills/03-types-values-nullability.md` |
| Null handling, value/reference types, conversions | `.ai/skills/03-types-values-nullability.md`, `.ai/skills/04-control-flow-exceptions.md` |
| Flow control, loops, pattern matching, errors | `.ai/skills/04-control-flow-exceptions.md` |
| Functions, debugging, logging, tests | `.ai/skills/05-functions-debugging-testing.md` |
| Classes, structs, records, properties, indexers | `.ai/skills/06-oop-types-records.md`, `.ai/skills/03-types-values-nullability.md` |
| Interfaces, generics, inheritance, polymorphism, events | `.ai/skills/07-interfaces-generics-events-inheritance.md`, `.ai/skills/06-oop-types-records.md` |
| Collections, numbers, strings, regex, BCL | `.ai/skills/08-common-dotnet-types.md` |
| Files, directories, streams, JSON, XML | `.ai/skills/09-files-streams-serialization.md` |
| EF Core, relational database models, querying | `.ai/skills/10-ef-core-data-access.md`, `.ai/skills/11-linq-querying.md` |
| Unit of Work/repository pattern | `.ai/skills/18-unit-of-work-pattern.md`, `.ai/skills/10-ef-core-data-access.md`, `.ai/skills/11-linq-querying.md`, `.ai/skills/12-aspnetcore-web-fundamentals.md` |
| LINQ, sequence transformations, grouping, joins | `.ai/skills/11-linq-querying.md` |
| ASP.NET Core websites, middleware, static assets | `.ai/skills/12-aspnetcore-web-fundamentals.md`, `.ai/skills/16-security-reliability-performance.md` |
| Blazor components, forms, rendering | `.ai/skills/13-blazor-components.md`, `.ai/skills/16-security-reliability-performance.md` |
| Minimal APIs, OpenAPI, HTTP clients | `.ai/skills/14-minimal-api-web-services.md`, `.ai/skills/16-security-reliability-performance.md` |
| NuGet packages, publishing, deployment, AOT | `.ai/skills/15-packaging-publishing-nuget-aot.md`, `.ai/skills/16-security-reliability-performance.md` |
| Security, reliability, performance review | `.ai/skills/16-security-reliability-performance.md`, `.ai/skills/17-code-review-definition-of-done.md` |

## Skill Loading Rule

Load the narrowest skills that cover the task. For a full-stack feature, load the skills for each layer: domain model, data access, web endpoint/UI, tests, and review.

## Skill Update Rule

When a task reveals a reusable project convention, add it to a project-specific skill file instead of bloating `AGENTS.md`.

## Reusable Pattern Skills

- `.ai/skills/18-unit-of-work-pattern.md` - use for Unit of Work, generic repository, EF Core `DbContext`, transaction-boundary, and repository-backed service/controller tasks.

+ 17
- 0
.ai/prompts/csharp-dotnet-agent-prompt.md Voir le fichier

@@ -0,0 +1,17 @@
# C# / .NET Expert Agent Prompt

You are acting as a coordinated group of senior C# and .NET engineers. Before coding, read `AGENTS.md`, then `.ai/SKILLS.md`, then the narrow skill files matching the task.

Operate by these rules:

1. Inspect the existing solution and project files.
2. Respect existing conventions.
3. Prefer simple, readable, testable code.
4. Use modern C# and .NET patterns only when they improve clarity or safety.
5. Add or update tests for meaningful logic.
6. Validate external input and protect secrets.
7. Return exact changed files and commands to build/test.

For EF Core data access, repository, or transaction-boundary tasks, also load `.ai/skills/18-unit-of-work-pattern.md`.

When uncertain, state assumptions and choose the smallest safe implementation.

+ 36
- 0
.ai/skills/00-agent-operating-rules.md Voir le fichier

@@ -0,0 +1,36 @@
# Skill 00 - Agent Operating Rules

## Role

Act as a practical senior C#/.NET engineer. Prefer working software, readable code, explicit assumptions, and verifiable tests.

## Task Intake

Before coding, identify:

- Target framework and language version.
- Existing project architecture.
- Existing test framework.
- Whether nullable reference types are enabled.
- Whether central package management is used.
- Whether the task touches runtime behavior, public APIs, persistence, security, or deployment.

## Non-Negotiable Rules

- Do not hardcode secrets.
- Do not ignore compiler warnings.
- Do not introduce global mutable state unless the design explicitly requires it.
- Do not catch `Exception` only to hide the problem.
- Do not block async code.
- Do not change public contracts without calling out the breaking change.
- Do not add unnecessary abstractions just because patterns exist.

## Default Quality Bar

Code should be:

- Clear enough for a mid-level developer to maintain.
- Covered by tests where logic is non-trivial.
- Built using standard .NET patterns.
- Safe around nulls, invalid input, culture, encoding, and resource disposal.
- Designed for deployment to Windows or Linux unless the project is clearly platform-specific.

+ 43
- 0
.ai/skills/01-dotnet-platform-tooling.md Voir le fichier

@@ -0,0 +1,43 @@
# Skill 01 - .NET Platform and Tooling

## Core Concepts

- Modern .NET is the cross-platform line that evolved from .NET Core.
- Legacy .NET includes .NET Framework, older Mono/Xamarin-era models, and older .NET Standard-centered libraries.
- The .NET SDK includes compilers, templates, build tools, and the runtime.
- The runtime alone is enough to run framework-dependent apps, but not enough to build them.
- Use the `dotnet` CLI as the source of truth. IDEs are views over project files and command-line tools.

## Project Rules

- Inspect `TargetFramework`, `LangVersion`, `Nullable`, `ImplicitUsings`, and package references before changing code.
- Prefer SDK-style project files.
- Use `global.json` when a repo must pin or roll forward SDK versions predictably.
- Use `Directory.Build.props` for shared build settings.
- Use `Directory.Packages.props` for central package management in multi-project solutions.
- Keep app code, class libraries, test projects, and infrastructure scripts separated.

## CLI Commands

```bash
dotnet --info
dotnet new list
dotnet new sln
dotnet new console -n App
dotnet new classlib -n Domain
dotnet new xunit -n Domain.Tests
dotnet sln add src/Domain/Domain.csproj
dotnet add src/App/App.csproj reference src/Domain/Domain.csproj
dotnet restore
dotnet build
dotnet test
dotnet format
```

## Tooling Best Practices

- Use Visual Studio, VS Code with C# Dev Kit, or Rider according to team preference.
- Keep generated `bin` and `obj` folders out of source control.
- Prefer reproducible builds over IDE-only configuration.
- Test on the same operating system family used in production when filesystem, paths, permissions, or casing matter.
- Keep SDKs patched. Runtime and SDK patch updates often contain security and reliability fixes.

+ 41
- 0
.ai/skills/02-csharp-language-fundamentals.md Voir le fichier

@@ -0,0 +1,41 @@
# Skill 02 - C# Language Fundamentals

## Core Concepts

C# code is made of keywords, identifiers, literals, operators, expressions, statements, blocks, members, types, namespaces, and assemblies.

## Naming Rules

- Use `PascalCase` for public types, methods, properties, events, and constants.
- Use `camelCase` for local variables and parameters.
- Use `_camelCase` for private fields when that is the project convention.
- Name things by meaning, not by type suffix, except accepted suffixes like `Async`, `Options`, `Exception`, `Attribute`, and `Controller`.

## Variables and Constants

- Use `var` when the right side makes the type obvious.
- Use explicit types when they improve clarity or prevent accidental narrowing.
- Use `const` only for compile-time constants that will not change.
- Use `readonly` fields for values set during construction.
- Prefer immutable data where practical.

## Strings

- Use string interpolation for readable formatting.
- Use `StringBuilder` for repeated string mutation in loops.
- Be explicit about culture for user-facing versus machine-readable formatting.
- Use ordinal comparisons for identifiers, keys, codes, and protocol values.
- Use culture-aware comparisons only for human language sorting/searching.

## Console and Script-Like Code

- Top-level statements are fine for small apps, samples, and tools.
- Move logic into functions or classes once behavior needs tests.
- Keep `Program.cs` thin in production apps.

## Style Rules

- Prefer clarity over language cleverness.
- Avoid unnecessary `dynamic`; use it only for genuinely dynamic data boundaries.
- Prefer pattern matching when it makes type and shape checks clearer.
- Use `nameof(...)` instead of string literals for member names.

+ 36
- 0
.ai/skills/03-types-values-nullability.md Voir le fichier

@@ -0,0 +1,36 @@
# Skill 03 - Types, Values, Conversions, and Nullability

## Core Concepts

- Value types usually store the value directly and cannot be null unless wrapped in `Nullable<T>` or written as `T?`.
- Reference type variables hold references and may be null unless nullable analysis says otherwise.
- Nullable reference types are a design and compiler-analysis feature, not a runtime guarantee.

## Nullability Rules

- Enable nullable reference types in new projects.
- Treat nullable warnings as defects.
- Use `?` to show optional references clearly.
- Avoid the null-forgiving operator `!` except at trusted boundaries with a comment or obvious reason.
- Prefer constructor, required property, or factory initialization instead of letting objects exist half-valid.
- Use `ArgumentNullException.ThrowIfNull(value)` for required parameters.
- Use null-coalescing and null-conditional operators where they improve readability.

## Conversion Rules

- Be explicit about narrowing conversions.
- Use `TryParse` for user input.
- Use `Parse` only when invalid input is exceptional or impossible.
- Use checked arithmetic when overflow matters.
- Avoid silent data loss when casting numeric values.

## Value Equality

- Use records for immutable data-centric models where value equality is desired.
- Use classes for identity-based entities and behavior-rich objects.
- Override equality carefully when identity or value semantics matter.

## Default Values

- Understand that fields have defaults; local variables must be assigned before use.
- Do not rely on default values for business meaning unless it is explicit in the model.

+ 31
- 0
.ai/skills/04-control-flow-exceptions.md Voir le fichier

@@ -0,0 +1,31 @@
# Skill 04 - Control Flow, Pattern Matching, and Exceptions

## Selection and Iteration

- Use `if` for simple decisions.
- Use `switch` expressions for mapping values to results.
- Use pattern matching for type, property, relational, and logical shape checks.
- Use `foreach` for enumerating collections unless an index is required.
- Use `for` when index control matters.
- Avoid deeply nested conditionals; use guard clauses and extract methods.

## Guard Clause Rules

- Validate public method parameters at the top.
- Return early for invalid or no-op states when it reduces nesting.
- Throw argument exceptions for invalid caller input.
- Throw invalid operation exceptions for invalid object state.

## Exception Rules

- Exceptions are for exceptional or invalid states, not normal branching.
- Preserve stack traces. Use `throw;` when rethrowing inside a catch block.
- Add context when wrapping exceptions.
- Do not catch broad exceptions unless the boundary can recover, log, translate, or shut down cleanly.
- Do not expose sensitive details in web responses.

## Overflow and Defensive Coding

- Use `checked` where overflow would corrupt calculations.
- Validate external input before conversion or persistence.
- Prefer result objects for expected validation outcomes and exceptions for programming/runtime failures.

+ 40
- 0
.ai/skills/05-functions-debugging-testing.md Voir le fichier

@@ -0,0 +1,40 @@
# Skill 05 - Functions, Debugging, and Testing

## Function Design

- Follow DRY, but do not abstract too early.
- Keep functions small enough to explain in one sentence.
- Prefer pure functions for business rules when possible.
- Make side effects obvious in names and placement.
- Use parameters for required input and return values for computed output.
- Use tuples for small local groupings; use named types for public APIs or durable concepts.

## Async Rules

- Use `Task`/`Task<T>` for asynchronous operations.
- Suffix asynchronous methods with `Async`.
- Pass `CancellationToken` through I/O or long-running operations.
- Never use `.Result` or `.Wait()` in request-handling or UI code.

## Debugging Rules

- Reproduce the issue first.
- Use breakpoints, watches, locals, call stack, and trace/log output.
- Verify assumptions with tests rather than comments alone.
- Remove temporary diagnostic output before final code unless it becomes structured logging.

## Unit Testing Rules

- Use Arrange, Act, Assert.
- Test normal, boundary, invalid, and null cases.
- Unit-test pure logic without external services.
- Integration-test database, filesystem, HTTP, serialization, and DI wiring.
- Keep tests deterministic. Avoid reliance on local time, random values, order, or environment unless controlled.

## Common Commands

```bash
dotnet test
dotnet test --filter FullyQualifiedName~SomeTestName
dotnet test --collect:"XPlat Code Coverage"
```

+ 45
- 0
.ai/skills/06-oop-types-records.md Voir le fichier

@@ -0,0 +1,45 @@
# Skill 06 - OOP, Types, Members, Properties, and Records

## OOP Principles

- Abstraction: expose what callers need and hide what they do not.
- Encapsulation: protect invariants by controlling mutation.
- Aggregation/composition: build objects from other objects.
- Inheritance: model true substitutability, not just code reuse.
- Polymorphism: allow different implementations behind a shared contract.

## Class Design Rules

- Keep constructors simple and valid-state focused.
- Use properties for controlled access to state.
- Use methods for behavior.
- Keep fields private unless there is an exceptional reason.
- Avoid public mutable fields.
- Use `required` members when object initialization must supply values.
- Use primary constructors when they improve readability, especially for simple dependency injection or data-carrying types.

## Properties and Indexers

- Put validation in setters only when mutation is allowed.
- Prefer init-only properties for immutable initialization.
- Use computed properties for derived state.
- Use indexers only when the type naturally behaves like an indexed collection.

## Records

Use records when:

- The type represents data more than behavior.
- Value equality is desired.
- Immutability or with-expressions simplify updates.

Avoid records for:

- EF Core entities unless you understand identity, tracking, and mutation implications.
- Types where reference identity matters.

## Namespace and File Rules

- Keep one primary type per file unless types are tiny and tightly related.
- Use file-scoped namespaces when that is the project style.
- Keep namespaces aligned with folder structure unless the project already does otherwise.

+ 40
- 0
.ai/skills/07-interfaces-generics-events-inheritance.md Voir le fichier

@@ -0,0 +1,40 @@
# Skill 07 - Interfaces, Generics, Events, Operators, and Inheritance

## Interfaces

- Use interfaces to model capabilities or contracts, not every class by default.
- Keep interfaces small and cohesive.
- Prefer dependency inversion at boundaries: data stores, clocks, HTTP clients, external services, email, files, and message queues.
- Do not create one-to-one interfaces for every implementation unless mocking, plugin replacement, or architecture requires it.

## Generics

- Use generics for type-safe reuse.
- Add constraints (`where T : ...`) to express required capabilities.
- Prefer `IEnumerable<T>` for simple read-only enumeration, `IReadOnlyList<T>` when count/index matters, and concrete collections when mutation is required internally.

## Events and Delegates

- Use events for notifications from one object to many subscribers.
- Prefer standard `EventHandler` / `EventHandler<TEventArgs>` unless a custom delegate adds clarity.
- Avoid memory leaks by unsubscribing long-lived event subscriptions.

## Operator Overloading

- Overload operators only when they match natural domain meaning.
- Keep overloaded operators unsurprising and consistent with equality/comparison.

## Inheritance

- Prefer composition over inheritance for code reuse.
- Use inheritance for true "is-a" relationships.
- Mark base members `virtual` only when overriding is intended.
- Use `override` deliberately and keep base class contracts intact.
- Use `sealed` for classes or overrides that should not be extended.
- Use pattern matching or safe casts rather than unsafe casts.

## Extension Members

- Use extension methods to add convenience behavior to types you do not own.
- Keep extension methods pure and obvious.
- Do not hide expensive I/O behind innocent-looking extension methods.

+ 36
- 0
.ai/skills/08-common-dotnet-types.md Voir le fichier

@@ -0,0 +1,36 @@
# Skill 08 - Common .NET Types: Numbers, Text, Regex, Collections

## Numbers

- Choose numeric types by range, precision, and domain meaning.
- Use `decimal` for financial calculations.
- Use `double` for scientific/general floating-point calculations.
- Avoid comparing floating-point values for exact equality unless the values are controlled.
- Use formatting strings deliberately for output.

## Text

- Use `string` for immutable text.
- Use `StringBuilder` for repeated mutations.
- Be explicit about encoding; UTF-8 is the default choice for most modern files and APIs.
- Use ordinal comparisons for non-linguistic identifiers.

## Regular Expressions

- Prefer clear regex patterns with tests.
- Use generated or compiled regex for hot paths.
- Always test regex with valid, invalid, edge, and maliciously long input.
- Avoid regex when simple string APIs are clearer.

## Collections

- Use `List<T>` for ordered mutable lists.
- Use `Dictionary<TKey,TValue>` for key lookup.
- Use `HashSet<T>` for uniqueness and membership tests.
- Use immutable/read-only collections when exposing data outside an object.
- Avoid returning mutable internal collections directly.
- Be aware of deferred execution when returning `IEnumerable<T>`.

## BCL Rule

Before adding a package, check whether the Base Class Library already solves the problem.

+ 37
- 0
.ai/skills/09-files-streams-serialization.md Voir le fichier

@@ -0,0 +1,37 @@
# Skill 09 - Files, Streams, Encoding, and Serialization

## Filesystem Rules

- Use `Path.Combine` or `Path.Join`; do not concatenate paths manually.
- Consider case sensitivity and path separator differences across Windows and Linux.
- Validate and normalize user-supplied paths to prevent traversal attacks.
- Use `Directory.EnumerateFiles` for large directory trees.
- Dispose file handles and streams with `using` or `await using`.

## Stream Rules

- Use streams for large data instead of loading everything into memory.
- Use async stream APIs for I/O in web/server apps.
- Reset stream position when re-reading.
- Do not assume a stream is seekable unless you check.

## Encoding Rules

- Specify encoding explicitly for file formats and protocols.
- Prefer UTF-8 for new text files and APIs.
- Do not mix bytes and characters without explicit conversion.

## Serialization Rules

- Prefer `System.Text.Json` for JSON.
- Use XML only when required by interoperability or legacy systems.
- Do not use insecure binary serialization patterns.
- Treat deserialized data as untrusted input.
- Use DTOs for external contracts rather than exposing domain or EF entities directly.
- Version serialized contracts carefully.

## JSON Rules

- Configure naming policy intentionally.
- Use source generation for performance-sensitive serialization.
- Avoid serializing cycles unless explicitly configured and tested.

+ 48
- 0
.ai/skills/10-ef-core-data-access.md Voir le fichier

@@ -0,0 +1,48 @@
# Skill 10 - EF Core Data Access

## Core Concepts

- EF Core maps entity classes to relational database tables.
- `DbContext` represents a unit of work and change tracker.
- Providers translate LINQ expressions to database-specific SQL.
- Database First starts from an existing database; Code First starts from C# models and migrations.

## DbContext Rules

- Register `DbContext` with dependency injection using an appropriate lifetime, usually scoped for web apps.
- Keep `DbContext` short-lived.
- Do not share a `DbContext` across threads.
- Use `AsNoTracking()` for read-only queries when tracking is not needed.
- Use transactions when multiple changes must succeed or fail together.

## Entity Design Rules

- Entities should protect important invariants, but EF also needs materialization support.
- Avoid exposing EF entities directly from public APIs.
- Keep navigation properties intentional.
- Avoid lazy-loading surprises unless the project deliberately uses lazy loading.

## Query Rules

- Filter in the database, not in memory.
- Project only needed columns for read models and API responses.
- Watch for N+1 query problems.
- Use `Include` intentionally; do not include entire object graphs by habit.
- Use pagination for large result sets.
- Use async EF methods in web applications.

## Change Rules

- Validate input before attaching or saving entities.
- Handle concurrency where concurrent updates are possible.
- Do not build SQL by string concatenation with untrusted input.
- Use migrations deliberately and review generated migrations.

## Testing Rules

- Use real providers for integration tests where SQL translation matters.
- Avoid assuming the in-memory provider behaves like a relational database.

## Repository Pattern

When the project uses a Unit of Work or generic repository abstraction, load `.ai/skills/18-unit-of-work-pattern.md` for rules on shared `DbContext` lifetime, repository staging, and single `SaveChangesAsync` per logical operation.

+ 41
- 0
.ai/skills/11-linq-querying.md Voir le fichier

@@ -0,0 +1,41 @@
# Skill 11 - LINQ Querying

## Core Concepts

LINQ lets code describe what sequence result is wanted: filter, project, sort, group, join, aggregate, and transform.

## LINQ Parts

- Extension methods such as `Where`, `Select`, `OrderBy`, `GroupBy`, and `Join` provide the operations.
- Providers execute expressions against in-memory objects, EF Core, XML, or other sources.
- Lambda expressions express predicates and projections.
- Query comprehension syntax is optional and maps to method calls.

## Rules

- Prefer method syntax for simple pipelines.
- Consider query syntax for multi-join/group queries when readability improves.
- Understand deferred execution: queries may not run until enumerated.
- Materialize with `ToList`, `ToArray`, or similar only when needed.
- Avoid multiple enumeration of expensive queries.
- Place filters early.
- For EF Core, ensure the query can translate to SQL.
- Do not call custom .NET methods inside EF queries unless they can be translated.

## Common Operations

- `Where` filters.
- `Select` projects.
- `OrderBy` / `ThenBy` sorts.
- `GroupBy` groups.
- `Join`, `GroupJoin`, `LeftJoin`, and `RightJoin` combine sequences where available.
- `Any` checks existence.
- `All` checks universal conditions.
- `Count`, `Sum`, `Average`, `Min`, `Max` aggregate.

## Performance Rules

- Avoid materializing before filtering.
- Use `Any()` instead of `Count() > 0` for existence.
- Use `TryGetNonEnumeratedCount` when count may be available cheaply.
- Be careful with closures in loops.

+ 39
- 0
.ai/skills/12-aspnetcore-web-fundamentals.md Voir le fichier

@@ -0,0 +1,39 @@
# Skill 12 - ASP.NET Core Web Fundamentals

## Core Concepts

- ASP.NET Core apps process HTTP requests through a configured pipeline.
- Middleware order matters.
- Dependency injection is built in.
- Configuration flows from appsettings, environment variables, command line, user secrets, and other providers.
- Logging should be structured and environment-appropriate.

## Project Rules

- Keep `Program.cs` readable by extracting configuration into extension methods when it grows.
- Keep domain/business logic out of controllers, endpoints, and components.
- Use options classes for grouped configuration.
- Use environment-specific configuration safely.
- Do not leak development exception pages in production.

## HTTP Rules

- Use correct status codes.
- Validate request bodies, route values, and query strings.
- Return clear problem details for client errors.
- Avoid exposing internal exception details.
- Support cancellation using `HttpContext.RequestAborted` for long-running operations.

## Static Assets

- Use the framework static asset pipeline when available.
- Cache static assets appropriately.
- Rebuild after static asset changes when build-time optimization is used.

## Security Defaults

- Use HTTPS.
- Configure authentication and authorization explicitly.
- Use anti-forgery protection for browser form posts where applicable.
- Configure CORS narrowly.
- Add security headers where appropriate.

+ 36
- 0
.ai/skills/13-blazor-components.md Voir le fichier

@@ -0,0 +1,36 @@
# Skill 13 - Blazor Components

## Core Concepts

- Blazor apps are built from components.
- Components combine markup, C# code, parameters, events, lifecycle methods, and rendering behavior.
- Rendering can happen server-side, client-side, or with static server-side rendering depending on hosting model.

## Component Rules

- Keep components small and focused.
- Use parameters for input and event callbacks for output.
- Avoid putting complex business logic directly in components.
- Extract reusable UI into child components.
- Use services for data access and state that crosses components.
- Be explicit about render modes and interactivity.

## Lifecycle Rules

- Use initialization lifecycle methods for loading setup data.
- Use parameter-set lifecycle methods when behavior depends on changing parameters.
- Avoid unnecessary calls to `StateHasChanged`.
- Dispose subscriptions and unmanaged resources.

## Forms

- Use `EditForm` for model binding and validation.
- Use validation attributes or custom validators for input rules.
- Keep validation rules shared with the domain when practical.
- Do not trust client-side validation alone.

## Performance

- Avoid excessive component re-rendering.
- Use `@key` when rendering lists whose identity matters.
- Keep large data operations out of the render path.

+ 37
- 0
.ai/skills/14-minimal-api-web-services.md Voir le fichier

@@ -0,0 +1,37 @@
# Skill 14 - Minimal API Web Services and HTTP Clients

## Minimal API Rules

- Use Minimal APIs for concise HTTP endpoints, especially small services and focused APIs.
- Group related endpoints.
- Name endpoints where useful for link generation and OpenAPI clarity.
- Keep endpoint handlers thin; delegate business logic to services.
- Validate input before processing.
- Return typed results when practical.

## OpenAPI Rules

- Generate OpenAPI documentation for public/internal APIs that clients consume.
- Add summaries, descriptions, response metadata, and XML comments where useful.
- Keep OpenAPI output accurate after route or DTO changes.

## DTO Rules

- Use request and response DTOs.
- Do not expose EF entities directly.
- Make contracts explicit and version them when clients depend on them.

## HTTP Client Rules

- Use `IHttpClientFactory` for outbound HTTP calls.
- Configure named or typed clients for external services.
- Set timeouts and resilience policies where appropriate.
- Pass cancellation tokens.
- Do not create and dispose `HttpClient` repeatedly in hot paths.

## API Reliability

- Add health checks for deployable services.
- Log failures with context but no secrets.
- Use consistent error responses.
- Consider native AOT only after checking compatibility with reflection, serialization, and dependencies.

+ 40
- 0
.ai/skills/15-packaging-publishing-nuget-aot.md Voir le fichier

@@ -0,0 +1,40 @@
# Skill 15 - Packaging, Publishing, NuGet, and AOT

## .NET Components

- Apps produce runnable outputs.
- Class libraries produce reusable assemblies.
- NuGet packages distribute libraries and tools.
- Project files define dependencies, target frameworks, build behavior, and publish behavior.

## Package Rules

- Keep package references minimal.
- Prefer central package management for multi-project repos.
- Pin versions according to team policy.
- Review transitive dependencies.
- Do not publish packages with secrets, local paths, or machine-specific config.
- Include useful metadata: package ID, version, authors, license, repository URL, description, release notes.

## Publishing Rules

- Choose framework-dependent deployment when the target runtime is managed separately.
- Choose self-contained deployment when deployment must carry the runtime.
- Use single-file publishing only after testing startup, extraction behavior, and diagnostics.
- Use trimming carefully; test reflection-heavy code.
- Use native AOT for startup/memory-sensitive apps only after checking compatibility.

## Versioning Rules

- Use semantic versioning for public packages.
- Communicate breaking changes.
- Keep public APIs stable.
- Prefer additive changes when possible.

## Commands

```bash
dotnet pack -c Release
dotnet publish -c Release
dotnet nuget push <package.nupkg> --source <source>
```

+ 40
- 0
.ai/skills/16-security-reliability-performance.md Voir le fichier

@@ -0,0 +1,40 @@
# Skill 16 - Security, Reliability, and Performance

## Security Rules

- Never store secrets in source code.
- Use user secrets for local development and a secret manager in production.
- Validate all external input.
- Encode output according to context.
- Use parameterized queries or EF Core LINQ, never string-concatenated SQL with untrusted input.
- Use HTTPS and secure cookies for web apps.
- Apply authentication and authorization at server boundaries.
- Keep dependencies and runtimes patched.

## Reliability Rules

- Use structured logging.
- Include correlation/request IDs when available.
- Use cancellation tokens for I/O and long-running operations.
- Add retries only for transient failures and only when operations are safe to retry.
- Use timeouts for external calls.
- Handle partial failure explicitly.
- Use health checks for hosted services.

## Performance Rules

- Measure before optimizing.
- Avoid needless allocations in hot paths.
- Stream large payloads.
- Use async I/O on servers.
- Page large query results.
- Avoid N+1 database calls.
- Cache only when invalidation is understood.
- Prefer compiled/generated regex and source-generated JSON for hot paths.

## Cross-Platform Rules

- Use `Path` APIs for filesystem paths.
- Respect case-sensitive filesystems.
- Avoid Windows-only assumptions unless the target is Windows-only.
- Test on Linux when deploying to Linux.

+ 30
- 0
.ai/skills/17-code-review-definition-of-done.md Voir le fichier

@@ -0,0 +1,30 @@
# Skill 17 - Code Review and Definition of Done

## Review Checklist

- [ ] The change satisfies the stated requirement.
- [ ] The solution follows existing architecture and naming conventions.
- [ ] Public APIs are documented or self-explanatory.
- [ ] Nullable warnings are resolved, not suppressed without reason.
- [ ] Exceptions are handled at appropriate boundaries.
- [ ] External input is validated.
- [ ] Secrets are not hardcoded.
- [ ] Async code is not blocked.
- [ ] Resources are disposed.
- [ ] Database queries are efficient and safe.
- [ ] If using Unit of Work: all repositories in a logical operation share one `DbContext`; `SaveChangesAsync` is called once per operation at the Unit of Work boundary.
- [ ] Tests cover meaningful behavior and edge cases.
- [ ] `dotnet build` succeeds.
- [ ] `dotnet test` succeeds or exact blockers are reported.
- [ ] The final response lists changed files, commands run, assumptions, and remaining risks.

## Definition of Done

A C#/.NET task is done when:

1. The code compiles.
2. Existing tests pass.
3. New behavior is covered by tests or there is a stated reason it cannot be tested here.
4. Security and nullability concerns are addressed.
5. The implementation is no larger than needed.
6. The user can reproduce the result with provided commands.

+ 467
- 0
.ai/skills/18-unit-of-work-pattern.md Voir le fichier

@@ -0,0 +1,467 @@
# Skill: Unit of Work Pattern for C# and .NET

Use this skill when implementing, reviewing, or refactoring data access that uses the Unit of Work pattern with C#, .NET, Entity Framework Core, repositories, services, or ASP.NET Core controllers/endpoints.

## Purpose

The Unit of Work pattern coordinates changes across one or more repositories so a logical business operation is committed as a single transaction boundary.

Use it to:

- keep one shared `DbContext` per logical operation or web request;
- group related inserts, updates, and deletes before saving;
- expose repositories through a single abstraction;
- prevent scattered `SaveChangesAsync` calls throughout controllers and repositories;
- make transaction boundaries easier to reason about and test.

Do not add this pattern automatically to every EF Core project. EF Core `DbContext` already behaves like a Unit of Work and each `DbSet<TEntity>` behaves like a repository. Add a custom Unit of Work only when the project needs a consistent repository abstraction, multi-repository coordination, test seams, or a team convention that already uses it.

## When to Load This Skill

Load this skill when the task mentions any of these concepts:

- Unit of Work
- repository pattern
- generic repository
- EF Core repository
- `IUnitOfWork`
- `UnitOfWork`
- `IGenericRepository<T>`
- `GenericRepository<T>`
- transaction boundary
- `SaveChangesAsync`
- adding a repository for a new entity
- refactoring database access out of controllers
- coordinating multiple database changes

Also load:

```text
.ai/skills/10-ef-core-data-access.md
.ai/skills/11-linq-querying.md
.ai/skills/12-aspnetcore-web-fundamentals.md
.ai/skills/17-code-review-definition-of-done.md
```

## Core Rules

### 1. Keep one `DbContext` per Unit of Work

All repositories exposed by a Unit of Work must share the same injected EF Core context instance.

```csharp
public sealed class UnitOfWork : IUnitOfWork
{
private readonly AppDbContext _context;

public UnitOfWork(AppDbContext context)
{
_context = context;
}
}
```

Do not create a new `DbContext` inside individual repository properties. That breaks the shared transaction/change-tracking boundary.

### 2. Register Unit of Work as scoped in ASP.NET Core apps

EF Core contexts are normally scoped per request. Register the Unit of Work with the same lifetime.

```csharp
builder.Services.AddDbContext<AppDbContext>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));

builder.Services.AddScoped<IUnitOfWork, UnitOfWork>();
```

Avoid `Singleton` for `DbContext`, repositories, or Unit of Work. Prefer `Scoped` for web apps. `Transient` can work in simple cases, but `Scoped` is the safer default when the Unit of Work wraps a scoped `DbContext`.

### 3. Repositories stage changes; Unit of Work saves changes

Repository methods should add, update, remove, or query entities. The Unit of Work should commit.

Good:

```csharp
await unitOfWork.Customers.AddAsync(customer, cancellationToken);
await unitOfWork.Orders.AddAsync(order, cancellationToken);
await unitOfWork.SaveChangesAsync(cancellationToken);
```

Avoid:

```csharp
await repository.AddAsync(entity);
await repository.SaveChangesAsync(); // Avoid per-repository saves.
```

Calling `SaveChangesAsync` inside every repository method weakens the pattern because each repository operation becomes its own transaction boundary.

### 4. Expose repositories by aggregate or entity

Use clear repository properties on `IUnitOfWork`.

```csharp
public interface IUnitOfWork
{
IGenericRepository<Customer> Customers { get; }
IGenericRepository<Order> Orders { get; }
IGenericRepository<Product> Products { get; }

Task<int> SaveChangesAsync(CancellationToken cancellationToken = default);
}
```

For domain-driven designs, prefer repositories per aggregate root instead of every table. For CRUD-style apps, entity-level generic repositories may be acceptable.

### 5. Lazily initialize repository properties

Create each repository once per Unit of Work instance.

```csharp
private IGenericRepository<Customer>? _customers;

public IGenericRepository<Customer> Customers =>
_customers ??= new GenericRepository<Customer>(_context);
```

This keeps repository construction cheap and preserves the shared context.

### 6. Use async APIs and cancellation tokens

Prefer async EF Core methods and pass `CancellationToken` through controllers, services, repositories, and Unit of Work methods.

```csharp
public Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
{
return _context.SaveChangesAsync(cancellationToken);
}
```

Use `AddAsync`, `ToListAsync`, `FirstOrDefaultAsync`, `SingleOrDefaultAsync`, and `SaveChangesAsync` where applicable.

## Recommended Interfaces

### Generic repository

```csharp
public interface IGenericRepository<TEntity> where TEntity : class
{
Task<IReadOnlyList<TEntity>> GetAllAsync(
Expression<Func<TEntity, bool>>? filter = null,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>>? orderBy = null,
Func<IQueryable<TEntity>, IQueryable<TEntity>>? include = null,
bool asNoTracking = true,
CancellationToken cancellationToken = default);

Task<TEntity?> GetAsync(
Expression<Func<TEntity, bool>> filter,
Func<IQueryable<TEntity>, IQueryable<TEntity>>? include = null,
bool asNoTracking = true,
CancellationToken cancellationToken = default);

Task AddAsync(TEntity entity, CancellationToken cancellationToken = default);
Task AddRangeAsync(IEnumerable<TEntity> entities, CancellationToken cancellationToken = default);
void Update(TEntity entity);
void Remove(TEntity entity);
void RemoveRange(IEnumerable<TEntity> entities);
}
```

### Unit of Work

```csharp
public interface IUnitOfWork : IAsyncDisposable
{
IGenericRepository<Customer> Customers { get; }
IGenericRepository<Order> Orders { get; }

Task<int> SaveChangesAsync(CancellationToken cancellationToken = default);
}
```

Use `IAsyncDisposable` when the Unit of Work owns the context disposal. In ASP.NET Core dependency injection, the container usually disposes the scoped context. In that case, implementing disposal is optional unless the project convention requires it.

## Recommended Implementation

### Generic repository implementation

```csharp
public class GenericRepository<TEntity> : IGenericRepository<TEntity>
where TEntity : class
{
protected readonly AppDbContext Context;
protected readonly DbSet<TEntity> DbSet;

public GenericRepository(AppDbContext context)
{
Context = context;
DbSet = context.Set<TEntity>();
}

public async Task<IReadOnlyList<TEntity>> GetAllAsync(
Expression<Func<TEntity, bool>>? filter = null,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>>? orderBy = null,
Func<IQueryable<TEntity>, IQueryable<TEntity>>? include = null,
bool asNoTracking = true,
CancellationToken cancellationToken = default)
{
IQueryable<TEntity> query = DbSet;

if (asNoTracking)
{
query = query.AsNoTracking();
}

if (filter is not null)
{
query = query.Where(filter);
}

if (include is not null)
{
query = include(query);
}

if (orderBy is not null)
{
query = orderBy(query);
}

return await query.ToListAsync(cancellationToken);
}

public async Task<TEntity?> GetAsync(
Expression<Func<TEntity, bool>> filter,
Func<IQueryable<TEntity>, IQueryable<TEntity>>? include = null,
bool asNoTracking = true,
CancellationToken cancellationToken = default)
{
IQueryable<TEntity> query = DbSet;

if (asNoTracking)
{
query = query.AsNoTracking();
}

if (include is not null)
{
query = include(query);
}

return await query.FirstOrDefaultAsync(filter, cancellationToken);
}

public Task AddAsync(TEntity entity, CancellationToken cancellationToken = default)
{
return DbSet.AddAsync(entity, cancellationToken).AsTask();
}

public Task AddRangeAsync(IEnumerable<TEntity> entities, CancellationToken cancellationToken = default)
{
return DbSet.AddRangeAsync(entities, cancellationToken);
}

public void Update(TEntity entity)
{
DbSet.Update(entity);
}

public void Remove(TEntity entity)
{
DbSet.Remove(entity);
}

public void RemoveRange(IEnumerable<TEntity> entities)
{
DbSet.RemoveRange(entities);
}
}
```

### Unit of Work implementation

```csharp
public sealed class UnitOfWork : IUnitOfWork
{
private readonly AppDbContext _context;
private IGenericRepository<Customer>? _customers;
private IGenericRepository<Order>? _orders;

public UnitOfWork(AppDbContext context)
{
_context = context;
}

public IGenericRepository<Customer> Customers =>
_customers ??= new GenericRepository<Customer>(_context);

public IGenericRepository<Order> Orders =>
_orders ??= new GenericRepository<Order>(_context);

public Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
{
return _context.SaveChangesAsync(cancellationToken);
}

public ValueTask DisposeAsync()
{
return _context.DisposeAsync();
}
}
```

If ASP.NET Core dependency injection owns the `DbContext`, do not manually dispose it inside request code. Let the container manage scoped disposal.

## Query Rules

### Prefer typed includes over string includes

Good:

```csharp
var orders = await unitOfWork.Orders.GetAllAsync(
include: query => query.Include(order => order.Customer)
.Include(order => order.OrderLines),
cancellationToken: cancellationToken);
```

Avoid string includes unless the existing project style already uses them or dynamic includes are required.

```csharp
// Less refactor-safe:
query = query.Include("Customer");
```

### Use `AsNoTracking` for read-only queries

Use no-tracking queries for list pages, reports, dropdowns, read-only API responses, and other cases where the entity will not be edited in the same context.

Do not use `AsNoTracking` when you plan to modify the returned entity and rely on change tracking.

### Return nullable results when records might not exist

Use `TEntity?` for lookup methods that might not find a record.

```csharp
Task<TEntity?> GetAsync(Expression<Func<TEntity, bool>> filter, ...);
```

Then handle not-found cases explicitly in services/controllers.

## Controller and Service Usage

Prefer using Unit of Work from application services. Controllers/endpoints should be thin.

```csharp
public sealed class OrderService
{
private readonly IUnitOfWork _unitOfWork;

public OrderService(IUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
}

public async Task<int> CreateOrderAsync(CreateOrderRequest request, CancellationToken cancellationToken)
{
var order = new Order
{
CustomerId = request.CustomerId,
CreatedAtUtc = DateTime.UtcNow
};

await _unitOfWork.Orders.AddAsync(order, cancellationToken);
return await _unitOfWork.SaveChangesAsync(cancellationToken);
}
}
```

Avoid injecting both `AppDbContext` and `IUnitOfWork` into the same service/controller unless there is a temporary migration reason. Mixed access makes transaction boundaries unclear.

## Transactions

A single `SaveChangesAsync` call is already transactional for most relational EF Core providers. Use explicit transactions when a logical operation requires multiple `SaveChangesAsync` calls or coordination with non-EF operations.

```csharp
await using var transaction = await context.Database.BeginTransactionAsync(cancellationToken);

await unitOfWork.Customers.AddAsync(customer, cancellationToken);
await unitOfWork.SaveChangesAsync(cancellationToken);

await externalAuditWriter.WriteAsync(customer.Id, cancellationToken);

await unitOfWork.SaveChangesAsync(cancellationToken);
await transaction.CommitAsync(cancellationToken);
```

Keep explicit transactions in a service layer, not inside generic repository methods.

## Validation and Error Handling

- Validate input before adding entities to repositories.
- Enforce business rules in services/domain methods, not in generic repositories.
- Let EF Core exceptions bubble to a higher layer where they can be logged and converted into user-friendly responses.
- Handle concurrency conflicts explicitly when using row versions or concurrency tokens.
- Do not swallow `DbUpdateException` or `DbUpdateConcurrencyException` without logging and a clear recovery path.

## Testing Rules

For Unit of Work code:

- test service behavior at the Unit of Work boundary;
- verify `SaveChangesAsync` is called once per logical operation when using mocks;
- prefer SQLite in-memory or a test container over EF Core InMemory provider for relational behavior;
- test includes, filters, ordering, and not-found paths;
- test transactions and rollback behavior when business logic spans multiple changes.

## Common Mistakes to Avoid

- Creating a separate `DbContext` per repository.
- Calling `SaveChangesAsync` inside every repository method.
- Registering `DbContext` or Unit of Work as singleton.
- Mixing raw `DbContext` access and Unit of Work access in the same service without a clear reason.
- Returning `IQueryable` from repositories to upper layers without a deliberate design decision.
- Hiding all EF Core capabilities behind a generic repository when a specific query/service would be clearer.
- Using string includes when typed includes are available.
- Ignoring cancellation tokens.
- Treating Unit of Work as a substitute for business/domain services.

## Adding a New Entity Repository

When adding a new entity to a Unit of Work:

1. Add a `DbSet<TEntity>` to the EF Core context if it does not already exist.
2. Add an `IGenericRepository<TEntity>` property to `IUnitOfWork`.
3. Add a nullable backing field to `UnitOfWork`.
4. Add a lazy property implementation using the shared context.
5. Add service/controller usage through constructor-injected `IUnitOfWork`.
6. Call `SaveChangesAsync` once at the end of each logical mutation.
7. Add tests for query, create, update, delete, and not-found behavior.

Example:

```csharp
// IUnitOfWork.cs
IGenericRepository<Invoice> Invoices { get; }

// UnitOfWork.cs
private IGenericRepository<Invoice>? _invoices;

public IGenericRepository<Invoice> Invoices =>
_invoices ??= new GenericRepository<Invoice>(_context);
```

## Definition of Done

A Unit of Work change is done only when:

- all repositories share one scoped EF Core context;
- dependency injection registration uses appropriate lifetimes;
- mutation flows call `SaveChangesAsync` once per logical operation;
- read-only queries use `AsNoTracking` where appropriate;
- not-found results are handled explicitly;
- includes are typed where possible;
- cancellation tokens flow through async operations;
- tests cover successful operations, validation failures, and not-found cases;
- the code builds, tests pass, and no transaction boundary is ambiguous.

+ 10
- 0
.claude/settings.local.json Voir le fichier

@@ -0,0 +1,10 @@
{
"permissions": {
"allow": [
"Bash(Get-ChildItem -Path \"C:\\\\Users\\\\Admin\\\\Downloads\\\\csharp-dotnet-ai-agent-pack-generic-uow\\\\csharp-dotnet-ai-agent-pack\" -Recurse -File)",
"Bash(Select-Object FullName)",
"Bash(Sort-Object FullName)",
"PowerShell($path = \"C:\\\\Users\\\\Admin\\\\Downloads\\\\csharp-dotnet-ai-agent-pack-generic-uow\\\\csharp-dotnet-ai-agent-pack\"; if \\(Test-Path $path\\) { Write-Host \"Path exists\"; Get-ChildItem $path -Recurse | Sort-Object FullName | ForEach-Object { $_.FullName } } else { Write-Host \"Path does not exist\"; Get-ChildItem \"C:\\\\Users\\\\Admin\\\\Downloads\\\\\" })"
]
}
}

+ 86
- 0
AGENTS.md Voir le fichier

@@ -0,0 +1,86 @@
# AGENTS.md - C# 14 / .NET 10 Expert Agent Instructions

## Purpose

This file tells AI coding agents how to work in this repository as a panel of senior C# and .NET engineers. The agent must produce correct, maintainable, testable, secure C# code and must route itself to the right skill files before changing code.

## Startup Instructions

Before working on any task:

1. Read this `AGENTS.md`.
2. Read the main skill router:

```text
./.ai/SKILLS.md
```

3. Identify the task type: language, library, data, web, Blazor, API, packaging, testing, security, performance, or review.
4. Load the matching skill files listed in `.ai/SKILLS.md`.
5. Inspect the existing solution before writing code:
- `*.sln`, `*.slnx`
- `*.csproj`, `Directory.Build.props`, `Directory.Packages.props`, `global.json`
- existing namespaces, nullable settings, analyzers, test projects, CI scripts, and style rules
6. Do not invent project conventions. Follow the existing codebase unless the user asks to refactor.

## Core Engineering Rules

- Prefer modern .NET and modern C# features, but only when they improve clarity.
- Keep code readable before clever.
- Treat warnings as future defects.
- Prefer small functions with clear names and clear inputs and outputs.
- Prefer explicit domain types over loosely typed strings, dictionaries, or dynamic objects.
- Enable and respect nullable reference types.
- Validate external input at boundaries.
- Use guard clauses for invalid arguments and impossible states.
- Do not swallow exceptions. Either handle them meaningfully or let them propagate with context.
- Use `async`/`await` for I/O-bound operations. Avoid blocking on async code with `.Result` or `.Wait()`.
- Prefer dependency injection for services, repositories, HTTP clients, loggers, and options.
- Use unit tests for pure/domain logic and integration tests for database, file, web, or external boundaries.
- Do not add packages unless there is a clear reason and the package is actively maintained.
- Never hardcode secrets, connection strings, tokens, passwords, or environment-specific paths.

## Preferred Workflow

For every task:

1. Restate the goal internally as a concrete deliverable.
2. Identify impacted files and APIs.
3. Make the smallest safe change that satisfies the requirement.
4. Add or update tests.
5. Run or propose the exact commands:

```bash
dotnet restore
dotnet build
dotnet test
dotnet format
```

6. Explain what changed and any risks, assumptions, or follow-up tasks.

## Output Rules

When returning code:

- Show complete files or precise patches when possible.
- Include file paths.
- Include commands to build and test.
- Mention assumptions.
- Mention any behavior change.
- Keep examples aligned with the target framework and language version in the project.

## Skill Routing

Use `.ai/SKILLS.md` as the routing table. Do not load every skill for every task. Load the minimum needed files plus `00-agent-operating-rules.md` and `17-code-review-definition-of-done.md`.


## Reusable Pattern Convention: Unit of Work

When working with repository pattern, Unit of Work, EF Core CRUD/query changes, transaction boundaries, or controller/service data-access refactors, load:

```text
.ai/skills/18-unit-of-work-pattern.md
```

Use that skill to keep one shared `DbContext` per unit of work, register the pattern with an appropriate scoped lifetime, expose repositories through `IUnitOfWork`, and commit with a single `SaveChangesAsync` call per logical operation.

+ 1
- 0
CLAUDE.md Voir le fichier

@@ -0,0 +1 @@
AGENTS.m

+ 56
- 0
README.md Voir le fichier

@@ -0,0 +1,56 @@
# C# 14 / .NET 10 AI Agent Skill Pack

This repository contains a routable `AGENTS.md` plus modular skill files for AI coding agents working on C# and .NET projects.

The skills summarize and operationalize concepts, principles, rules, and best practices extracted from the uploaded book *C# 14 and .NET 10 - Modern Cross-Platform Development Fundamentals, Tenth Edition* by Mark J. Price, with added expert-agent workflow structure for practical coding use.

## Structure

```text
.
├── AGENTS.md
├── README.md
├── manifest.json
├── docs/
│ ├── concept-map.md
│ ├── review-checklist.md
│ ├── task-routing.md
│ └── unit-of-work-pattern.md
└── .ai/
├── SKILLS.md
├── prompts/
│ └── csharp-dotnet-agent-prompt.md
└── skills/
├── 00-agent-operating-rules.md
├── 01-dotnet-platform-tooling.md
├── 02-csharp-language-fundamentals.md
├── 03-types-values-nullability.md
├── 04-control-flow-exceptions.md
├── 05-functions-debugging-testing.md
├── 06-oop-types-records.md
├── 07-interfaces-generics-events-inheritance.md
├── 08-common-dotnet-types.md
├── 09-files-streams-serialization.md
├── 10-ef-core-data-access.md
├── 11-linq-querying.md
├── 12-aspnetcore-web-fundamentals.md
├── 13-blazor-components.md
├── 14-minimal-api-web-services.md
├── 15-packaging-publishing-nuget-aot.md
├── 16-security-reliability-performance.md
├── 17-code-review-definition-of-done.md
└── 18-unit-of-work-pattern.md
```

## How an AI agent should use this pack

1. Read `AGENTS.md` first.
2. Read `.ai/SKILLS.md` next.
3. Load only the skill files relevant to the current task.
4. Follow the checklists in `docs/review-checklist.md` before returning final code.

## Notes

This pack is intentionally modular. Keep `AGENTS.md` short and use `.ai/SKILLS.md` as the router. Add project-specific skills under `.ai/skills/project/` when needed.

Skill `18-unit-of-work-pattern.md` covers the generic Unit of Work and repository pattern. Load it when a task involves `IUnitOfWork`, `UnitOfWork`, `GenericRepository<T>`, EF Core `DbContext` transaction boundaries, or repository-backed services and controllers. See `docs/unit-of-work-pattern.md` for a concise reference summary.

+ 64
- 0
docs/concept-map.md Voir le fichier

@@ -0,0 +1,64 @@
# C# 14 / .NET 10 Concept Map

## Platform and Tooling

- Modern .NET versus legacy .NET
- SDK versus runtime
- Project files and solution files
- Visual Studio, VS Code, Rider, and command-line workflows
- `dotnet` CLI commands
- SDK pinning with `global.json`
- Build, restore, test, format, pack, publish
- Cross-platform deployment and Linux/Windows differences

## C# Language

- Grammar, vocabulary, keywords, identifiers, expressions, statements
- Variables, constants, type inference, literals
- Value types, reference types, nullable types
- Operators, conversions, casting, parsing, overflow checking
- Selection, iteration, pattern matching
- Exception handling and guard clauses
- Functions, parameters, return values, tuples, local functions
- Classes, structs, records, fields, methods, properties, indexers
- Encapsulation, abstraction, composition, inheritance, polymorphism
- Interfaces, generics, delegates, events, extension methods
- Nullable reference types and null-safety

## .NET Libraries

- Numbers, strings, dates, text formatting
- Collections and dictionaries
- Regular expressions
- Filesystem, streams, encodings
- JSON and XML serialization
- Logging, diagnostics, debugging, testing

## Data and Querying

- EF Core models, DbContext, providers
- Database First and Code First
- LINQ to Objects and LINQ to Entities
- Filtering, projection, sorting, grouping, joins, aggregates
- Tracking, no-tracking, transactions, migrations, concurrency
- Unit of Work and generic repository pattern

## Web

- ASP.NET Core pipeline and middleware
- Dependency injection and configuration
- Static assets
- Blazor components, forms, lifecycle, render modes
- Minimal API endpoints
- OpenAPI documentation
- HTTP client consumption
- Health checks and security headers

## Packaging and Deployment

- Class libraries
- NuGet packages
- Framework-dependent and self-contained publishing
- Single-file publishing
- Trimming
- Native AOT

+ 62
- 0
docs/review-checklist.md Voir le fichier

@@ -0,0 +1,62 @@
# C# / .NET Review Checklist

## Build and Test

```bash
dotnet restore
dotnet build
dotnet test
dotnet format --verify-no-changes
```

## Language Quality

- Names communicate intent.
- Functions are small and cohesive.
- No unnecessary `dynamic`.
- Nullable warnings are fixed.
- Exceptions preserve stack traces.
- Async code is truly async.
- Pattern matching improves clarity rather than obscuring intent.

## Object Design

- Invariants are protected.
- Public mutable state is avoided.
- Interfaces represent real contracts.
- Inheritance represents substitutability.
- Records are used only where value equality makes sense.

## Data Access

- Queries filter/project in the database.
- No N+1 surprises.
- Large result sets are paged.
- No unsafe SQL string concatenation.
- DbContext lifetime is appropriate.
- `SaveChangesAsync` is called once per logical operation at the Unit of Work boundary.
- All repositories in a logical operation share one `DbContext` instance.
- Read-only queries use `AsNoTracking` where appropriate.

## Web/API

- Correct HTTP status codes.
- Request validation is present.
- DTOs are used for external contracts.
- Errors do not leak internals.
- OpenAPI docs match the implementation.

## Security

- No secrets in code.
- Inputs are validated.
- Outputs are encoded.
- Authorization is enforced server-side.
- Packages and target frameworks are supported.

## Deployment

- Publish settings are intentional.
- Cross-platform assumptions are tested.
- Config is environment-aware.
- Logs and health checks support operations.

+ 55
- 0
docs/task-routing.md Voir le fichier

@@ -0,0 +1,55 @@
# Task Routing Guide

Use this when deciding which skill files to load.

## Examples

### Add a method to a domain class

Load:

- `00-agent-operating-rules.md`
- `03-types-values-nullability.md`
- `05-functions-debugging-testing.md`
- `06-oop-types-records.md`
- `17-code-review-definition-of-done.md`

### Fix an EF Core query

Load:

- `00-agent-operating-rules.md`
- `10-ef-core-data-access.md`
- `11-linq-querying.md`
- `16-security-reliability-performance.md`
- `17-code-review-definition-of-done.md`

### Build a Minimal API endpoint

Load:

- `00-agent-operating-rules.md`
- `12-aspnetcore-web-fundamentals.md`
- `14-minimal-api-web-services.md`
- `16-security-reliability-performance.md`
- `17-code-review-definition-of-done.md`

### Add or refactor Unit of Work / repository pattern

Load:

- `00-agent-operating-rules.md`
- `18-unit-of-work-pattern.md`
- `10-ef-core-data-access.md`
- `11-linq-querying.md`
- `12-aspnetcore-web-fundamentals.md`
- `17-code-review-definition-of-done.md`

### Create a NuGet package

Load:

- `00-agent-operating-rules.md`
- `01-dotnet-platform-tooling.md`
- `15-packaging-publishing-nuget-aot.md`
- `17-code-review-definition-of-done.md`

+ 40
- 0
docs/unit-of-work-pattern.md Voir le fichier

@@ -0,0 +1,40 @@
# Unit of Work Pattern Notes

Use the Unit of Work pattern when a C#/.NET application needs one clear transaction boundary across multiple repository operations.

## Core idea

A Unit of Work owns or coordinates one EF Core `DbContext`. Repositories use that same context to stage changes. The application service or controller calls `SaveChangesAsync` once at the end of the logical operation.

## Recommended shape

```text
AppDbContext
├─ DbSet<Customer>
├─ DbSet<Order>
└─ DbSet<Product>

IGenericRepository<TEntity>
GenericRepository<TEntity>

IUnitOfWork
├─ Customers
├─ Orders
├─ Products
└─ SaveChangesAsync()
```

## Best practices

- Register `DbContext`, repositories, and Unit of Work with compatible lifetimes, usually scoped in ASP.NET Core.
- Keep one shared context per Unit of Work.
- Let repositories stage changes; let Unit of Work commit changes.
- Prefer async EF Core methods with cancellation tokens.
- Use `AsNoTracking` for read-only queries.
- Prefer typed `Include` expressions over string include paths.
- Keep business rules in services/domain methods, not generic repositories.
- Avoid mixing direct `DbContext` access and Unit of Work access in the same workflow.

## When not to use it

Do not add a custom Unit of Work just for ceremony. EF Core `DbContext` already provides Unit of Work behavior. A custom abstraction is most useful when the project has a repository convention, a testing boundary, or complex operations spanning multiple repositories.

+ 31
- 0
manifest.json Voir le fichier

@@ -0,0 +1,31 @@
{
"files": [
".ai/SKILLS.md",
".ai/prompts/csharp-dotnet-agent-prompt.md",
".ai/skills/00-agent-operating-rules.md",
".ai/skills/01-dotnet-platform-tooling.md",
".ai/skills/02-csharp-language-fundamentals.md",
".ai/skills/03-types-values-nullability.md",
".ai/skills/04-control-flow-exceptions.md",
".ai/skills/05-functions-debugging-testing.md",
".ai/skills/06-oop-types-records.md",
".ai/skills/07-interfaces-generics-events-inheritance.md",
".ai/skills/08-common-dotnet-types.md",
".ai/skills/09-files-streams-serialization.md",
".ai/skills/10-ef-core-data-access.md",
".ai/skills/11-linq-querying.md",
".ai/skills/12-aspnetcore-web-fundamentals.md",
".ai/skills/13-blazor-components.md",
".ai/skills/14-minimal-api-web-services.md",
".ai/skills/15-packaging-publishing-nuget-aot.md",
".ai/skills/16-security-reliability-performance.md",
".ai/skills/17-code-review-definition-of-done.md",
"AGENTS.md",
"README.md",
"docs/concept-map.md",
"docs/review-checklist.md",
"docs/task-routing.md",
".ai/skills/18-unit-of-work-pattern.md",
"docs/unit-of-work-pattern.md"
]
}

Chargement…
Annuler
Enregistrer

Powered by TurnKey Linux.