From software-engineering
Preferred patterns and conventions for building .NET/C# APIs with ASP.NET Core, MongoDB, Auth0, and xUnit. Apply proactively to all backend work.
How this skill is triggered — by the user, by Claude, or both
Slash command
/software-engineering:api-designThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Preferred patterns and conventions for building .NET/C# APIs. Apply proactively to all backend work.
Preferred patterns and conventions for building .NET/C# APIs. Apply proactively to all backend work.
Apply this skill when:
| Concern | Choice |
|---|---|
| Framework | ASP.NET Core — controllers, not minimal API |
| Language | C# |
| Database | MongoDB |
| Auth | Auth0 |
| Messaging | RabbitMQ (when needed) |
| Tests | xUnit + Testcontainers |
Solution
├── Api/ # Controllers, startup, DI
├── Domain/ # POCOs, Interfaces/, Services/
├── Storage/ # Repository implementations
├── External/ # Third-party providers
└── Tests/Api.Tests/
Start every feature as a vertical slice — Controller → Repository → Domain entity. Introduce MediatR only when a controller accumulates too many injected dependencies — not upfront.
Plain C# classes — no EF, no MongoDB attributes, no framework references. Model the domain before touching infrastructure.
public class User
{
public string Id { get; private set; }
public string AccountId { get; private set; }
public string Email { get; private set; }
public User(string id, string accountId, string email)
{
Id = id;
AccountId = accountId;
Email = email;
}
}
One per aggregate root. Single Save method that upserts. Interface in Domain/Interfaces/, implementation in Storage/Repositories/.
public interface IUserRepository
{
Task Save(User user);
Task<User?> GetById(string id);
Task<IReadOnlyList<User>> GetByAccountId(string accountId);
}
Persist domain objects directly — no persistence DTOs. Use ClassMapRegistrar for private fields and polymorphic types. Register before any MongoDB operations.
ApiUser unpacks Auth0 claims namespaced as "{audience}/user_id", "{audience}/account_id". IApiUser in domain contracts. Supports impersonation via impersonate_account_id. In tests: FakeApiUser — never wire JWT.
Always start a new endpoint with an integration test asserting a success response.
[Fact]
public async Task The_user_is_created_successfully()
{
var response = await _client.PostAsJsonAsync("/users", new { Email = "[email protected]" });
response.StatusCode.Should().Be(HttpStatusCode.Created);
}
Use Testcontainers for real infrastructure — don't fake the database at integration test level. Fakes not mocks. Extract GivenA[Thing] builders when setup recurs.
GitHub Actions. Set up the test workflow immediately on project creation — never defer.
name: Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-dotnet@v4
with:
dotnet-version: '9.x'
- run: dotnet test --no-build --verbosity normal
Keep change sets small — one concern at a time. Always model the domain before touching infrastructure.
Provides behavioral guidelines to reduce common LLM coding mistakes, focusing on simplicity, surgical changes, assumption surfacing, and verifiable success criteria.
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Creates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.
npx claudepluginhub de-anchorite/claude-skills --plugin software-engineering